Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 736 lines (592 sloc) 20.907 kb
7cbd412 @davidcranor first commit
authored
1 /*
2 * thinnerclient.c
3 *
4 * NTSC display, UART reading, and PS/2 keyboard driver
5 * for STM32F series microcontrollers
6 *
7 * David Cranor and Max Lobovsky (PS/2 stuff adapted from work by Matt Sarnoff)
8 * 8/30/10
9 *
10 * (c) Massachusetts Institute of Technology 2010
11 * Permission granted for experimental and personal use;
12 * license for commercial sale available from MIT.
13 */
14
15 #include "stm32f10x.h"
16 #include "stm32f10x_exti.h"
17
18 #include "thinnerclient.h"
19
20 #include "video.h"
21 #include "keycodes.h"
22 #include "termconfig.h"
23 #include "terminal.h"
24
25 #include <stdint.h>
26 #include "defs.h"
27
28
29 //Peripheral configuration structures
30 GPIO_InitTypeDef GPIO_InitStructure;
31 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
32 TIM_OCInitTypeDef TIM_OCInitStructure;
33 NVIC_InitTypeDef NVIC_InitStructure;
34 SPI_InitTypeDef SPI_InitStructure;
35 DMA_InitTypeDef DMA_InitStructure;
36 USART_InitTypeDef USART_InitStructure;
37 EXTI_InitTypeDef EXTI_InitStructure;
38
39 //Timer stuf to generate sync and video display. Need to tweak these if doing a PAL port.
40 #define TIMER_PERIOD 5083
41 #define INTERRUPT_DELAY 700
42 uint16_t CCR2_Val = 380;
43 uint16_t PrescalerValue = 0;
44
45 volatile uint16_t lineCount = 0;
46
47 //PLL hackery
48 void overclockSystemInit(void);
49
50 // Peripheral configuration functions
51 void GPIO_Config(void);
52 void RCC_Config(void);
53 void TIM_Config(void);
54 void NVIC_Config(void);
55 void SPI_Config(void);
56 void DMA_Config(void);
57 void USART_Config(void);
58 void EXTI_Config(void);
59
60 //Interrupt handlers
61 void TIM2_IRQHandler(void); //Sync interrupt
62 void USART1_IRQHandler(void); //USART received stuff interrupt
7e2a21b @davidcranor updated README, fixed keyboard code, removed last remnants of platfor…
authored
63 void EXTI9_5_IRQHandler(void); //Keyboard interrupt handler
7cbd412 @davidcranor first commit
authored
64
65 //Decode a keypress
66 void decode(uint8_t code);
67
68 //The framebuffer itself
69 uint16_t frameBuffer[BUFFER_VERT_SIZE][BUFFER_LINE_LENGTH];
70
71 uint32_t charCounter = 0;
72
73 #define ESC K_ESC
74 #define CLK K_CAPSLK
75 #define NLK K_NUMLK
76 #define SLK K_SCRLK
77 #define F1 K_F1
78 #define F2 K_F2
79 #define F3 K_F3
80 #define F4 K_F4
81 #define F5 K_F5
82 #define F6 K_F6
83 #define F7 K_F7
84 #define F8 K_F8
85 #define F9 K_F9
86 #define F10 K_F10
87 #define F11 K_F11
88 #define F12 K_F12
89 #define INS K_INS
90 #define DEL K_DEL
91 #define HOM K_HOME
92 #define END K_END
93 #define PGU K_PGUP
94 #define PGD K_PGDN
95 #define ARL K_LEFT
96 #define ARR K_RIGHT
97 #define ARU K_UP
98 #define ARD K_DOWN
99 #define PRS K_PRTSC
100 #define BRK K_BREAK
101
102
103 //Keyboard lookup tables
104 __attribute__((section("FLASH"))) const char codetable[] = {
105 // 1 2 3 4 5 6 7 8 9 A B C D E F
106 0, F9, 0, F5, F3, F1, F2, F12, 0, F10, F8, F6, F4, '\t','`', 0,
107 0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0,
108 0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0,
109 0, 'n', 'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j', 'u', '7', '8', 0,
110 0, ',', 'k', 'i', 'o', '0', '9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0,
111 0, 0, '\'',0, '[', '=', 0, 0, CLK, 0, '\n',']', 0, '\\',0, 0,
112 0, 0, 0, 0, 0, 0, '\b',0, 0, '1', 0, '4', '7', 0, 0, 0,
113 '0', '.', '2', '5', '6', '8', ESC, NLK, F11, '+', '3', '-', '*', '9', SLK, 0,
114 0, 0, 0, F7
115 };
116
117 __attribute__((section("FLASH"))) const char codetable_shifted[] = {
118 // 1 2 3 4 5 6 7 8 9 A B C D E F
119 0, F9, 0, F5, F3, F1, F2, F12, 0, F10, F8, F6, F4, '\t','~', 0,
120 0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0,
121 0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
122 0, 'N', 'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J', 'U', '&', '*', 0,
123 0, '<', 'K', 'I', 'O', ')', '(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0,
124 0, 0, '"', 0, '{', '+', 0, 0, CLK, 0, '\n','}', 0, '|', 0, 0,
125 0, 0, 0, 0, 0, 0, '\b',0, 0, '1', 0, '4', '7', 0, 0, 0,
126 '0', '.', '2', '5', '6', '8', ESC, NLK, F11, '+', '3', '-', '*', '9', SLK, 0,
127 0, 0, 0, F7
128 };
129
130 //codes that follow E0 or E1
131
132 __attribute__((section("FLASH"))) const char codetable_extended[] = {
133 // 1 2 3 4 5 6 7 8 9 A B C D E F
134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, PRS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
137 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
138 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/', 0, 0, 0, 0, 0,
139 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\n',0, 0, 0, 0, 0,
140 0, 0, 0, 0, 0, 0, 0, 0, 0, END, 0, ARL, HOM, 0, 0, 0,
141 INS, DEL, ARD, '5', ARR, ARU, 0, BRK, 0, 0, PGD, 0, PRS, PGU, 0, 0,
142 0, 0, 0, 0
143 };
144
145
146 /* keyboard init */
147 static int8_t keyup = 0;
148 static int8_t extended = 0;
149 static int8_t bitcount = 11;
150 static uint8_t scancode = 0;
151 static int8_t mods = 0;
152
153 /* circular buffer for keys */
154 #define MAX_KEY_BUF 32
155 volatile uint8_t charbufsize = 0;
156 volatile uint8_t charbuf[MAX_KEY_BUF];
157 volatile uint8_t charbufhead = 0;
158 volatile uint8_t charbuftail = 0;
159
160 /* circular UART buffer */
161 #define MAX_BUF 254
162 volatile uint8_t bufsize;
163 volatile uint8_t buf[MAX_BUF];
164 volatile uint8_t bufhead;
165 volatile uint8_t buftail;
166
167 void thinnerClientSetup(void)
168 {
169
170 // Setup (overclocked to 80MHz) STM32 system (clock, PLL and Flash configuration) This is totally unnecessary.
171 // Needed a clock speed that is agreeable to being divided by the spi port clock divider to give the resolution desired.
172 // There is probably a lower system sepeed which will also work, but wanted to make sure we had enough cycles to get the job done....
173 overclockSystemInit();
174
175 //Set up the system clocks
176 RCC_Config();
177
178 // Setup the GPIOs
179 GPIO_Config();
180
181 //Setup the SPI port (video is output by its shift register).
182 SPI_Config();
183
184 //Setup the DMA to keep the spi port fed
185 DMA_Config();
186
187 //Setup the timers for generating sync and drawing to the screen.
188 TIM_Config();
189
190 //Set up the USART for sending and receiving data.
191 USART_Config();
192
193 //Setup the necessary interrupts. I *think* that messing wiht priority levels will fix the screen distortion when receiving data from USART or keyboard.
194 NVIC_Config();
195
196 //Hook the external interrupts to the right pins.
197 EXTI_Config();
198 }
199
200
201 void RCC_Config(void)
202 {
203
204 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM4, ENABLE);
205 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
7e2a21b @davidcranor updated README, fixed keyboard code, removed last remnants of platfor…
authored
206 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
7cbd412 @davidcranor first commit
authored
207 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
208 }
209
210 void GPIO_Config(void)
211 {
212 /* GPIOA Configuration:TIM2 Channel 2 as alternate function push-pull */
213 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_7 | GPIO_Pin_5 ;
214 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
215 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
216
217 GPIO_Init(GPIOA, &GPIO_InitStructure);
218
219 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_0; //Debugging Pins
220 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
221 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
222
223 GPIO_Init(GPIOA, &GPIO_InitStructure);
224
7e2a21b @davidcranor updated README, fixed keyboard code, removed last remnants of platfor…
authored
225 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11; //setting up for keyboard pin change interrupts.
7cbd412 @davidcranor first commit
authored
226 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
227 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
228
7e2a21b @davidcranor updated README, fixed keyboard code, removed last remnants of platfor…
authored
229 GPIO_Init(GPIOA, &GPIO_InitStructure);
230 GPIO_EXTILineConfig( GPIO_PortSourceGPIOA, GPIO_PinSource8 ); //connect exti
7cbd412 @davidcranor first commit
authored
231
232
233 /* Configure USART1 Rx as input floating */
234 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
235 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
236 GPIO_Init(GPIOA, &GPIO_InitStructure);
237
238
239 /* Configure USART1 Tx as alternate function push-pull */
240 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
241 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
242 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
243 GPIO_Init(GPIOA, &GPIO_InitStructure);
244 }
245
246 void TIM_Config(void)
247 {
248 /* Compute the prescaler value */
249 PrescalerValue = (uint16_t) 0;
250
251 /* Time base configuration */
252 TIM_TimeBaseStructure.TIM_Period = TIMER_PERIOD; //72mhz/15.73426 khz line rate
253 TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
254 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
255 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
256
257 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
258
259 /* PWM1 Mode configuration: Channel 2, because there is a broken wire stuck in the header for channel 1 on my protoboard.*/
260 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
261 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
262 TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
263 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
264
265 TIM_OC2Init(TIM2, &TIM_OCInitStructure);
266
267 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
268
269 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
270 TIM_OCInitStructure.TIM_Pulse = INTERRUPT_DELAY;
271
272 TIM_OC1Init(TIM2, &TIM_OCInitStructure);
273
274 TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
275
276 /* Enable TIM2 Count Compare interrupt */
277 TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
278
279 /* TIM2 enable counter */
280 TIM_Cmd(TIM2, ENABLE);
281 }
282
283 void NVIC_Config(void)
284 {
7e2a21b @davidcranor updated README, fixed keyboard code, removed last remnants of platfor…
authored
285 // Enable the EXTI9_5 Interrupt for keyboard transmissions
286 NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
7cbd412 @davidcranor first commit
authored
287 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
288 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
289
290 NVIC_Init(&NVIC_InitStructure);
291
292 //Enable timer2 interrupt
293 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
294 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
295 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
296
297 NVIC_Init(&NVIC_InitStructure);
298
299 //Enable USART interrupt
300 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
301 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
302 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
303
304 NVIC_Init(&NVIC_InitStructure);
305 }
306
307 void SPI_Config(void)
308 {
309 //Set up SPI port. This acts as a pixel buffer.
310 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
311 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
312 SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
313 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
314 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
315 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
316 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
317 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
318
319 SPI_Init(SPI1, &SPI_InitStructure);
320
321 SPI_Cmd(SPI1, ENABLE);
322 }
323
324 void DMA_Config(void)
325 {
326
327 //Set up the DMA to keep the SPI port fed from the framebuffer.
328 DMA_DeInit(DMA1_Channel3);
329 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x4001300C;
330 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)frameBuffer[1];
331 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
332 DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
333
334 DMA_InitStructure.DMA_BufferSize = BUFFER_LINE_LENGTH;
335 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
336 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
337 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
338 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
339 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
340 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
341
342 DMA_Init(DMA1_Channel3, &DMA_InitStructure);
343 }
344
345 void USART_Config(void)
346 {
347
348 //Set up the USART.
349 USART_InitStructure.USART_BaudRate = 57600; //57600; //9600; //921600;
350 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
351 USART_InitStructure.USART_StopBits = USART_StopBits_1;
352 USART_InitStructure.USART_Parity = USART_Parity_No;
353 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
354 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
355
356 USART_Init(USART1, &USART_InitStructure);
357
358 //Enable receive interrupts
359 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
360
361 //enable the usart
362 USART_Cmd(USART1, ENABLE);
363 }
364
365
366 void EXTI_Config(void)
367 {
7e2a21b @davidcranor updated README, fixed keyboard code, removed last remnants of platfor…
authored
368 // Enable an interrupt on EXTI line 8 rising
369 EXTI_InitStructure.EXTI_Line = EXTI_Line8;
7cbd412 @davidcranor first commit
authored
370 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
371 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
372 EXTI_InitStructure.EXTI_LineCmd = ENABLE;
373
374 EXTI_Init(&EXTI_InitStructure);
375 }
376
7e2a21b @davidcranor updated README, fixed keyboard code, removed last remnants of platfor…
authored
377 void EXTI9_5_IRQHandler(void)
7cbd412 @davidcranor first commit
authored
378 {
379 //figure out what the keyboard is sending us
7e2a21b @davidcranor updated README, fixed keyboard code, removed last remnants of platfor…
authored
380 EXTI_ClearFlag(EXTI_Line8);
7cbd412 @davidcranor first commit
authored
381 --bitcount;
382 if (bitcount >= 2 && bitcount <= 9)
383 {
384 scancode >>= 1;
7e2a21b @davidcranor updated README, fixed keyboard code, removed last remnants of platfor…
authored
385 if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11))
7cbd412 @davidcranor first commit
authored
386 scancode |= 0x80;
387 }
388 else if (bitcount == 0)
389 {
390 //puthex(scancode);
391 decode(scancode);
392 scancode = 0;
393 bitcount = 11;
394 }
395 }
396
397 void USART1_IRQHandler(void)
398 {
399 //receive data from the serial port
400 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
401 {
402 GPIO_ResetBits(GPIOA, GPIO_Pin_0);
403 buf_enqueue(USART_ReceiveData(USART1));
404 USART_ClearFlag(USART1, USART_FLAG_RXNE);
405 }
406 }
407
408 void TIM2_IRQHandler(void)
409 {
410
411 //here's where the ntsc video drawing magic happens!
412 TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
413 lineCount++;
414
415 //DMA the next line of data to the screen!
416 if(lineCount < BUFFER_VERT_SIZE)
417 {
418 DMA_DeInit(DMA1_Channel3);
419 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)frameBuffer[lineCount];
420 DMA_Init(DMA1_Channel3, &DMA_InitStructure);
421 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
422 DMA_Cmd(DMA1_Channel3, ENABLE);
423 }
424
425 //vertical sync
426 if(lineCount == 242)
427 {
428 TIM_SetCompare2(TIM2, (4575-342));
429 }
430
431 //transition back to normal sync
432 if(lineCount == 261)
433 {
434 TIM_SetCompare2(TIM2, 511);
435 }
436
437 //go back to normal
438 if(lineCount == 262)
439 {
440 TIM_SetCompare2(TIM2, 342);
441 lineCount = 0;
442 }
443 }
444
445
446 void waitForVsync(void)
447 {
448 while(lineCount < 242);
449 }
450
451 void Delay(volatile unsigned long delay)
452 {
453 for(; delay; --delay );
454 }
455
456 //fill the framebuffer with junk, used for debugging
457 void fillFrameBuffer(void)
458 {
459 uint16_t i;
460 uint16_t j;
461 for(i = 0; i<(BUFFER_VERT_SIZE); i++)
462 {
463 for(j = 0; j<(BUFFER_LINE_LENGTH); j++)
464 {
465 if(j < LEFT_MARGIN)
466 {
467 frameBuffer[i][j] = 0;
468 } else if (j > 32){
469 frameBuffer[i][j] = 0;
470 } else {
471 frameBuffer[i][j] = i*j;
472 }
473 }
474 }
475 }
476
477 //Decode PS/2 keycodes
478 void decode(uint8_t code)
479 {
480 if (code == 0xF0)
481 keyup = 1;
482 else if (code == 0xE0 || code == 0xE1)
483 extended = 1;
484 else
485 {
486 if (keyup) // handling a key release; don't do anything
487 {
488 if (code == 0x12) // left shift
489 mods &= ~_BV(0);
490 else if (code == 0x59) // right shift
491 mods &= ~_BV(1);
492 else if (code == 0x14) // left/right ctrl
493 mods &= (extended) ? ~_BV(3) : ~_BV(2);
494 }
495 else // handling a key press; store character
496 {
497 if (code == 0x12) // left shift
498 mods |= _BV(0);
499 else if (code == 0x59) // right shift
500 mods |= _BV(1);
501 else if (code == 0x14) // left/right ctrl
502 mods |= (extended) ? _BV(3) : _BV(2);
503 else if (code <= 0x83)
504 {
505 uint8_t chr;
506 if (extended)
507 chr = codetable_extended[code];
508 else if (mods & 0b1100) // ctrl
509 chr = codetable[code] & 31;
510 else if (mods & 0b0011) // shift
511 chr = codetable_shifted[code];
512 else
513 chr = codetable[code];
514
515 if (!chr) chr = '?';
516
517 // add to buffer
518 if (charbufsize < MAX_KEY_BUF)
519 {
520 charbuf[charbuftail] = chr;
521 if (++charbuftail >= MAX_KEY_BUF) charbuftail = 0;
522 charbufsize++;
523 }
524 }
525 }
526 extended = 0;
527 keyup = 0;
528 }
529 }
530
531 /*********Key and serial buffer stuff. Needs to be updated to support atomic writing (if possible without messing up screen drawing, the sizes get mismatched easily******/
532 uint8_t buffer_get_key()
533 {
534 if (charbufsize == 0)
535 return 0;
536
537 uint8_t newchar = charbuf[charbufhead];
538 if (++charbufhead >= MAX_KEY_BUF) charbufhead = 0;
539 charbufsize--;
540
541 return newchar;
542 }
543
544 uint8_t key_buf_size()
545 {
546 uint8_t sz;
547 sz = charbufsize;
548 return sz;
549 }
550
551
552 void buf_clear()
553 {
554 bufsize = bufhead = buftail = 0;
555 }
556
557 void buf_enqueue(uint8_t c)
558 {
559 if (1) //bufsize < MAX_BUF)
560 {
561 buf[buftail] = c;
562 if (++buftail >= MAX_BUF) buftail = 0;
563 bufsize++;
564 }
565 }
566
567 uint8_t buf_dequeue()
568 {
569 uint8_t ret = 0;
570 if (1) //bufsize > 0)
571 {
572 uint8_t c = buf[bufhead];
573 if (++bufhead >= MAX_BUF) bufhead = 0;
574 bufsize--;
575 ret = c;
576 }
577 return ret;
578 }
579
580 uint8_t buf_size()
581 {
582 uint8_t sz;
583 sz = bufsize;
584 return sz;
585 }
586
587
588 /*************End of key and serial buffer stuff********************/
589
590
591
592
593 //hack hack hack hack copypaste hack hack hack yuck
594 void overclockSystemInit(void)
595 {
596 /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
597 /* Set HSION bit */
598 RCC->CR |= (uint32_t)0x00000001;
599
600 /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
601 #ifndef STM32F10X_CL
602 RCC->CFGR &= (uint32_t)0xF8FF0000;
603 #else
604 RCC->CFGR &= (uint32_t)0xF0FF0000;
605 #endif /* STM32F10X_CL */
606
607 /* Reset HSEON, CSSON and PLLON bits */
608 RCC->CR &= (uint32_t)0xFEF6FFFF;
609
610 /* Reset HSEBYP bit */
611 RCC->CR &= (uint32_t)0xFFFBFFFF;
612
613 /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
614 RCC->CFGR &= (uint32_t)0xFF80FFFF;
615
616 #ifndef STM32F10X_CL
617 /* Disable all interrupts and clear pending bits */
618 RCC->CIR = 0x009F0000;
619 #else
620 /* Reset PLL2ON and PLL3ON bits */
621 RCC->CR &= (uint32_t)0xEBFFFFFF;
622
623 /* Disable all interrupts and clear pending bits */
624 RCC->CIR = 0x00FF0000;
625
626 /* Reset CFGR2 register */
627 RCC->CFGR2 = 0x00000000;
628 #endif /* STM32F10X_CL */
629
630 /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
631 /* Configure the Flash Latency cycles and enable prefetch buffer */
632 __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
633
634 /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
635 /* Enable HSE */
636 RCC->CR |= ((uint32_t)RCC_CR_HSEON);
637
638 /* Wait till HSE is ready and if Time out is reached exit */
639 do
640 {
641 HSEStatus = RCC->CR & RCC_CR_HSERDY;
642 StartUpCounter++;
643 } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));
644
645 if ((RCC->CR & RCC_CR_HSERDY) != RESET)
646 {
647 HSEStatus = (uint32_t)0x01;
648 }
649 else
650 {
651 HSEStatus = (uint32_t)0x00;
652 }
653
654 if (HSEStatus == (uint32_t)0x01)
655 {
656 /* Enable Prefetch Buffer */
657 FLASH->ACR |= FLASH_ACR_PRFTBE;
658
659 /* Flash 2 wait state */
660 FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
661 FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
662
663
664 /* HCLK = SYSCLK */
665 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
666
667 /* PCLK2 = HCLK */
668 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
669
670 /* PCLK1 = HCLK */
671 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
672
673 #ifdef STM32F10X_CL
674 /* Configure PLLs ------------------------------------------------------*/
675 /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
676 /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
677
678 RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
679 RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
680 RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
681 RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
682
683 /* Enable PLL2 */
684 RCC->CR |= RCC_CR_PLL2ON;
685 /* Wait till PLL2 is ready */
686 while((RCC->CR & RCC_CR_PLL2RDY) == 0)
687 {
688 }
689
690
691 /* PLL configuration: PLLCLK = PREDIV1 * 10 = 80 MHz */
692 RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
693 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
694 RCC_CFGR_PLLMULL10);
695 #else
696 /* PLL configuration: PLLCLK = HSE * 10 = 80 MHz */
697 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
698 RCC_CFGR_PLLMULL));
699 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL10);
700 #endif /* STM32F10X_CL */
701
702 /* Enable PLL */
703 RCC->CR |= RCC_CR_PLLON;
704
705 /* Wait till PLL is ready */
706 while((RCC->CR & RCC_CR_PLLRDY) == 0)
707 {
708 }
709
710 /* Select PLL as system clock source */
711 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
712 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
713
714 /* Wait till PLL is used as system clock source */
715 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
716 {
717 }
718 }
719 else
720 { /* If HSE fails to start-up, the application will have wrong clock
721 configuration. User can add here some code to deal with this error */
722
723 /* Go to infinite loop */
724 while (1)
725 {
726 }
727 }
728 }
729
730
731
732
733
734
735
Something went wrong with that request. Please try again.