forked from kernelcrash/electron-rom-emulator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
executable file
·176 lines (145 loc) · 5.53 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include "main.h"
#include "stm32f4_discovery.h"
GPIO_InitTypeDef GPIO_InitStructure;
enum sysclk_freq {
SYSCLK_42_MHZ=0,
SYSCLK_84_MHZ,
SYSCLK_168_MHZ,
SYSCLK_200_MHZ,
SYSCLK_240_MHZ,
};
void rcc_set_frequency(enum sysclk_freq freq)
{
int freqs[] = {42, 84, 168, 200, 240};
/* USB freqs: 42MHz, 42Mhz, 48MHz, 50MHz, 48MHz */
int pll_div[] = {2, 4, 7, 10, 10};
/* PLL_VCO = (HSE_VALUE / PLL_M) * PLL_N */
/* SYSCLK = PLL_VCO / PLL_P */
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
uint32_t PLL_P = 2;
uint32_t PLL_N = freqs[freq] * 2;
uint32_t PLL_M = (HSE_VALUE/1000000);
uint32_t PLL_Q = pll_div[freq];
RCC_DeInit();
/* Enable HSE osscilator */
RCC_HSEConfig(RCC_HSE_ON);
if (RCC_WaitForHSEStartUp() == ERROR) {
return;
}
/* Configure PLL clock M, N, P, and Q dividers */
RCC_PLLConfig(RCC_PLLSource_HSE, PLL_M, PLL_N, PLL_P, PLL_Q);
/* Enable PLL clock */
RCC_PLLCmd(ENABLE);
/* Wait until PLL clock is stable */
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
/* Set PLL_CLK as system clock source SYSCLK */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Set AHB clock divider */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* Set APBx clock dividers */
switch (freq) {
/* Max freq APB1: 42MHz APB2: 84MHz */
case SYSCLK_42_MHZ:
RCC_PCLK1Config(RCC_HCLK_Div1); /* 42MHz */
RCC_PCLK2Config(RCC_HCLK_Div1); /* 42MHz */
break;
case SYSCLK_84_MHZ:
RCC_PCLK1Config(RCC_HCLK_Div2); /* 42MHz */
RCC_PCLK2Config(RCC_HCLK_Div1); /* 84MHz */
break;
case SYSCLK_168_MHZ:
RCC_PCLK1Config(RCC_HCLK_Div4); /* 42MHz */
RCC_PCLK2Config(RCC_HCLK_Div2); /* 84MHz */
break;
case SYSCLK_200_MHZ:
RCC_PCLK1Config(RCC_HCLK_Div4); /* 50MHz */
RCC_PCLK2Config(RCC_HCLK_Div2); /* 100MHz */
break;
case SYSCLK_240_MHZ:
RCC_PCLK1Config(RCC_HCLK_Div4); /* 60MHz */
RCC_PCLK2Config(RCC_HCLK_Div2); /* 120MHz */
break;
}
/* Update SystemCoreClock variable */
SystemCoreClockUpdate();
}
/* Input Signals GPIO pins on THETA0 -> PC0, _r/w -> PC1 */
void config_gpio_portc(void) {
/* GPIOC Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* Configure GPIO Settings */
// Using PC1 for r/w instead of PC2 now
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
//GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
//GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// PC10 out, PC11 out, PC12 out
GPIOC->MODER = 0x01500000;
GPIOC->ODR = 0x0000;
}
/* Input/Output data GPIO pins on PD{8..15}. Also PD2 is used fo MOSI on the STM32F407VET6 board I have */
void config_gpio_data(void) {
/* GPIOD Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Configure GPIO Settings */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 |
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |
GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
//GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOD, &GPIO_InitStructure);
// Make sure PD2 is output
GPIOD->MODER = 0x00000010;
}
/* Input Address GPIO pins on PE{0..15} */
void config_gpio_addr(void) {
/* GPIOE Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
/* Configure GPIO Settings */
GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 |
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |
GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
/* Debug GPIO pins on PA0 */
void config_gpio_dbg(void) {
/* GPIOA Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* Configure GPIO Settings */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
int main(void) {
rcc_set_frequency(SYSCLK_200_MHZ);
/* PD{8..15} and PD2 for SD card MOSI*/
config_gpio_data();
/* PE{0..15} */
config_gpio_addr();
/* PC{0..2} and PC8 and PC{10..12} */
config_gpio_portc();
/* PA0 */
config_gpio_dbg();
// switch on compensation cell
RCC->APB2ENR |= 0 | RCC_APB2ENR_SYSCFGEN ;
SYSCFG->CMPCR |= SYSCFG_CMPCR_CMP_PD; // enable compensation cell
while ((SYSCFG->CMPCR & SYSCFG_CMPCR_READY) == 0); // wait until ready
// call never ending polling loop
asm_poller();
}