I've tried your project. Apparently I'm not getting the result you are seeing.
When I load your project in as is and I have NO transducer on P1.6 (left unconnected), I get 0 as an ADC reading.
When I comment out the line 29 in main()
and I set the P1.6 in the TopDesign to pull-up with an Initial Drive State to high, I get 4095 as an ADC reading.
All is as expected.
Try disconnecting your transducer and see if you get the same results as I do.
Thank you very much for verifying my project. I realized it works as you described on my side as well. However, in my application I have to multiplex between several of such pins and this is where the problem shows up again.
I have attached a second project using the SAR sequencer to mux between 4 such pins. With all of them set to resistive pull up (or strong drive) and initial state high, and all pins unconnected on my CY8CKIT-059, I am reading a floating value (between 100 to 400).
MVE.cyprj.Archive02.zip 2.2 MB
1 of 1 people found this helpful
I tried your new project. I get the same results as you.
To root cause the issue, I took the following steps in sequence:
- I rebuilt your original MVE project with pullup on P1.6 and commenting out the CyPins_ClearPin(Pin_1_0); Result: P1.6 high. OK
- I changed the pin assignment to P3.0. Result: P3.0 high. OK
- I added three more pins (P3.1, P3.2, P3.3) as pull ups. Result: P3.0 through P3.3 high. OK
- Changed the ADC_SAR to a ADC_SAR_Seq. Result: P3.0 through P3.3 low. Not OK
Something about the ADC_SAR_Seq appears to be either be changing the pin definitions to Analog-HiZ only or the input mux is shorting the inputs not being scanned.
More debugging to follow.
1 of 1 people found this helpful
Continued root cause isolation:
5. I replaced the ADC_SAR_Seq with a discreet AMuxSeq as a front end and a ADC_SAR. Result: P3.0 through P3.3 high. OK
This confirms that something about the configuration of the ADC_SAR_Seq is either modifying the input configuration or shorting non-scanned inputs.
As can be seen in experiment 5., if you are willing to control the Amux yourself, your problem is solved.
6. Using experiment 5, project, I added code in main() to dump the drive mode register values of Port 3. Results:
4095,4095,4095,4095, DM0=00 DM1=0F DM2=00
Therefore for P3.0 through P3.3 the drive mode is "b010 : Mode 2, weak pull-up." (From PSoC 5LP TRM page 372) This is design-intent.
7. I substituted the ADC_SAR_Seq in place of the working Amux and ADC_SAR with the drive mode register values. Result:
1024,943,820,1526, DM0=00 DM1=0F DM2=00. P3.0 through P3.3 low Not OK BUT the drive mode appears to be the same.
Therefore without further study, it appears that the AMux control in the ADC_SAR_Seq is shorting the inputs to VSSA.
Maybe Cypress can comment on this.
Amazing work Len!
Thank you very much for your in depth investigation. I actually checked the drive mode registers earlier and realised they were as configured, which was puzzling. Good to know there is a workaround.
I will implement my own sequencer then.
Would be great if Cypress can comment on this. Will wait a while before marking it as solved.
Thanks again for your help!
An update to this question:
The problem is with Analog Mux Hardware. Putting a SAR behind an AMuxHW results in reading floating signals. If I swap out the AMuxHW for a software Amux, the problem goes away. To investigate further, I forced both the muxes to use the same route (AMUXBUSR) and verified that all the software does is setting CYREG_PRT3_AMUX register for ports P3.0 to P3.3. The problem remains for the hardware version, while the software mux works fine. I have attached versions for both the HW and SW muxes for anyone wishing to replicate the problem.
Unfortunately I require hardware controlled switching in my application. Is there any guide on how to drive CYREG_PRT3_AMUX (or other routing registers) using UDB logic?
On a sidenote, if I put a voltage follower op-amp between the analog pins and the SAR the problem is gone. But I waste an analog pin as it is hardwired to the amp.
I would not recommend the Opamp in follower mode in front of the SAR. For one thing, it doesn't solve your need for a HW switched mux. Additionally, the common-mode outset offset error that could be introduced is unnecessary.
Below is a schematic for changing the AmuxHW using UDB as requested. It uses the EOS (end-of-sample) signal.
Note that the EOC output has both a DMA request and Interrupt Service Request (ISR) component attached. Only one of these is needed.
If you chose the isr_eoc, you will get an interrupt for each channel after the conversion is complete.
A faster HW state-machine technique is to use the DMA request. This requires you reserve RAM memory for a buffer and set up the DMA configuration properly. If configured, you can get an isr_end_all_channels when all four channels have been converted.
The Control_Reg_1 is used to reset the BasicCounter_1 if needed to resync the ADC_SAR_1 and the AmuxHW_1.
I appreciate the time you took to do the schematic, but unfortunately this is not what I need. The AMuxHw IP from Cypress is flawed as it will modify the pin drivers causing the ADC to read a floating signal. Only the software version of AMux (or AMux sequencer) can be used in my application, which is sub-optimal.
What I need is a way to roll my own AMuxHw. I reckon there should be additional ways to access the routing registers from UDB via the DSI (How else is the AMuxHw from Cypress doing it?). As seen in the figure below, it should be possible to access port control via DSI. But documentation on this is scarce. Can anyone from Cypress comment on this?
Just to update that I have found the solution to this problem. The problem lies with the output enable logic.
Referencing Fig 1, note that to use UDBs to implement hardware multiplexing, PRT[x]BIE has to be '1' all the time, which I confirmed to be true. But this means that the only way to control OE would be through the Bidirectional Control port, which is controllable only from UDB (through registers PRT[x]OE_SEL, PRT[x]OE_SEL). These registers appear to be unconfigured (default at '0').
Fig 1: Output logic schematic
To verify my suspicion, I had the project configured as per Fig 2:
Fig 2: Solution to reading floating signals
Now the registers PRT[x]OE_SEL and PRT[x]OE_SEL are non-zero and the SAR is reading 4095 as expected from a weak pull-up pin.
Interestingly, if I hard-wire the output enables as per Fig 3:
Fig 3: Misleading implementation
PSOC creator appears to optimize away the constant, resulting in the OE registers left unconfigured again. This is very misleading and is a bug I hope Cypress will address.
Thank you for your time =)
I'm glad you found the problem with your circuit.
Question: Is there a reason why you are using analog inputs with an Output Enable (OE)? Normally OEs are used for digital tri-state output control. I'm not sure OEs will work correctly when you configure a pin as analog Hi-Z. In analog Hi-Z mode, the pin is just a pass-through to internal analog buses.