Search This Blog

Tuesday, November 30, 2021

XMEGA ADC

 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 B from A & subtract PA0

Read A from A & Subtract PA0
Read B from B & 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 B from
A

Read A from A
Read B from B

      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  
muxNeg = 000 as PortA.0

 

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
ADCB never seems to have anything sensible.  All read 600-900

 8 PB0=0V= -530    @1V=+1850

11PB3=1V=      @1V=-2048
Note negatives
This is weird. 

Signed DIFFERENTIAL  
muxNeg = 111 Internal Ground

 

 

      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.
ADCB never seems to have anything sensible

Results show up on ADCB

08 PB0 0V = -522 1V = 1737
Note 1737 + 522 = 2259 ???

 

 

 

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