Zajęcia 3
RCC_AHB1ENR EQU 0x40023830 ;adres rejestru APB1 clock enable
GPIOG_MODER EQU 0x40021800 ;itd.
GPIOG_OTYPER EQU 0x40021804
GPIOG_ODR EQU 0x40021814
THUMB
AREA vector_table, DATA, READONLY ;tablia wektorow przerwan - niepelna!
DCD 0x2000FFFF ;wartosc wskaznika stosu pod adresem 0x00000000
DCD reset_handler ;komorka 0x00000004 - adres procedury obslugi przerwania reset
ALIGN
AREA program_data, DATA, READWRITE ;dane inicjowane wartoscia - tablica 8 liczb 32bitowych
delay_tab DCD 0x0004, 0x0001, 0x0001, 0x0001, 0x0001
ALIGN
AREA program_code, CODE, READONLY ;kod programu
ENTRY ;punkt wejsciowy - adres 1 instrukcji (ldr)
reset_handler
LDR R3,= delay_tab
LDR R4,[R3], #4
MOVS R1, #0
tab_loop
LDR R0,[R3], #4
MOVS R2, #32
main_loop
EOR R1, R1, R0 ;R1=R1xR0
LSR R0, R0, #1
SUBS R2, R2, #1
BNE main_loop
SUBS R4, R4, #0
BNE tab_loop
AND R1, R1, #1
endless_loop
B endless_loop
END
Zajęcia 4
THUMB
AREA vector_table, DATA, READONLY ;tablia wektorow przerwan - niepelna!
DCD 0x2000FFFF ;wartosc wskaznika stosu pod adresem 0x00000000
DCD reset_handler ;komorka 0x00000004 - adres procedury obslugi przerwania reset
ALIGN
AREA program_data, DATA, READWRITE ;dane inicjowane wartoscia - tablica 8 liczb 32bitowych
delay_tab DCB 0x0004, 0x0002, 0x0001, 0x0005, 0x0001
ALIGN
AREA program_code, CODE, READONLY ;kod programu
ENTRY
reset_handler ;punkt wejsciowy - adres 1 instrukcji (ldr)
LDR R1,=delay_tab
LDRB R2,[R1],#1
MOV R3,#0
petla_loop
LDRB R0,[R1],#1
CMP R0,R3
IT HI
MOVHI R3,R0
SUBS R2,R2,#1
BNE petla_loop
endless_loop
B endless_loop
END
Zajęcia 5
RCC_AHB1ENR EQU 0x40023830 ;adres rejestru APB1 clock enable
GPIOG_MODER EQU 0x40021800 ;itd.
GPIOG_OTYPER EQU 0x40021804
GPIOG_ODR EQU 0x40021814
THUMB
AREA vector_table, DATA, READONLY ;tablia wektorow przerwan - niepelna!
DCD 0x2000FFFF ;wartosc wskaznika stosu pod adresem 0x00000000
DCD reset_handler ;komorka 0x00000004 - adres procedury obslugi przerwania reset
ALIGN
AREA program_data, DATA, READWRITE ;dane inicjowane wartoscia - tablica 8 liczb 32bitowych
delay_tab DCB 0x0002, 0x0001, 0x0005, 0x0001
ALIGN
AREA program_code, CODE, READONLY ;kod programu
ENTRY
reset_handler ;punkt wejsciowy - adres 1 instrukcji (ldr)
MOV R0,#0x0004
LDR R1,=delay_tab
BL maks ; skok do labelki maks
maks
PUSH {R4, R5} ; wrzucenie na stos zeby ich nie zgubic
MOV R4,#0x80000000
petla_loop
LDRB R5,[R1],#1 ;ladowanie pierwszego elementu
CMP R5,R4 ;porownanie
IT GT
MOVGT R4,R5
SUBS R0,R0,#1
BNE petla_loop
MOV R0, R4
POP {R4, R5} ;pobranie ze stosu
BX LR ;skok do LR (adresu do ktorego ma wrocic funkcja)
endless_loop
B endless_loop
nop
END
Zajęcia 6
asm_simple.s
RCC_AHB1ENR EQU 0x40023830 ;adres rejestru APB1 clock enable
GPIOG_MODER EQU 0x40021800 ;itd.
GPIOG_OTYPER EQU 0x40021804
GPIOG_ODR EQU 0x40021814
THUMB
IMPORT clock_config
AREA vector_table, DATA, READONLY ;tablia wektorow przerwan - niepelna!
DCD 0x2000FFFF ;wartosc wskaznika stosu pod adresem 0x00000000
DCD reset_handler ;komorka 0x00000004 - adres procedury obslugi przerwania reset
ALIGN
AREA program_data, DATA, READWRITE ;dane inicjowane wartoscia - tablica 8 liczb 32bitowych
delay_tab DCD 0xC000, 0x10000, 0x18000, 0x20000, 0x30000, 0x40000, 0x60000, 0x80000
ALIGN
AREA program_code, CODE, READONLY ;kod programu
ENTRY ;punkt wejsciowy - adres 1 instrukcji (ldr)
reset_handler
BL clock_config
LDR R0,=RCC_AHB1ENR ;wlacz zegar portu GPIOG
LDR R1,[R0]
ORR R1,R1,#(1<<6)
STR R1,[R0]
LDR R0,=GPIOG_MODER ;tryb pracy lini 13 i 14 portu G - wyjscie
LDR R1,[R0]
ORR R1,R1,#((1<<(2*13)) :OR: (1<<(2*14)))
STR R1,[R0],#0x14 ;R0=GPIOG_ODR
MOV R2,#((1<<13) :OR: (1<<14)) ;maska ledow - jedynki na 13 i 14 pozycji
MOV R1,#(1<<13) ;wartosc poczatkowa - zielony led
LDR R7,=delay_tab ;R7 - baza- adres tablicy
MOV R6,#0 ;w R6 wskaznik na pierwszy element
main_loop
LDR R4,[R7,R6, LSL #2] ;R4=delay_tab[baza+4*R6]
ADD R6,R6,#1
AND R6,R6,#7 ;przesun wskaznik (mod 8)
MOV R5,#5 ;5 iteracji z kazda wartoscia zwloki
inner_loop
EORS R1,R1,R2 ;zamien ledy
STR R1,[R0] ;wyslij do portu i/o
MOV R3,R4 ;wladuj liczbe iteracji
delay_loop ;zwloka regulowana wartoscia z tablicy
SUBS R3,R3,#1
BCS delay_loop
SUBS R5,R5,#1
BCS inner_loop
B main_loop
END
clock_config.s
RCC_CR EQU 0x40023800
RCC_PLLCFGR EQU 0x40023804
RCC_CFGR EQU 0x40023808
RCC_AHB1ENR EQU 0x40023830
RCC_AHB2ENR EQU 0x40023834
RCC_APB1ENR EQU 0x40023840
RCC_PLLCFGR_CLR_MASK EQU 0xF0BC0000
THUMB
EXPORT clock_config
AREA config_code, CODE, READONLY
ALIGN
clock_config
PUSH {R4-R6}
;po resecie - wlaczony wewnetrzny oscylator (HSI) - 16MHz
LDR R4,=RCC_CR ;RCC_CR - CLOCK CONTROL REGISTER
LDR R5,[R4]
BIC R5,R5,#1<<0 ;HSI off
ORR R5,R5,#1<<16 ;HSE on
STR R5,[R4]
hse_stabilization
LDR R5,[R4]
ANDS R5,R5,#1<<17 ;czekaj na ustabilizowanie HSE
BEQ hse_stabilization
;konfiguracja PLL: fout = (fin/M)*(N/P)
;fin=16MHz dla HSI, 8MHz dla HSE
;wartosci po resecie:
;M=16 (bity 5-0)
;N=192 (bity 14-6)
;P=2 (bity 16-17)
;Q=4 (bity 24-27)
LDR R6,=RCC_PLLCFGR_CLR_MASK
LDR R5,[R4,#4] ;RCC_PLLCFGR - PLL CONFIGURATION REGISTER
ANDS R5,R5,R6 ;maska - zostaw tylko bity 'reserved'
ORR R5,R5,#30 ;PLLM: 2 - 63
ORR R5,R5,#432<<6 ;PLLN: 100 - 432
ORR R5,R5,#1<<16 ;PLLP 0=/2 1=/4 2=/6 3=/8
ORR R5,R5,#1<<22 ;wejscie PLL 22 bit HSE=1 HSI=0
ORR R5,R5,#4<<24 ;PLLQ
STR R5,[R4,#4]
LDR R5,[R4] ;RCC_CR
ORR R5,R5,#1<<24 ;wlacz PLL
STR R5,[R4]
pll_stabilization
LDR R5,[R4]
ANDS R5,R5,#1<<25 ;czekaj na zatrzasniecie PLL
BEQ pll_stabilization
LDR R5,[R4,#8] ;RCC_CFGR
ORR R5,R5,#02 ;System Clock source: 0-HSI 1-HSE 2-PLL
ORR R5,R5,#0<<4 ;AHB PRESCALER 0 - /1, 8 - /2, 9 - /4 ,10 - /8 ... 15 - /512
ORR R5,R5,#0<<10 ;APB1 PRESCALER LOW SPEED 0 - /1, 4 - /2, 5- /4, 6 - /8, 7 - /16
ORR R5,R5,#0<<13 ;APB2 PRESCALER HI SPEED 0 - /1, 4 - /2, 5- /4, 6 - /8, 7 - /16
STR R5,[R4,#8]
sys_clk_check
LDR R5,[R4,#8]
ANDS R5,R5,#02<<2 ;zaczekaj az bedzie gotowy, wartosci jak wyzej
BEQ sys_clk_check
POP {R4-R6}
BX LR
ALIGN
END
Zajęcia 8
Zajęcia n-1
#include <stdio.h>
//#include <stdlib.h>
#include "stm32f4xx.h"
#include "GLCD.h"
#define __FI 1
#if (__FI == 1)
#define __FONT_WIDTH 16
#define __FONT_HEIGHT 24
#else
#define __FONT_WIDTH 6
#define __FONT_HEIGHT 8
#endif
uint32_t rand_lfsr32(void);
uint32_t rand_hw(void);
void clock_config(void);
uint32_t i,x;
char s[20];
int main()
{
clock_config();
RCC->AHB2ENR |= 1<<6; //wlacz zegar DRNG
RNG->CR |= 1<<2; //wlacz DRNG
GLCD_Initialize();
GLCD_SetBackColor(Black);
GLCD_SetTextColor(White);
GLCD_Clear(Black);
x=0xabcdef12;
for (i=0;i<10;i++) {
x=rand_lfsr32();
//x=rand_hw();
sprintf(s,"%x", x);
GLCD_DisplayString(i, 0, __FI,s);
}
while (1);
}
void clock_config(void)
{
//wspolpraca z pamiecia FLASH
FLASH->ACR |= 5; //5 WaitStatow dla 180MHz
FLASH->ACR |= ((1<<8) | (1<<9) | (1<<10)); //wlacz prefetch oraz I&D cache
//wybor oscylatora
RCC->CR &= ~(1<<0); //HSI OFF
RCC->CR |= (1<<16); //HSE ON
while (!(RCC->CR & 1<<17)); //czekaj az sie HSE ustabilizuje
//konfiguracja PLL: fout = (fin/M)*(N/P)
RCC->PLLCFGR &= 0xF0BC0000; //zostaw tylko bity reserved, reszta 0
RCC->PLLCFGR |= 4;//8; //M (2-63)
RCC->PLLCFGR |= 360<<6;//192<<6; //N (192-432)
RCC->PLLCFGR |= 1<<16; //P 0=/2 1=/4 2=/6 3=/8
RCC->PLLCFGR |= 15<<25; //2<<24; //Q (2-15) USB SDIO random number generator
RCC->PLLCFGR |= 1<<22; //wejscie PLL 1=HSE, 0=HSI
RCC->CR |= 1<<24; // 1 - PLL ON, 0 - PLL OFF
while (!(RCC->CR & 1<<25)); //czekaj az PLL sie zatrzasnie
RCC->CFGR |= 2; //0 - HSI, 1 - HSE, 2 - PLL jako SYSCLK
RCC->CFGR |= 0<<4; //AHB PRESCALER 8 - /2, 9 - /4 ,10 - /8 ...
RCC->CFGR |= 7<<10; //APB1 PRESCALER LOW SPEED 4 - /2, 5- /4, 6 - /8, 7 - /16
RCC->CFGR |= 0<<13; //APB2 PRESCALER HI SPEED
}
//uzupelnic LFSR-32bit
//wielomian: x^32+x^30+x^26+x^25
__asm uint32_t rand_lfsr32(void)
{
LDR R3,=__cpp(&x)
LDR R0,[R3]
ROR R0,R0,#1
ASR R1,R0,#31
AND R1,R1, #0x23000000
EOR R0,R0,R1
bx lr
}
//uzupelnic - generator sprzetowy
__asm uint32_t rand_hw(void)
{
LDR R1,=0x50060800
rand_loop
LDR R0,[R1,#4]
ANDS R0, #1
BEQ rand_loop
LDR R0,[R1,#8]
bx lr
}