Hi,
I am using S32K148 EVB and Touch Example from S32K148 cookbook. The example itself works fine. (Well, not really. I couldn't get the example built. I imported the project and when building I got errors such as "fatal error: device_registers.h: No such file or directory". In the end, I created a new project to which I copied all the source files from said example without any changes and it compiles and works. Oh well)
However, now I am trying to use the same example to measure an external capacitor or a touch sensor. I am trying to mimic the schematic of S32K148 EVB touch pads with two capacitors and a resistor. I plan to replace the other capacitor with my own touch pad if I got this setup working
In Touch1.h, the ports and pins for Cext and touch pad are defined like this
#define ELEC1
#define ELEC1_ADC ADC0
#define ELEC1_ADC_CHANNEL 0
#define ELEC1_PORT PORTA
#define ELEC1_GPIO PTA
#define ELEC1_ELEC_GPIO_PIN 15
#define ELEC1_CEXT_GPIO_PIN 0
#define ELEC1_PORT_MASK (1 << ELEC1_ELEC_GPIO_PIN) | (1 << ELEC1_CEXT_GPIO_PIN)
I tried to replace Touch1 with my external setup and used IO pins PTB14 and PTB15. The defines like this:
#define ELEC1
#define ELEC1_ADC ADC0
#define ELEC1_ADC_CHANNEL 9
#define ELEC1_PORT PORTB
#define ELEC1_GPIO PTB
#define ELEC1_ELEC_GPIO_PIN 15
#define ELEC1_CEXT_GPIO_PIN 14
#define ELEC1_PORT_MASK (1 << ELEC1_ELEC_GPIO_PIN) | (1 << ELEC1_CEXT_GPIO_PIN)
I made no other changes in the source code. Again, code compiles fine, but when I start debugging I get following errors:
BusFault: An imprecise (asynchronous) data access error has occurred.
HardFault: A fault has been escalated to a hard fault.
I also tried with pins PTC27 and PTC28 and I get the same error. What could be the reason for this? Something to do with interrupts? Any help would be appreciated.
Attached a picture of my Design Studio view. I use Design Studion v2.2 and these are my extensions:
Hi @Maijaaah,
Have you enabled clock for the PORT B?
PCC->PCCn[PCC_PORTB_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTB */
BR, Daniel
Hi Daniel,
thank you, that did it! I had tried it already earlier and just looked that I get the same error still -> didn't help. I tried again yesterday and realised that because I just replaced enabling clock for port A with enabling clock for port B, I now got the error from Touch 2 that still had the original pins, lol. So, now I enable clocks for both ports, A and B, and I get no errors.
So touch 2 works, but now I have a new problem... I'm printing the voltage from PTB14 in TouchSense1() like this:
// Equivalent voltage digitalization
// Wait for conversion complete flag
while(ADC_conversion_complete()==0){}
adcResult = ADC_channel_read();
//(void)adcResult;
// Compare with the Touched reference.
//if(ADC_channel_read() < ELEC1_TOUCHED_LIMIT_VALUE)
if(adcResult < ELEC1_TOUCHED_LIMIT_VALUE)
{
Touched = true;
}
printf("ADC result: %d\n", adcResult);
return Touched;
And adcResult is always 0. I even tried connecting PTA1 pin to PTB14, because Touch2 works so there should be some voltage on pin PTA1 right?
I'm probably missing something obvious, but I've been reading about ADC and I still don't understand what's wrong.
Hi @Maijaaah,
I think the problem is that you read a wrong ADC result register:
uint32_t ADC_channel_read (void)
{
uint16_t adc_raw_result = 0;
adc_raw_result = ADC0 -> R[0]; /* For SW trigger mode, R[0] is used */
return (uint32_t)((5000 * adc_raw_result) / 0xFFF); /* Convert result to mV for 0-5 V range */
}
Because you use channel 9 now.
Regards,
Daniel
Hi @danielmartynek , thanks again for the reply.
I tried that and it does not help. Not only that, but it also breaks Touch2. I tried printing ADC result in both functions TouchSense1() and TouchSense2(). Previously it prints 0 from Touch1 (the changed pins) and ~2300mV from Touch2 (800-900mV when touched) and the LED colour changes as it should. If I change 0 to 9 in adc_raw_result = ADC0 -> R[9]; then both adc results are 0 and the LED doesn't react to touch anymore.
I did a little digging on the ADC and as far as I understand, this example uses SW trigger for ADC (void ADC_channel_convert (uint16_t adc_channel) in adc.c starts the conversion) and the result after SW trigger is always read from R[0]. At least that's what I understand from this application note and especially appendix A. There ADC measures from channel 12, is triggered with SW trigger and the result is read from R[0].
Also, Touch2 is on ADC channel 1 and it works with the same adc_channel_read() function.
I compared the ways ADC is initialised on this example and on that application note. There are some differences, which I don't yet understand. Could that have something to do with this?
Again, grateful for all the help!
Hi @Maijaaah,
Yes, you are right, sorry for that.
Can you share the project so that I can test it and avoid guessing?
Thank you,
BR, Daniel
my project is in the attachment. I hope there's everything needed.
Hi @Maijaaah,
PTB14 can be connected to ADC1_SE9 or to ADC0_SE9 or both at the same time.
By default, PTB14 is connected to ADC1_SE9.
So you can either connect the pin to both ADC modules in SIM_CHIPCTL[ADC_INTERLEAVE_EN] or you can use ADC1.
Regards,
Daniel