Trying to get my head around the Atmel Microchip XMEGA ADC.
Useful References
[1] http://ww1.microchip.com/downloads/en/Appnotes/00002535A.pdf
This picture seems to imply that all 16 inputs ADC0-ADC15 can be switched 
Reference [1] "In devices with two ADCs, the inputs can only be connected to the corresponding port. Meaning that ADCA can be connected only to PORT A, and ADC B can be connected only to PORT B."
The XMEGA 128A1 has two ADCs 
PROBLEM SOME ADC PINS READ WRONG
The ATXMEGA128 has 16 analogue inputs.  These are on Port A and Port B.
The first indication of the problem was that ADC12 which monitored the 5V rail was reading high.  I lifted the top resistor of the divider and so there was now a 5K2 resistor to GND.  Using a multimeter, it read 1.0V when I was expecting 0V.
I put a post on the BASCOM forum.
https://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&p=81048#81048
and someone asked had i considered JTAG.
DOES JTAG INFLUENCE THIS?
A response to the MCSELEC forum post mentions JTAG Fuses.  I wonder.
What Pins?
JTAG Fuses?
Page 58 of the datasheet shows that indeed the JTAG uses pins on port B.
Now I read the fuses
I note FUSEBYTE0 mentions JTAG But what does it mean?XMEGA A1U Datasheet
7.4 Fuses and Lock bits
The fuses are used to configure important system functions, and can only be written from an external programmer. The application software can read the fuses. The fuses are used to configure reset sources such as brownout detector and watchdog, startup configuration, JTAG enable, and JTAG user ID.
The lock bits are used to set protection levels for the different flash sections (that is, if read and/or write access should be blocked). Lock bits can be written by external programmers and application software, but only to stricter protection levels.
Chip erase is the only way to erase the lock bits. To ensure that flash contents are protected even during chip erase, the lock bits are erased after the rest of the flash memory has been erased.
An unprogrammed fuse or lock bit will have the value one, while a programmed fuse or lock bit will have the value zero.
Both fuses and lock bits are reprogrammable like the flash program memory 
7.13 JTAG Disable
It is possible to disable the JTAG interface from the application software. This will prevent all external JTAG access to the device until the next device reset or until JTAG is enabled again from the application software. As long as JTAG is disabled, the I/O pins required for JTAG can be used as normal I/O pins.
So I add a line "DISABLE JTAG"
And that my friends fixed the problem!
This is my test program 
'*******************************************************************************
' FILENAME:    
ATXMEGA128A1 ADC Test x.bas
'
' PROCESSOR:   
ATXMEGA128A1
' CLOCK:       
16Mhz XTAL
' TITLE:
' BOARD:       
0420-04 and 0420-01
' MODIFIED:    
29-NOV-2021
' AUTHOR:      
Frank Thomson
'*******************************************************************************
$regfile = "xm128A1Udef.dat" '"xm128A1Udef.dat" '  "C:\MCS\BASCAVR2082\DAT\xm128A1Udef.dat"
$framesize = 200         ' After global
variables then after unused SRAM, grows bottom up, string conversion routines
(PRINT, LCD, INPUT) require a buffer in SRAM
$swstack = 200           ' ISR routine
parameters and grow top down
$hwstack = 200           ' Return address
after routine call (SUB, FUNCTION, GOSUB) and grow top down
$crystal = 16000000
'Config Osc = Enabled , 32mhzosc = Enabled         ' enable 2 MHz and 32 MHz internal
oscillators
'Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc =
1_1
Config osc = disabled , EXTOSC = enabled , 32KHZOSC=DISABLED, pllosc = enabled , range = 12MHZ_16MHZ , startup = XTAL_16KCLK , pllsource = extclock , pllmul = 1
Config Sysclock = PLL , Prescalea = 1 , Prescalebc = 1_1
Disable Jtag   <-- This is the fix
'$sim                   
' Comment this out for real program
' INITIALIZE HARDWARE
'PORT A has the first 8 Analogue inputs.
' Can only be read with ADCA
'                 
TypRead
'PORT A.0 - 0 ADC0 
-  1  Connects to GND  0R
'     A.1 - 0
ADC1    13   16k to GND
'     A.2 - 0
ADC2    22   16k to GND
'     A.3 - 0
ADC3    19   16k to GND
'     A.4 - 0
ADC4    17   16k to GND
'     A.5 - 0
ADC5    14   16k to GND
'     A.6 - 0
ADC6    34   24k to GND
'     A.7 - 1
ADC7    34   24k to GND
Config Porta = &B00000000    ' All IN
Porta = &B00000000
' PORT B Has another 8 ADCs  They can only be read with ADCB
'          DDR      TypRead
'PORT B.0 - 0 ADC8     
7   Test Point TP126  (Open Circuit)
'     B.1 - 0
ADC9   1189   RF
Power Detector via divider 2k4 x 750R to GND
'     B.2 - 1 ADC10
- 437   DAC1 output Not normally used for
ADC
'     B.3 - 0
ADC11   324   Test Point TP127   (Open Circuit)
'     B.4 - 0
ADC12  1613   8K2 to GND
'     B.5 - 0
ADC13   841   Adjustable regulator via  12k x 3k0 
to GND
'     B.6 - 0
ADC14  1482   12V input mon via divider 18k x 1k5  to GND
'     B.7 - 0
ADC15  1652   3V3 rail mon via divider  12k x 3k0 
to GND
'               
76543210
Config Portb = &B00000100
Portb = &B00000000
' PORTS C, D, E, F, H, J, K, Q Default to ALL INPUTS
' Except Port D which has a LED
'PORT D.0 - 0  
0  LED SPARE 2
'     D.1 - 0   0  LED
SPARE 1
'     D.2 - 0   0  LED
FAIL
'     D.3 - 0   0  LED
STATUS
'     D.4 - 0   0  LED
TESTING
'     D.5 - 0   0  LED
DEVICE
'     D.6 - 0   0 
Reserved for USB N
'     D.7 - 0   0 
Reserved for USB N
'               
76543210
Config PortD = &B00000011
PortD        = &B00000000
'---- INITIALISE COMMS
---------------------------------------------------------------------
 Config Com5 = 9600 , mode = ASYNCHRONEOUS, Parity = None , Stopbits = 1 , Databits = 8
 Open "COM5:" For Binary As #6
 Config Serialin6 = Buffered , Size = 10
'----- INITIALISE ADC
----------------------------------------------------------------------
' The XMEGA128A1 has two Analogue to Digital Converters.
' Inputs ADC0 to 7 
can only be routed by the MUX register to ADCA and 8-15 to ADCB.
' There are 4 channels - For these tests we will only use
Channel 0
' Prescaler= 4, 8, 16, 32, 64, 128, 256 and 512
' DIFFERENTIAL MODE
'Config Adca = Single , Convmode = signed , Resolution =
12bit , Dma = Off , Reference = Int1v , Event_mode = None , Prescaler = 512 ,
Ch0_gain = 1 , Ch0_inp = diff , Mux0 = &B0000000, Ch1_gain = 1 , Ch1_inp =
INTERNAL , Mux1 = &B1_000 , Ch2_gain = 1 , Ch2_inp = Single_ended , Mux2 =
&B10000000 , Ch3_gain = 1 , Ch3_inp = DIFF , Mux3 = &B1100000
'Config AdcB = Single , Convmode = signed , Resolution =
12bit , Dma = Off , Reference = Int1v , Event_mode = None , Prescaler = 512 ,
Ch0_gain = 1 , Ch0_inp = diff , Mux0 = &B0000000, Ch1_gain = 1 , Ch1_inp =
INTERNAL , Mux1 = &B1_000 , Ch2_gain = 1 , Ch2_inp = Single_ended , Mux2 =
&B10000000 , Ch3_gain = 1 , Ch3_inp = DIFF , Mux3 = &B1100000
' SINGLE ENDED
Config Adca = Single , Convmode = signed , Resolution = 12bit , Dma = Off , Reference = Int1v , Event_mode = None , Prescaler = 512 , Ch0_gain = 1 , Ch0_inp = SINGLE_ENDED , Mux0 = &B0000000, Ch1_gain = 1 , Ch1_inp = INTERNAL , Mux1 = &B1_000 , Ch2_gain = 1 , Ch2_inp = Single_ended , Mux2 = &B10000000 , Ch3_gain = 1 , Ch3_inp = DIFF , Mux3 = &B1100000
Config AdcB = Single , Convmode = signed , Resolution = 12bit , Dma = Off , Reference = Int1v , Event_mode = None , Prescaler = 512 , Ch0_gain = 1 , Ch0_inp = SINGLE_ENDED , Mux0 = &B0000000, Ch1_gain = 1 , Ch1_inp = INTERNAL , Mux1 = &B1_000 , Ch2_gain = 1 , Ch2_inp = Single_ended , Mux2 = &B10000000 , Ch3_gain = 1 , Ch3_inp = DIFF , Mux3 = &B1100000
' MUX is
' See Table 28-16 page 362 of XMEGA Manual
"Differential without gain"
'      7 6 5 4 3 2 1
0
'     /  | | | | \ \ \ 
MUXNEG DIFFERENTIAL   
SINGLE_ENDED
' Not    Positive \
\ \Negative Side           MUXNEG is
IGNORED
' Used   Side
of       Of the ADC
'        ADC           0 0 0 = ADC0Pin
'        = Channel
'        Number        1 0 1 = PAD Ground
'                     
1 1 0 = Reserved
'                     
1 1 1 = Internal Ground
'
'-----DIMENSION VARIABLES-------------------------------------------------------------------
dim k_b as byte    ' Used to hold input
Dim LEDcounter as word
dim i as byte
dim mux as byte
Dim myADCX as integer
dim MUXNEG as byte :  MUXNEG = &b00000101     ' See table
above.
'-----MAIN PROGRAM
START---------------------------------------------------------------------
portd.0 = 1 ' LED
SPARE 2 ON
Print #6 ,
print #6, "AT X Mega 128A1U ADC
Program";
loopforever:
k_b = Inkey(#6)  ' Get a byte from the uart. 
Loop keeps running
if k_b > 0 Then  ' we have a character
    print #6, chr(k_b)   'echo it
    ' ----READ ALL 16
ADCs------------------------------------------
    For i = 0 to 15
        mux = i * 8
        mux = mux and &b01111000    ' Make sure LS 3 bits are zero
        mux = mux OR MUXNEG         ' Add in the LS 3
bits
        if i <= 7 then
            myADCX = getadc(ADCA, 0 , mux) 
' ADC inputs 0-7 can be routed to ADCA only
        else
            myADCX = getadc(ADCB, 0 , mux) 
' ADC inputs 8-15 can be routed to ADCB only
        end if
        'Print #6,
i ; " ,  "; myADCX
        Print #6, myADCX
    Next i
end if
' Heartbeat LED
LEDcounter   =   
LEDcounter  + 1
if LEDcounter >= 60000 then
    toggle portd.1   'FAIL LED ON OFF
    LEDcounter = 0
end if
goto loopforever
| 
 | U | No U | 
| [AU] SINGLE_ENDED UNSIGNED | Read A from A & Subtract PA0 | Read A from A & Subtract PA0 | 
| ADC0-7b Port A | PA0=0V reads 166 PA1=0 PA1=1V = | PA0 0V reads 138 PA1=0 reads 157 =1V=4095 | 
| ADC8-15 Port B | 11 PB3=0V Reads 182 =1V 4095 All show up on ADC A. ADCB is crap | 8 PB0 0V = 1V = 4095 11 PB3=0V = 1 @1V=2047 These show up on ADCB as both 0-7 and 8-15 | 
| 
 | 
 | 
 | 
| [AS] SINGLE ENDED SIGNED | Read A from A  | Read A from A  | 
| ADC0-7b Port A | PA0=0V reads -10 PA1=0V= @1=2047 | ON ADCA PA0=0V Reads -3 PA1=0V = -3 @1=2047 | 
| ADC8-15 Port B | Show up on ADCA 08 PB0=0V = 5 @1V= 2047 11 PB3=0V =0 @1V = 2047 | ON ADCB 8 PB0=0V = 0 @1V=2047 11PB3=0V = 1 @1V=2047 | 
| 
 | 
 | 
 | 
| Signed DIFFERENTIAL
    | 
 | Read A from A. Read B from B but unsure how to correct | 
| ADC0-7b Port A | ADC A Works. -? To 2047 0V in read about -6 | PA0=0V reads -1 PA1=0V = 0 @1V=2047 | 
| ADC8-15 Port B | ADC A 8-15 seems to work. 0V in read about -6 | 8 PB0=0V= -530 @1V=+1850 11PB3=1V=      @1V=-2048 | 
| Signed DIFFERENTIAL
    | 
 | 
 | 
| ADC0-7b Port A | ADC A -? To +2047. With 0V in, Read about -28 | PA0 reads -1 | 
| ADC8-15 Port B | ADC A 8-15 seems to
  work. | Results show up on ADCB 08 PB0 0V = -522 1V = 1737 
 | 
| 
 | 
 | Note with MuxNex set to 111, the registers read back 011 = ADC3 pin | 
| 
 | 
 | 
 | 
PROBLEM: EEPROM IS NOT BEING RETAINED
XMEGA128A1U
Is it a Fuse issue?
Fuse Byte 0 OxFF JTAG UID So we assume no
Fuse Byte 1 0x00  Watchdog stuff - We assume no
Fuse Byte 2 0xFF  6 BOOTRST 5 TOSCSEL - We assume no
Fuse Byte 3 
Fuse Byte 4 - no
Fuse Byte 5 Bit 3 EESAVE 
Bit 3 – EESAVE: EEPROM is Preserved through the Chip Erase
A chip erase command will normally erase the flash, EEPROM, and internal SRAM. If this fuse is programmed, the
EEPROM is not erased during chip erase. This is useful if EEPROM is used to store data independently of the
software revision.
Table 4-8. EEPROM preserved through chip erase.
Changes to the EESAVE fuse bit take effect immediately after the write timeout elapses. Hence, it is possible to
update EESAVE and perform a chip erase according to the new setting of EESAVE without leaving and reentering
programming mode
     7654 3210
37 = 0011 0111
          1    1= EEPROM Erased during chip erase
          0    0= Preserved      





 
No comments:
Post a Comment