Luminary Cortex-M3 and Keil IDE

Thread Starter

millwood

Joined Dec 31, 1969
0
I am moving gradually to the new ARMv7M variant, and specifically the Luminary chips. I have a dev board in the mail to me (LM3S811, $49 for the board, with a OLED display and can function like a jtag adapter should I move onto something else).

I had played with LPCs before but those Luminary beasts are totally different in how they are setting up, and sample code is hard to come by.

so it took me an entire morning to get something going.

Rich (BB code):
#include <lm3s811.h>

#define PORTA_ENABLED	0x01
#define PORTB_ENABLED	0x02
#define PORTC_ENABLED	0x04
#define PORTD_ENABLED	0x08
#define PORTE_ENABLED	0x0f

//hardware configuration
#define LED1	GPIO_PORTA_DATA_R					//1st led string on porta
#define LED2	GPIO_PORTC_DATA_R					//2nd led string on partc
#define LED3	GPIO_PORTD_DATA_R					//2nd led string on partd

void init_mcu(void) {

	SYSCTL_RCGC2_R=PORTA_ENABLED | PORTC_ENABLED | PORTD_ENABLED;	//enable gate a, c and d;

//set up porta
	GPIO_PORTA_DIR_R=0x0f;							//lowest four bits for output
	GPIO_PORTA_DEN_R=0x0f;							//lowest four bits enabled for digital
	GPIO_PORTA_AFSEL_R=0x00;						//no alternative functions on all 8 bits
	GPIO_PORTA_DATA_R=0x55;							//output set to 0b01010101. But only last four bits used due to DIR_R setting

//set up portc
	GPIO_PORTC_DIR_R=0xff;							//all 8 bits for output
	GPIO_PORTC_DEN_R=0xff;							//all 8 bits enabled for digital
	GPIO_PORTC_AFSEL_R=0x00;						//no alternative functions on all 8 bits
	GPIO_PORTC_DATA_R=0x01;							//output set to 0b00000001. But only last four bits used due to DIR_R setting

//set up portd
	GPIO_PORTD_DIR_R=0xff;							//all 8 bits for output
	GPIO_PORTD_DEN_R=0xff;							//all 8 bits enabled for digital
	GPIO_PORTD_AFSEL_R=0x00;						//no alternative functions on all 8 bits
	GPIO_PORTD_DATA_R=0x01;							//output set to 0b00000001. But only last four bits used due to DIR_R setting

}

void delay(int dly) {
	for (; dly>0; dly--)
		;
}

int main(void) {
	
	int LED2_i=1;
	int LED3_i=1;
	
	init_mcu();
	while (1) {
		delay(5000);
		LED1=~LED1;									//blinking led1
		
		LED2=LED2_i;
		if (LED2_i==0x80)							//if the left most bit is on
			LED2_i=1;								//reset to to the right most bit
		else
			LED2_i<<=1;								//otherwise, shift to the left by 1 bit

		LED3=LED3_i;
		if (LED3_i==0xff)							//if all leds are on
			LED3_i=0;								//turn all LEDs off
		else
			LED3_i=LED3_i+1;						//increment by 1;
	}

}
it is a way to blink 3 strings of LEDs on port A, port C and port D:

on port A, we are just blinking the last four leds:
on port C, we are rolling leds from the lowest bit to the highest bit.
on port D, we are just incrementing the leds, linearly.

the weird thing about those luminary chips is the rcgc registers. in particular, we have to run the clocks to the ports before we can use them. that took me a while to figure out, :).

so here it is. if someone is using the luminary chips, you don't have to waste a morning to figure that out.
 

Thread Starter

millwood

Joined Dec 31, 1969
0
I use hi-tide as my IDE on PIC. it is a great improvement over the command lines, but not that great for debugging purposes.

Keil's IDE, uvision, has many interesting features. the ones I like the most are:

1) logic analyzers: it shows up, in very graphics fashion, the values of the variables, or registers, and you can lay them out and see how they change vs. one another. Here, you can see that how PortD is incrementing it linearly.

2) peripheral: you can pull up any peripherals and see its pin / registers status. here, you can see how the pins for port A, C and D change.
 

Attachments

Thread Starter

millwood

Joined Dec 31, 1969
0
and if you zoom in in the logic analyzer, you can see how the variables / pins change from one clock to another.

features like those really helped debugging a program.

it just gave me one more reason to stay in the arm land.
 

Attachments

Thread Starter

millwood

Joined Dec 31, 1969
0
finally, I was able to get the adc working, both directly through the registers and then through Luminary's StellarisWare.

if you think PIC's adc is @#$ked up, take a look at the following code to see how a simple pulling of adc is done on the Luminary chip, :(.

Rich (BB code):
#include <lm3s811.h>

int ulSensor0Data, ulSensor1Data, ulSensor2Data;

void init_mcu(void) {
	
	SYSCTL_RCGC0_R |= (SYSCTL_RCGC0_ADC | 					//turn on adc
						SYSCTL_RCGC0_ADCSPD500K);			//and run it at 125ksps
	ADC_ACTSS_R &= ~(ADC_ACTSS_ASEN0 | ADC_ACTSS_ASEN1 |
					ADC_ACTSS_ASEN2 | ADC_ACTSS_ASEN3);		//programming adc: disable ADCACTSS during reprogramming
	ADC_SSPRI_R = (ADC_SSPRI_SS3_1ST | ADC_SSPRI_SS1_2ND |
					ADC_SSPRI_SS0_3RD | ADC_SSPRI_SS2_4TH);	//set up the priority: SS3 first, SS1 2nd, SS0 3rd and SS2 4th
	
	ADC_EMUX_R = (ADC_EMUX_EM1_PROCESSOR);					//set up the sequency trigger: ss1 by processor	only in this example
	
	//set-up sequence 1										//only sequence 1 is used. can have up to 4 steps
	ADC_SSMUX1_R = ((0 << ADC_SSMUX1_MUX0_S) |				//step 0 from adc0
					(1 << ADC_SSMUX1_MUX2_S) |				//step 1 from adc2
					(2 << ADC_SSMUX1_MUX1_S));				//step 2 from adc1
	ADC_SSCTL1_R = 											//step 0: single-ended, no temp sensor, no interrupt;
															//step 1: single-ended, no temp sensor, no interrupt;
					(ADC_SSCTL1_IE2 | ADC_SSCTL1_END2);		//step 2: single-ended, no temp sensor, interrupt enabled;
	//may configure addtional sequences from here.

	//ADC_SAC_R = ADC_SAC_AVG_2X;								//hardware averaging 2x. 0 - 64x oversampling available
	ADC_ACTSS_R |= ADC_ACTSS_ASEN1;							//enable sequence 1 - not initiated yet.

}

void delay(int dly) {
	for (; dly>0; dly--)
		;
}

int main(void) {
	init_mcu();

	while (1) {

		ADC_PSSI_R |= ADC_PSSI_SS1;								//initiate ss1 sequence - did this actually trigger an adc?
		while (!(ADC_RIS_R & ADC_RIS_INR1)) {}					//wait for ADC to complete;
		ulSensor0Data = ADC_SSFIFO1_R;							//retrive step 0 / adc0 result from sequence 1
		ulSensor1Data = ADC_SSFIFO1_R;							//retrive step 1 / adc2	result from sequence 1
		ulSensor2Data = ADC_SSFIFO1_R;							//retrive step 2 / adc1 result from sequence 1
		ADC_ISC_R |= ADC_ISC_IN1;								//clear the interrupt;
		//delay(500);
	}
}
I am posting the code here in case some people may find it helpful.

BTW, hardware oversamplingn still isn't working.
 
Top