CPAC+Øvelse+3

toc =Øvelse 1=

Opgave A
Vi leder efter USER_KEY og SYS_LED2 i [|DevKit8000_schematic]. Vi finder: Som leder os videre til: Ergo er USER_KEY mappet til GPIO 26. Nu skal vi blot finde SYS_LED2

USER_KEY = GPIO 26 SYS_LED2 = GPIO 186

Opgave B
Den følgende figure er taget fra manualen og illustrerer hvordan at de forskellige GPIO porte er mappet ind på de forskellige banke. Som det kan ses ovenfor er GPIO'erne mappet på følgende måde:
 * GPIO bank || Bit range ||
 * = 1||> 31-0||
 * = 2||> 63-34||
 * = 3||> 95-64||
 * = 4||> 126-96||
 * = 5||> 159-128||
 * = 6||> 191-160||

Vi så i Opgave A at USER_KEY ligger på GPIO bit 26 og at SYS_LED2 ligger på bit 186. Ved at sammenligene med vores GPIO Bank tabel kan vi konkludere følgende: USER_KEY ligger i GPIO bank 1. SYS_LED2 ligger i GPIO bank 6.

Opgave C
Ved at slå op i manuallen (spruf98c.pdf) under "1.6 General-Purpose Interface Registers" samt "1.6.1 General-Purpose Interface Register Mapping Summary" finder vi de adresser GPIO_OE for de forskellige banke starter på. GPIO_OE er det interface der styrer om et ben skal være indgang eller udgang.

USER_KEY
GPIO_OE for __BANK 1__ starter på **0x48310034**

Ved at anvende kommandoen kan vi få et billede af hvad der ligger på den adresse. //b = 8-bit, w=16-bit og l=32-bit//

- læser en long (32bit fra ) code OMAP3 DevKit8000 # md.l 0x48310034 48310034: fefffedf   .... code

__1__: den 26. bit som er GPIO_OE for USER_KEY som bestemmer om USER_KEY skal være indput eller output.
 * ~ BYTE||= 3||= 2||= 1||= 0||
 * ~ HEX||= FE||= FF||= FE||= DF||
 * ~ BIT||= 31-24||= 23-16||= 15-8||= 7-0||
 * ~ BIN||= 1111-1__1__10||= 1111-1111||= 1111-1110||= 1101-1111||

Dette system bruger HØJ til input og LAV til output. Så vores USER_KEY er sat som indgang, hvilket giver god mening så den lader vi være.

SYS_LED2
GPIO_OE (in/out) for __BANK 6__ starter på **0x49058034**

code OMAP3 DevKit8000 # md.l 0x49058034 49058034: fffffaf9   ....   code

__1__: den 186. bit som er GPIO_OE for SYS_LED2 som bestemmer om SYS_LED2 skal være indput eller output.
 * ~ BYTE||= 3||= 2||= 1||= 0||
 * ~ HEX||= FF||= FF||= FA||= F9||
 * ~ BIT||= 191-184||= 183-176||= 175-168||= 167-160||
 * ~ BIN||= 1111-1__1__11||= 1111-1111||= 1111-1010||= 1111-1001||

SYS_LED2 er sat til indgang hvilket ikke passer overens med at vi gerne vil have den til at tænde og slukke efter ønske. Så den skal sætte til udgang.

Ved at anvende kommandoen kan vi skrive til en adresse. //b = 8-bit, w=16-bit og l=32-bit//

Eftersom vi ikke gider skrive en 32bit streng så vælger vi det mindste vi kan skrive, som er 8bit. Men vi skal lige huske at flytte adressen lidt frem for at få den rigtige del af GPIO_OE interfacet, således:

0x49058034+3 = 0x49058037

code OMAP3 DevKit8000 # mw.b 0x49058037 0xfb OMAP3 DevKit8000 # md.l 0x49058034 49058034: fbfffaf9 code

SYS_LED2 er nu sat til udgang.

Opgave D
Vi skal verificere at GPIO_DATAIN værdien for USER_KEY skifter når der trykket på knappen.

Når USER_KEY ikke er trykket ned. code OMAP3 DevKit8000 # md.b 0x48310038 4 48310038: 3c 00 00 0e <... code

For forståelsens skyld er her en tabel: (husk endianess) __1__: den 26. bit som er GPIO_DATAIN for USER_KEY.
 * ~ BYTE||= 3||= 2||= 1||= 0||
 * ~ HEX||= 0E||= 00||= 00||= 3C||
 * ~ BIT||=31-24||= 23-16||= 15-8||= 7-0||
 * ~ BIN||= 1111-1__1__10||= 0000-0000||= 0000-0000||= 0011-1100||

Når USER_KEY er trykket ned. code OMAP3 DevKit8000 # md.b 0x48310038 4 48310038: 3c 00 00 0a <... code

For forståelsens skyld er her en tabel: (husk endianess) __0__: den 26. bit som er GPIO_DATAIN for USER_KEY.
 * ~ BYTE||= 3||= 2||= 1||= 0||
 * ~ HEX||= 0A||= 00||= 00||= 3C||
 * ~ BIT||= 31-24||= 23-16||= 15-8||= 7-0||
 * ~ BIN||= 1111-1__0__10||= 0000-0000||= 0000-0000||= 0011-1100||

Som det kan ses på skifter den fra 0xOE til 0xOA. Så det virker! Vi kan også konkludere at den er aktiv lav da bitten skiftede til lav da der blev trykket.

Opgave E
Vi skal tænde/slukke for SYS_LED2 ved at ændre på GPIO_DATAOUT (udgangen).

Vi har slået op i manuallen og fundet at GPIO_DATAOUT for BANK 6 begynder på **0x4905803C**. Fremgangsmåde er den samme som i opgave D.

0x4905803C+3 = 0x4905803F

code OMAP3 DevKit8000 # mw.b 0x4905803f 0x04 OMAP3 DevKit8000 # md.b 0x4905803f 1 4905803f: 04. code

SYS_LED2 er nu slukket.

code OMAP3 DevKit8000 # mw.b 0x4905803f 0x00 OMAP3 DevKit8000 # md.b 0x4905803f 1 4905803f: 00. code

SYS_LED2 er nu tændt.

=Øvelse 2=

Opgave A
Søg og erstat omap2420h4 med omap3devkit8000 i Makefile så der kommer til at stå: code ifeq ($(ARCH),arm) ifeq ($(BOARD),omap3devkit8000) LOAD_ADDR = 0x80300000 else LOAD_ADDR = 0xc100000 endif endif code

Opgave B
Skriv et C program som får SYS_LED2 til at lyse når USER_KEY bliver trykket ned. code format="c" int hello_world (int argc, char *argv[]) {	volatile unsigned long* userKeyOE_ptr = 0x48310034; volatile unsigned long* sysLED2OE_ptr = 0x49058034; volatile unsigned long* userKeyDIN_ptr = 0x48310038; volatile unsigned long* sysLED2DOUT_ptr = 0x4905803C; unsigned long userKeyOE = *userKeyOE_ptr; unsigned long sysLED2OE = *sysLED2OE_ptr; printf("USER_KEY GPIO_OE: %lX\n", userKeyOE); //printf("Unsigned long: %lu\n", sizeof(unsigned long)); // This doesn't work on the devkit... WTF?!

if (!(userKeyOE & 1<<26)) // Check if USER_KEY is set to input, if not set it		*userKeyOE_ptr = (unsigned long)((unsigned long)userKeyOE | 1<<26); // Set USER_KEY to input printf("SYS_LED2 GPIO_OE: %lX\n", sysLED2OE); if (userKeyOE & 1<<26) // Check if SYS_LED2 is input, if it is change it		*sysLED2OE_ptr = (unsigned long)((unsigned long)sysLED2OE ^ (1UL<<26)); // Set SYS_LED2 to output // UL is a suffix on a numeric constant to tell the compiler that the value's type should be an unsigned long

while (1) {		// Update variables unsigned long userKeyDIN = *userKeyDIN_ptr; unsigned long sysLED2DOUT = *sysLED2DOUT_ptr; //printf("User key: %lX\n", (*userKeyDIN_ptr)); if (!(userKeyDIN & 1UL<<26)) // Button is pressed (active low) *sysLED2DOUT_ptr = (unsigned long)((unsigned long)sysLED2DOUT & ~(1UL<<26)); // Turn on SYS_LED2 (active low) else *sysLED2DOUT_ptr = (unsigned long)((unsigned long)sysLED2DOUT | (1UL<<26)); // Turn off SYS_LED2 (active low) }

return (0); } code Det er værd at nævne at det er super vigtigt at caste til unsigned long selvom variablen allerede er af unsigned long typen, for hvis det ikke skrives på præcis denne måde dør programmet (of doom).

Noget andet mærkeligt er at sizeof(long) pitter max!

Opgave C
Kompilere programmet med kommandoen:

Opgave D
Forbinder til devkittet via programmet minicom hvorefter vi overfører programmet til RAM plads 0x80300000 med kommandoen:

Hvorefter programmet kan eksekveres med kommandoen: