PDA

View Full Version : SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon



longpole001
- 24th November 2013, 00:57
WEll , another day, another bug

This one stems from what i think is a result of sillion issue with the ADC

Chip is a 16F1947 Rev 2 device ID is shown as 2522

The erratica from microchip tells of a ADC problem under some conditions , from what i am seeing is under most conditions and it hangs the cpu

http://ww1.microchip.com/downloads/en/DeviceDoc/80497F.pdf

The code has worked fine on other chips ( 16f1825, 16F1829 ,) and does work ok on this one when it does not hang the chip


Typically the chip hangs ranging form 1 min to to 20mins , but the code functions as it should during that time

i confirmed this part of the code by not doing the ADcin command and setting the "Value" variable = to a set number with no other changes and no cpu occured - tested for over 1 hour

Unfortunately i dont have another silicon revision to confirm my thoughts , but a workable get around would confirm the issue

Microchip tells of 2 workarounds , ...

1. is change to dedicated RC oscillator - not an option - when using the internal osc
2. Provide a fixed delay in software to stop the A-to-D conversion manually, after all ten bits are
converted, but before the conversion would complete automatically

Option 2 means that the command of ADCIN cant be used ?? and need to be a set register , counter and flag approch , which i not done for
ADC, so some input on this would be helpful.

snippets of code as it relate to the ADC as follows

regards

Sheldon
my internal is 32Mhz



DEFINE ADC_BITS 10 ' Number of bits in ADCIN result - Required for adcin command
DEFINE ADC_SAMPLEUS 10 ' ADC sampling time in microseconds - Required for adcin command

' ------------ADC Settings , routines and Variables ----------------
ADCON0 = %00010001 ' bit 7 -N/A , Bit 6-2 = ADC chan Sel /Temperature output /FVR output = AN4 sel = 00100 ,
' Bit 1 - Go/_done status flag - 1 = Go do ADC / 0 = Done ADC , Bit 0 = Enable ADC = 1 / 0 = Disable ADC

ADCON1 = %11110000 ' bit 7 = 1 ADFM ( ADRESH, ADRESL - right justify ).Bit 6-4 ADCS = 111 - using FRC internal ( 1.6us per sample)
' Bit3 - N/A , Bit2 = 0 (Vref- is connected to Vss) , Bit1-0 = 00 - Vref+ connected to VDD

FVRCON = %00000010 ' Bit 7 =0 disable Fixed Voltage Ref Modual, Bit 6 = VRef ready bit =1 always ok on 16F1825, Bit 5 - Temp indicator 1= enable/0 = disable
' Bit 4 = Temp Indicator Range Sel 0=Vout -Low range / 1= Vout -High range , Bit 3-2 = 00( DAC Fixed volt sel )
' Bit 1-0 = 10 - ADC Fixed Vref of 2.048v

AvgCount CON 10 ' Number of samples to average in Average routine
Fastspread CON 200 ' Fast Average threshold +/- in Average routine
ADavg VAR WORD ' Accumulated Varable of Readings in Average routine
Value VAR WORD ' Temp varable assigned in Average routine

' ----------------------------------------------------------------------------------------


y = 0 ' ensure 0
While Y < 10 ' do 10 voltage reads
ADCIN 4 ,Value ' Read PortA.5 value into variable , this applies the fixed voltage ref (via ADCON0,ADCON1,FVRCON)
' to comparitor and ADC pin selected and gives result.
gosub Average ' Go do running average of ADC reading
y = y+1 ' Increment loop counter
wend



' -=-=-=-=-=-= Average Analog values - a DT routine -=-=-=-=-=-=-=-=-=-=
Average:
IF Value = ADavg Then NoChange
IF ABS (Value - ADavg) > Fastspread OR Value < AvgCount Then FastAvg
IF ABS (Value - ADavg) < AvgCount Then RealClose
ADavg = ADavg - (ADavg/AvgCount)
ADavg = ADavg + (Value/AvgCount)
GoTo AVGok
FastAvg:
ADavg = Value
GoTo AVGok
RealClose:
ADavg = ADavg - (ADavg/(AvgCount/4))
ADavg = ADavg + (Value/(AvgCount/4))
AVGok:
Value = ADavg ' Put Average back into Value
NoChange:
Return

longpole001
- 24th November 2013, 01:08
by setting the ADC command enable / disable at the beginning / end of the subrouting which has the adcin command , the hanging is not as often but its there still

towlerg
- 24th November 2013, 01:56
Wow, what a ballsie guy. If I saw anything from from Microchip even hinting at such a problem, I'd drop that PIC so fast.

longpole001
- 24th November 2013, 04:01
well i next time ill ask the chip supplier for rev3 or better , but like most supplier its is very rare they actually supply details of the silicon ver with chip supplied details

Amoque
- 24th November 2013, 12:21
I think chips are like children in that once you own them you have to work with what you have... Certainly abandoning one to start again with another is, except under the rarest circumstances, a difficult choice.





While many of you do not share the holiday, I wish for you all the blessings we in the US celebrate this Thanksgiving season.

longpole001
- 25th November 2013, 08:44
rereading the methods to get around the problem option 1 actully looks the best way , but i am not sure how to do this

but it appears that by setting the ADC f/OSC conversion clock to the FRC internal , then putting the CPU into low power mode ( SLEEP mode ) , then doing a sample , then exit low power mode (SLEEP mode) by using the watchdog timer ( no other way i can see to make sleep mode exit)

i am guessing this may work but not sure ,

1. set up watchdog timer to be enabled by software bit ( _WDTE_SWDTEN ) ;WDT controlled by the SWDTEN bit in the WDTCON register) in config1 word
2. set WDTCON with 1ms timeout and enable watchdog timer lowest time
3. do asm command of sleep - to enter low power mode ( NAP 0 = too long a time about 18ms)
4. do adcin command which should complete a sample in 1.6uS
5.turn off watchdog timer

so the assumption is that the adcin command will work in low power mode and sample will complete in a max of 1ms

test to see !!!!!!!!!!!!

but anyone else can advise then please do

Cheers sheldon


item 1


' config for 16F1947
#CONFIG
;----- CONFIG1 Options --------------------------------------------------
__config _CONFIG1, _FOSC_INTOSC & _WDTE_SWDTEN & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF


;----- CONFIG2 Options --------------------------------------------------
__config _CONFIG2, _LVP_OFF & _BORV_HI & _STVREN_ON & _PLLEN_ON & _WRT_OFF & _VCAPEN_OFF
#ENDCONFIG



item 2 - 5


ADCON0 = %00010001 ' enable ADC AN4 , ADCON1 setup at start of program

y = 0 ' ensure 0
While Y < 10 ' do 10 voltage reads
' silicon bug in rev2 of 16F1947 , requires ADC to be done in lowpower mode and with FDC osc clock internal
WDTCON = %00000001 ' start watchdog timer set for 1ms so that sleep mode is exit after doing adcin commands
asm
SLEEP ;'Put cpu into low power mode
endasm
ADCIN 4 ,Value ' Read PortA.5 value into variable , this applies the fixed voltage ref (via ADCON0,ADCON1,FVRCON)
WDTCON = %00000000 ' stop watchdog timer after adcin commands
gosub Average ' Go do running average of ADC reading
y = y+1 ' Increment loop counter
wend

Darrel Taylor
- 25th November 2013, 18:33
That won't work, since it will have to wake from sleep before running the ADCIN command.

I might suggest something like this...
It doesn't work in the simulator, but hopefully it will work on real hardware.

It uses the ADIF interrupt to wake from sleep. With the FRC clock, it only takes 48uS to complete a conversion.
Waiting for the WDT is going to take 1000uS or more.
The WDT is enabled just in case the conversion doesn't complete, but the ADIF should always wake it up first.

It assumes you are using other interrupts, and disables them accordingly.


#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG
OSCCON = %11110000 ; 32Mhz Internal

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 25 ' 19200 Baud @ 32MHz, 0.16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

ADON VAR ADCON0.0 ; A/D converter Enable
GoDone VAR ADCON0.1 ; A/D conversion in progress
ADIE VAR PIE1.6 ; A/D Interrupt Enable
ADIF VAR PIR1.6 ; A/D Interrupt Flag
GIE VAR INTCON.7 ; Global Interrupt Enable
GIEsave VAR BIT ; Saves state of GIE

ADchan VAR BYTE ; Current A/D channel
ADvalue VAR WORD ; A/D result

ADCON1 = %10110000 ; Right Justify, FRC clock
ADON = 1

Main:
FOR ADchan = 0 TO 16 ; Loop through all A/D channe
ADCON0 = (ADCON0 & %11) | (ADchan << 2) ; Set Analog Channel
PAUSEUS 20 ; Acquisition time
GIEsave = GIE ; Save state of Global Interrupts
GIE = 0 ; Disable Global interrupts
ADON = 0 ; reset A/D module
ADON = 1
ADIF = 0 ; Clear Analog Interrupt Flag
ADIE = 1 ; Enable Analog Interrupt
GoDone = 1 ; Start Analog conversion
@ SLEEP ; go to SLEEP
ADIE = 0 ; Disable Analog Interrupt
GIE = GIEsave ; Restore Global Interrupt state
ADvalue.HighByte = ADRESH ; Get A/D result
ADvalue.LowByte = ADRESL

HSEROUT [DEC2 ADchan," = ",DEC ADvalue,13,10]
PAUSE 200
NEXT ADchan
GOTO Main

longpole001
- 25th November 2013, 22:10
thanks Darrel,


I have put this code in for the AN4 sensor only , however it seems i will have to do this for other A/D services for this rev of chip ???? :mad:


your DT_INTS-14.bas is included as part of this code for timer0 , and the variable GIE was already in use ,

timer0 setup as 8ms timer , and this A/D routine is called from it after incrementing counters of timer0 = 5sec duration to do a read of the Voltage level


couple of questions
1. Is the duration of the sample time of 20us seemed long for 1 A/D channel ? as the spec sheet for conversion using FRC is about 1.6us average - a max period of 6uS
2. i thought the sleep instruction ( low power mode ) may need to be issued prior to the conversion starting , or are all commands after a sleep command not actioned till sleep mode is terminated ?
3. as this now monitors the interrupt for sleep to finish , then the duration of this routine must be shorter than any other generated interrupts using DT_INT14 else this will not work ??



the code as it stands now
waiting on a Battery power duration test to complete to see if this works ok

Cheers

Sheldon



Get_volts :
ADON VAR ADCON0.0 ; A/D converter Enable
GoDone VAR ADCON0.1 ; A/D conversion in progress
ADIE VAR PIE1.6 ; A/D Interrupt Enable
ADIF VAR PIR1.6 ; A/D Interrupt Flag
GIEsave VAR BIT ; Saves state of GIE


ADCON0 = %00010001 ' enable ADC AN4 ,( ADCON1 setup at start of program , Right Justify, FRC clock )

y = 0 ' ensure 0
While Y < 10 ' do 10 voltage reads
' silicon bug in rev2 of 16F1947 , requires ADC to be done in lowpower mode and with FDC osc clock internal
' also ADCIN command wont work in sleep mode , interupts exit sleep mode
PAUSEUS 20 ; Acquisition time
GIEsave = GIE ; Save state of Global Interrupts ( GIE defined in DT_INTS-14.bas )
GIE = 0 ; Disable Global interrupts
ADON = 0 ; reset A/D module
ADON = 1 ; turn on A/D module
ADIF = 0 ; Clear Analog Interrupt Flag
ADIE = 1 ; Enable Analog Interrupt
GoDone = 1 ; Start Analog conversion
@ SLEEP ; go to SLEEP
ADIE = 0 ; Disable Analog Interrupt
GIE = GIEsave ; Restore Global Interrupt state ( GIE defined in DT_INTS-14.bas )
value.HighByte = ADRESH ; Get A/D result
value.LowByte = ADRESL

' ADCIN 4 ,Value ' Leave out for Rev 2 of 16F1947 - Read PortA.5 value into variable , this applies the fixed voltage ref (via ADCON0,ADCON1,FVRCON)
gosub Average ' Go do running average of ADC reading
y = y+1 ' Increment loop counter
wend

Darrel Taylor
- 25th November 2013, 23:05
1) If you are only reading 1 channel, you don't need any acquisition time.

2) When you put a PIC to SLEEP, all program execution STOPS.
Some peripherals may continue to operate, but the program will not run again until it wakes up.

3) When you put a PIC to SLEEP, the main oscillator is shut-down.
If you are running TIMER0 from the system clock, it too stops during sleep, and your 8mS periods will be extended.

longpole001
- 26th November 2013, 00:13
thanks darrel ,

ill let you know how it goes for testing in 24 hours

Well i wish had known of issues with this chip prior , will make an effort to check every time now for microchips erratica on each chip before using
oh well , it seems this problem is only with the silicon ver 2 , i hope the supplier can help me with higher revisions exchanged , cos this is dog of a version


cheers

Sheldon

longpole001
- 26th November 2013, 08:38
seems to be workin , cheers darrel