AT32UC3C0512C on STK600 ADC Single

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, Freaks!

Please, help me. I'm using AT32UC3C0512C on STK600 with STK600-RCUC3C0-36 routing and STK600-TQFP144 socket cards. STK600 connects to the PC and powers through USB cable. AREF0 jumper is mounted, AREF1 - unmounted. I use AREF1 as ADC input voltage to the ADCIN6 (PA10 uC and PB02 STK). Also, I programmed microcontroller to use external oscillator and switch on STK CLOCK to EXT position. In Atmel Studio 7 I set Vtarget 3.6V, Aref0 3.3V, Aref1 2.3V and Oscillator 16.01 MHz. I switch as output pins PC08-PC15 uC (PK00-PK07 on STK) and connect them on LED STK connector. I try to launch ADC in a Single-ended mode. INPSEL00.conv1 - set to 6 and INNSEL00.conv1 - set to 9. ADC set in 8 bit resolution and program set output pins to this value. Here is my program:

 

main.c file

#include <avr32/io.h>
#include <stdint.h>
#include "mainDefines.h"
#include "mainFunctions.h"

int PM_Initialization(void);	//Функция инициализации менеджера питания микроконтроллера
int SCIF_Initialization(void);	//Функция инициализации интерфейса контроля системы
int GPIO_Initialization(void);	//Функция инициализации выводов микроконтроллера
int ADC_Initialization(void);	//Функция инициализации аналого-цифрового преобразователя

int main(void)
{
	PM_Initialization();
	SCIF_Initialization();
	GPIO_Initialization();

	int i;

	long data;

	uint32_t pins[8] =
	{
		PC08,
		PC09,
		PC10,
		PC11,
		PC12,
		PC13,
		PC14,
		PC15
	};

	AVR32_ADCIFA.CFG.adcen = 0;
	AVR32_ADCIFA.CFG.sleep = 0;
	AVR32_ADCIFA.CFG.ssmq = 0;
	AVR32_ADCIFA.CFG.frm = 0;
	AVR32_ADCIFA.CFG.rs = 2;
	AVR32_ADCIFA.CFG.shd = 1;
	AVR32_ADCIFA.CFG.exref = 0;
	AVR32_ADCIFA.CFG.muxset = 1;
	AVR32_ADCIFA.CFG.sut = 0;

	AVR32_ADCIFA.CKDIV.cnt = 31;

	AVR32_ADCIFA.SHCAL.gain0 = 1;
	AVR32_ADCIFA.ADCCAL.gcal = 1;
	AVR32_ADCIFA.SHG0.gcnv0 = 1;

	AVR32_ADCIFA.SEQCFG0.sa = 1;
	AVR32_ADCIFA.SEQCFG0.hwla = 0;
	AVR32_ADCIFA.SEQCFG0.socb = 0;
	AVR32_ADCIFA.SEQCFG0.ovsx2 = 0;
	AVR32_ADCIFA.SEQCFG0.shdyn = 0;
	AVR32_ADCIFA.SEQCFG0.trgsel = 0;
	AVR32_ADCIFA.SEQCFG0.sres = 2;
	AVR32_ADCIFA.SEQCFG0.cnvnb = 0;

	AVR32_ADCIFA.INPSEL00.cnv0 = 6;

	AVR32_ADCIFA.INNSEL00.cnv0 = 9;

	AVR32_ADCIFA.CFG.adcen = 1;
	while(!AVR32_ADCIFA.SR.sutd){}
	AVR32_ADCIFA.CR.soc0 = 1;

	data = AVR32_ADCIFA.resx[0];

	for(i = 0; i < 8; ++i)
	{
		if(data & _BV(i)){
			unsetPin(pins[i]);
		}
		else
		{
			setPin(pins[i]);
		}
	}
}

int PM_Initialization()
{
	unlockPMReg(AVR32_PM_MCCTRL);
	AVR32_PM.MCCTRL.mcsel = 1;
	lockPMReg();

	unlockPMReg(AVR32_PM_CPUSEL);
	AVR32_PM.CPUSEL.cpusel = 0;
	AVR32_PM.CPUSEL.cpudiv = 0;
	lockPMReg();

	unlockPMReg(AVR32_PM_PBASEL);
	AVR32_PM.PBASEL.pbasel = 0;
	AVR32_PM.PBASEL.pbadiv = 0;
	lockPMReg();			

	unlockPMReg(AVR32_PM_PBBSEL);
	AVR32_PM.PBBSEL.pbbsel = 0;
	AVR32_PM.PBBSEL.pbbdiv = 0;
	lockPMReg();

	unlockPMReg(AVR32_PM_PBCSEL);
	AVR32_PM.PBCSEL.pbcsel = 0;
	AVR32_PM.PBCSEL.pbcdiv = 0;
	lockPMReg(); 

	unlockPMReg(AVR32_PM_CPUMASK);
	AVR32_PM.cpumask |= _BV(1);
	lockPMReg();					

	unlockPMReg(AVR32_PM_HSBMASK);
	AVR32_PM.hsbmask |= 0x1FFF;
	lockPMReg();			

	unlockPMReg(AVR32_PM_PBAMASK);
	AVR32_PM.pbamask |= 0x7DFFFFF;
	lockPMReg();				

	unlockPMReg(AVR32_PM_PBBMASK);
	AVR32_PM.pbbmask |= 0x7F;
	lockPMReg();				

	unlockPMReg(AVR32_PM_PBCMASK);
	AVR32_PM.pbcmask |= 0x3FF;
	lockPMReg();				

	unlockPMReg(AVR32_PM_CFDCTRL);
	AVR32_PM.CFDCTRL.cfden = 0;
	AVR32_PM.CFDCTRL.sfv = 0;
	lockPMReg();				

	return 0;
}

int SCIF_Initialization()
{
	unlockSCIFReg(AVR32_SCIF_OSCCTRL);
	AVR32_SCIF.OSCCTRL[0].mode = 1;
	AVR32_SCIF.OSCCTRL[0].gain = 3;
	AVR32_SCIF.OSCCTRL[0].agc = 0;
	AVR32_SCIF.OSCCTRL[0].startup = 0;
	AVR32_SCIF.OSCCTRL[0].oscen = 1;
	lockSCIFReg();

	return 0;
}

int GPIO_Initialization()
{
	unsigned char i;

	for(i = 0; i < NFUNC; ++i)
	{
		setPinFunction(pinsFunctions[i].pin, pinsFunctions[i].function);
	}

	return 0;
}

mainFunctions.h

 

#ifndef MAINFUNCTIONS_H_
#define MAINFUNCTIONS_H_
#endif /* MAINFUNCTIONS_H_ */

/***GPIO***/
uint8_t gpioPort(uint8_t);
uint8_t gpioPin(uint8_t);
void setPinFunction(uint8_t, char);
void setPin(uint8_t);
void unsetPin(uint8_t);
uint8_t readPinValue(uint8_t);

/***PM***/
void unlockPMReg(uint16_t);
void lockPMReg(void);

/***SCIF***/
void unlockSCIFReg(uint16_t);
void lockSCIFReg(void);

 

mainFunctions.c

 

#include <stdint.h>
#include <avr32/io.h>

#define _BV(pin)	(1 << pin)

uint8_t gpioPort(uint8_t gpioNumber)
{
	return gpioNumber / 32;
}

uint8_t gpioPin(uint8_t gpioNumber)
{
	return gpioNumber % 32;
}

void setPinFunction(uint8_t gpioNumber, char gpioFunction)
{
	uint8_t port = gpioPort(gpioNumber);
	uint8_t pin = gpioPin(gpioNumber);

	switch(gpioFunction)
	{
		case 'A':
			AVR32_GPIO.port[port].gperc |= _BV(pin);
			AVR32_GPIO.port[port].pmr0c |= _BV(pin);
			AVR32_GPIO.port[port].pmr1c |= _BV(pin);
			AVR32_GPIO.port[port].pmr2c |= _BV(pin);
			break;
		case 'B':
			AVR32_GPIO.port[port].gperc |= _BV(pin);
			AVR32_GPIO.port[port].pmr0s |= _BV(pin);
			AVR32_GPIO.port[port].pmr1c |= _BV(pin);
			AVR32_GPIO.port[port].pmr2c |= _BV(pin);
			break;
		case 'C':
			AVR32_GPIO.port[port].gperc |= _BV(pin);
			AVR32_GPIO.port[port].pmr0c |= _BV(pin);
			AVR32_GPIO.port[port].pmr1s |= _BV(pin);
			AVR32_GPIO.port[port].pmr2c |= _BV(pin);
			break;
		case 'D':
			AVR32_GPIO.port[port].gperc |= _BV(pin);
			AVR32_GPIO.port[port].pmr0s |= _BV(pin);
			AVR32_GPIO.port[port].pmr1s |= _BV(pin);
			AVR32_GPIO.port[port].pmr2c |= _BV(pin);
			break;
		case 'E':
			AVR32_GPIO.port[port].gperc |= _BV(pin);
			AVR32_GPIO.port[port].pmr0c |= _BV(pin);
			AVR32_GPIO.port[port].pmr1c |= _BV(pin);
			AVR32_GPIO.port[port].pmr2s |= _BV(pin);
			break;
		case 'F':
			AVR32_GPIO.port[port].gperc |= _BV(pin);
			AVR32_GPIO.port[port].pmr0s |= _BV(pin);
			AVR32_GPIO.port[port].pmr1c |= _BV(pin);
			AVR32_GPIO.port[port].pmr2s |= _BV(pin);
			break;
		case 'G':
			AVR32_GPIO.port[port].gperc |= _BV(pin);
			AVR32_GPIO.port[port].pmr0c |= _BV(pin);
			AVR32_GPIO.port[port].pmr1s |= _BV(pin);
			AVR32_GPIO.port[port].pmr2s |= _BV(pin);
			break;
		case 'H':
			AVR32_GPIO.port[port].gperc |= _BV(pin);
			AVR32_GPIO.port[port].pmr0s |= _BV(pin);
			AVR32_GPIO.port[port].pmr1s |= _BV(pin);
			AVR32_GPIO.port[port].pmr2s |= _BV(pin);
			break;
		case 'I':
			AVR32_GPIO.port[port].gpers |= _BV(pin);
			AVR32_GPIO.port[port].puers |= _BV(pin);
			AVR32_GPIO.port[port].pderc |= _BV(pin);
			break;
		case 'O':
			AVR32_GPIO.port[port].gpers |= _BV(pin);
			AVR32_GPIO.port[port].oders |= _BV(pin);
			AVR32_GPIO.port[port].puerc |= _BV(pin);
			AVR32_GPIO.port[port].pderc |= _BV(pin);
			AVR32_GPIO.port[port].odcr0s |= _BV(pin);
			AVR32_GPIO.port[port].odcr1s |= _BV(pin);
			break;
	}
}

void setPin(uint8_t gpioNumber)
{
	AVR32_GPIO.port[gpioPort(gpioNumber)].ovrs |= _BV(gpioPin(gpioNumber));
}

void unsetPin(uint8_t gpioNumber)
{
	AVR32_GPIO.port[gpioPort(gpioNumber)].ovrc |= _BV(gpioPin(gpioNumber));
}

uint8_t readPinValue(uint8_t gpioNumber)
{
	uint8_t port = gpioPort(gpioNumber);
	uint8_t pin = gpioPin(gpioNumber);

	return (AVR32_GPIO.port[port].pvr & _BV(pin));
}

void unlockPMReg(uint16_t pm_register)
{
	AVR32_PM.UNLOCK.addr = pm_register;
	AVR32_PM.UNLOCK.key = 0xAA;
}

void lockPMReg()
{
	AVR32_PM.UNLOCK.key = 0;
}

void unlockSCIFReg(uint16_t scif_register)
{
	AVR32_SCIF.UNLOCK.addr = scif_register;
	AVR32_SCIF.UNLOCK.key = 0xAA;
}

void lockSCIFReg()
{
	AVR32_SCIF.UNLOCK.key = 0x00;
}

 

mainDefines.h

 

#include <stdint.h>

#ifndef MAINDEFINES_H_
#define MAINDEFINES_H_

#define PA00	0
#define PA01	1
#define PA02	2
#define PA03	3
#define PA04	4
#define PA05	5
#define PA06	6
#define PA07	7
#define PA08	8
#define PA09	9
#define PA10	10
#define PA11	11
#define PA12	12
#define PA13	13
#define PA14	14
#define PA15	15
#define PA16	16
#define PA19	19
#define PA20	20
#define PA21	21
#define PA22	22
#define PA23	23
#define PA24	24
#define PA25	25
#define PA26	26
#define PA27	27
#define PA28	28
#define PA29	29
#define PB00	32
#define PB01	33
#define PB02	34
#define PB03	35
#define PB04	36
#define PB05	37
#define PB06	38
#define PB07	39
#define PB08	40
#define PB09	41
#define PB10	42
#define PB11	43
#define PB12	44
#define PB13	45
#define PB14	46
#define PB15	47
#define PB16	48
#define PB17	49
#define PB18	50
#define PB19	51
#define PB20	52
#define PB21	53
#define PB22	54
#define PB23	55
#define PB24	56
#define PB25	57
#define PB26	58
#define PB27	59
#define PB28	60
#define PB29	61
#define PB30	62
#define PB31	63
#define PC00	64
#define PC01	65
#define PC02	66
#define PC03	67
#define PC04	68
#define PC05	69
#define PC06	70
#define PC07	71
#define PC08	72
#define PC09	73
#define PC10	74
#define PC11	75
#define PC12	76
#define PC13	77
#define PC14	78
#define PC15	79
#define PC16	80
#define PC17	81
#define PC18	82
#define PC19	83
#define PC20	84
#define PC21	85
#define PC22	86
#define PC23	87
#define PC24	88
#define PC25	89
#define PC26	90
#define PC27	91
#define PC28	92
#define PC29	93
#define PC30	94
#define PC31	95
#define PD00	96
#define PD01	97
#define PD02	98
#define PD03	99
#define PD04	100
#define PD05	101
#define PD06	102
#define PD07	103
#define PD08	104
#define PD09	105
#define PD10	106
#define PD11	107
#define PD12	108
#define PD13	109
#define PD14	110
#define PD15	111
#define PD16	112
#define PD17	113
#define	PD18	114
#define PD19	115
#define PD20	116
#define PD21	117
#define PD22	118
#define PD23	119
#define PD24	120
#define PD25	121
#define PD26	122
#define PD27	123
#define PD28	124
#define PD29	125
#define PD30	126
#define ADCREF33_0		PA16
#define _BV(pin)	(1 << pin)
#define NFUNC	(sizeof pinsFunctions / sizeof pinsFunctions[0])

#endif /* MAINDEFINES_H_ */

struct pins_functions_map
{
	uint8_t pin;
	char function;
} pinsFunctions[] =
	{
		{ADCREF33_0, 'A'},,
		{PA10, 'A'},
		{PC08, 'O'},
		{PC09, 'O'},
		{PC10, 'O'},
		{PC11, 'O'},
		{PC12, 'O'},
		{PC13, 'O'},
		{PC14, 'O'},
		{PC15, 'O'},
	};

After program launch LED don't light at all. I try to change Aref1 though Atmel Studio and relaunch program, but still no result. Please help me. I new with uCs. Thanks for any help!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Change how you unlock the PM and SCIF registers.
The desired register and the unlock key must be written to the UNLOCK register in one instruction and then the next instruction should modify the desired register.
Access to the protected PM and SCIF registers is automatically locked after an update.
The Atmel header files define PM_UNLOCK and SCIF_UNLOCK macros.



An example., change
unlockPMReg(AVR32_PM_PBASEL);
AVR32_PM.PBASEL.pbasel = 0;
AVR32_PM.PBASEL.pbadiv = 0;
lockPMReg();


to, (if you like bitfields)
avr32_pm_unlock_t x;
avr32_pm_pbasel_t pba;
pba.pbasel = 0;
pba.pbadiv = 0;

x.addr = AVR32_PM_PBASEL;
x.key = 0xAA;
AVR32_PM.unlock = x;

AVR32_PM.pbasel = pba;



or if you like a more condensed format
PM_UNLOCK( PM_PBASEL );
AVR32_PM.pbasel = ( 0 << AVR32_PM_PBASEL_OFFSET ) | ( 0 << AVR32_PM_PBADIV_OFFSET );




The AVR32 has set/clear/toggle instructions therefore there is no need to read the register before setting or clearing individual bits,
eg. AVR32_GPIO.port[port].gpers = _BV(pin); is sufficient to set one bit in the .gper register,
and AVR32_GPIO.port[gpioPort(gpioNumber)].ovrc = _BV(gpioPin(gpioNumber)); will clear the required bit.



Minor points in void setPinFunction(,) ;
- pin-function 'G' is not available on the UC3Cxxxx
- the 'I' function should have a AVR32_GPIO.port[port].oderc = _BV(pin);

Last Edited: Sat. Sep 10, 2016 - 12:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you, mikech! I corrected my code, but still no effect. Seems microcontroller hungs after PM initialization. I tried to find mistakes and after initialiation of MCCTRL register in PM uC stops working. I don't know what I must correct. Please, help me one more.

 

Here my code:

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is your external clock connected and reaching the XIN pin ?


Temporarily disable the PM and SCIF initialisation and observe what happens with the default 115kHz internal clock.




The |= combination will produce incorrect results when using the bit clear/toggle instructions.
for example ;
AVR32_GPIO.port[port].gperc |= _BV(pin); will first read the GPER register, then clear the _BV(pin) bit and all the other bits that were previously set in the GPER !.
use AVR32_GPIO.port[port].gperc = _BV(pin); to efficiently clear bits.
AVR32_GPIO.port[port].gper &= ( ~ _BV(pin) ); is functionally equivalent to AVR32_GPIO.port[port].gperc = _BV(pin);
AVR32_GPIO.port[port].gper |= _BV(pin); is functionally equivalent to AVR32_GPIO.port[port].gpers = _BV(pin);

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I changed my code and a little bit simplifying it. I desided delete ADC instructions and understand why microcontroller hungs after PM initialization.
If I set MCSEL bitfield in MCCTRL register to 1 (Ocillator 0) and also enable SCIF initialization function, uC hungs. If I set MCSEL bitfield to 0 (RCSYS) and disable SCIF initialization function all LEDs lightning. I set CLOCK switch on the STK600 to EXT position and set Clock in Atmel Studio to 8MHz.

I read from STK600 User guide that powering from USB (my case) ~300mA can be delivered to the target section. So maybe when I set uC working from external clock (or enable many internal modules) it is not enough power? Only eight LEDs need ~ (20 mA * 8) = 160 mA. From AT32UC3C0512C datasheet I read that it can working in two modes - from 3.3 V and from 5 V. But I can't set more than 3.6 V in Atmel Studio.
If I powered STK600 from external power supply though jack connector, do I need switch on STK and remove VTARGET valtage jumper?
Thanks for your help, mikech!

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do not have an STK600 so cannot assist very much there :(


The micro has an internal 120MHz RC oscillator, (RC120M).
To use it you will need to set 1 wait-state in the FLASHC, then divide the CPU, HSB, PBA, PBB and PBC clocks by at least 2 and then select RC120M in MCCTRL
If that clock works then there is something wrong with your external clock.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, mikech! Thanks a lot for your help. It was really helpful. The problem was with a sequence of instructions. Firstly, I should to customize new oscillator and enable it. Then, I should to choose it in MCCTRL register of Power Manager. Only after that I should initialize ADC. Now it work the same way as I expected.

Attachment(s):