##// END OF EJS Templates
sync
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL -
r45:e203e69902ca dev_alexis
parent child
Show More
@@ -1,140 +1,140
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the libuc, microcontroler library
3 3 -- Copyright (C) 2011, Alexis Jeandet
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------
19 19 -- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@gmail.com
21 21 -------------------------------------------------------------------------------*/
22 22 #include "bsp.h"
23 23 #include <streamdevices.h>
24 24 #include <malloc.h>
25 25 #include <gpio.h>
26 26 #include <uart.h>
27 27 #include <stdio.h>
28 28 #include <i2c.h>
29 29
30 30 uint32_t OSC0 =8000000;
31 31 uint32_t INTOSC =16000000;
32 32 uint32_t RTCOSC =32768;
33 33 uint32_t currentCpuFreq=0;
34 34 extern streamdevice* __opnfiles__[__MAX_OPENED_FILES__];
35 35
36 36 float VREF0 =(float)3.3;
37 37
38 38 int bsp_init()
39 39 {
40 40 int i=0;
41 41 for(i=0;i<32;i++)
42 42 {
43 43 __opnfiles__[i] = NULL;
44 44 }
45 45 bsp_GPIO_init();
46 46 bsp_uart_init();
47 47 bsp_iic_init();
48 48 printf("\r================================================================\n\r");
49 49 printf("================================================================\n\r");
50 50 printf(BSP);
51 51 printf(" initialised\n\r");
52 52 printf("================================================================\n\r");
53 53 return 1;
54 54 }
55 55
56 56 void bsp_GPIO_init()
57 57 {
58 58 gpio_t gpio1 = gpioopen(PD12);//gpioopen(LED1); //PD9 D=> 0x0300 9 => 0x0009
59 59 gpio_t gpio2 = gpioopen(PD13);//gpioopen(LED2);
60 60 gpio_t gpio3 = gpioopen(PD14);//gpioopen(LED2);
61 61 gpio_t gpio4 = gpioopen(PD15);//gpioopen(LED2);
62 62 gpio_t dacRst=gpioopen(PD4);
63 63 gpiosetspeed(&gpio1,gpiohighspeed);
64 64 gpiosetspeed(&gpio2,gpiohighspeed);
65 65 gpiosetspeed(&gpio3,gpiohighspeed);
66 66 gpiosetspeed(&gpio4,gpiohighspeed);
67 67 gpiosetspeed(&dacRst,gpiohighspeed);
68 68 gpiosetdir(&gpio1,gpiooutdir);
69 69 gpiosetdir(&gpio3,gpiooutdir);
70 70 gpiosetdir(&gpio2,gpiooutdir);
71 71 gpiosetdir(&gpio4,gpiooutdir);
72 72 gpiosetdir(&dacRst,gpiooutdir);
73 73 gpioset(dacRst);
74 74 }
75 75
76 76 void bsp_uart_init()
77 77 {
78 78 if(__opnfiles__[1]==NULL)
79 79 {
80 80 //uart_t* uart1 = (uart_t*)malloc(sizeof(uart_t));
81 81 streamdevice* fd1 = (streamdevice*)malloc(sizeof(streamdevice));
82 82 uart_t uart = uartopenandconfig(uart3,uartparitynone | uart8bits | uartonestop,115200,PB10,PB11,-1,-1);
83 83 uartmkstreamdev(uart,fd1);
84 84 __opnfiles__[1] = fd1;
85 85 }
86 86 else
87 87 {
88 uartopenandconfig(2,uartparitynone | uart8bits | uartonestop,115200,PB10,PB11,-1,-1);
88 uartopenandconfig(uart3,uartparitynone | uart8bits | uartonestop,115200,PB10,PB11,-1,-1);
89 89 }
90 90 }
91 91
92 92 void bsp_spi_init()
93 93 {
94 94
95 95 }
96 96
97 97
98 98 void bsp_iic_init()
99 99 {
100 100 i2copenandconfig(i2c1,0,400000,PB9,PB6);
101 101 i2copenandconfig(i2c3,0,400000,PC9,PA8);
102 102 }
103 103
104 104 void bsp_SD_init()
105 105 {
106 106
107 107 }
108 108
109 109 void vs10XXclearXCS(){}
110 110 void vs10XXsetXCS(){}
111 111 int vs10XXDREQ()
112 112 {
113 113 return 1;
114 114 }
115 115
116 116
117 117 void bsppowersdcard(char onoff) //always ON
118 118 {
119 119
120 120 }
121 121
122 122 char bspsdcardpresent()
123 123 {
124 124 return 0;
125 125 }
126 126
127 127 char bspsdcardwriteprotected()
128 128 {
129 129 return 0;
130 130 }
131 131
132 132 void bspsdcardselect(char YESNO)
133 133 {
134 134
135 135 }
136 136
137 137
138 138
139 139
140 140
@@ -1,13 +1,14
1 1 TEMPLATE = subdirs
2 2 CONFIG += ordered
3 3 SUBDIRS += QtTest/test.pro \
4 4 SOLAR_PSU_HELLO/hello.pro \
5 5 SDCARD \
6 6 STM32F4IT \
7 BeagleSynthHello
7 BeagleSynthHello \
8 ../../../home/jeandet/hello
8 9
9 10
10 11
11 12
12 13
13 14
@@ -1,272 +1,302
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the libuc, microcontroler library
3 3 -- Copyright (C) 2012, Alexis Jeandet
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------
19 19 -- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@gmail.com
21 21 -------------------------------------------------------------------------------*/
22 22 #include <ili9328.h>
23 23 #include <stdio.h>
24 24 #include <stddef.h>
25 25 #include <core.h>
26 26 #include <math.h>
27 27
28 28 #ifdef __OPTIMIZED_MATH
29 29 #include <optimised_math.h>
30 30 #endif
31 31
32 32 #define _delay_(del) for(volatile int _d_e_l_=0;_d_e_l_<(del);_d_e_l_++);
33 33
34 #define ilipaintLine(LCD,X,Y,W,buffer,buffsize) \
35 for(int l=0;l<1;l++)\
36 {\
37 ili9328setFrame(LCD,X,Y,W,1);\
38 int rem=(W)%buffsize;\
39 if(rem)LCD->interface->writeGRAM(buffer,rem);\
40 for(int i=rem;i<(W);i+=buffsize)\
41 {\
42 LCD->interface->writeGRAM(buffer,buffsize);\
43 }\
44 }
45
34 46 void ili9328setGRAMaddress(LCD_t* LCD,uint16_t Haddress,uint16_t Vaddress)
35 47 {
36 48 LCD->interface->writereg(ILI9328_REGISTER_HORIZONTALGRAMADDRESSSET,Haddress);
37 49 LCD->interface->writereg(ILI9328_REGISTER_VERTICALGRAMADDRESSSET,Vaddress);
38 50 }
39 51
40 52 void ili9328refreshenable(struct LCD_t* LCD,int enable)
41 53 {
42 54 if(enable)
43 55 {
44 56 //LCD->interface->writereg(ILI9328_REGISTER_ENTRYMODE,0x1018);
45 57 }
46 58 else
47 59 {
48 60 //LCD->interface->writereg(ILI9328_REGISTER_ENTRYMODE,0x1008);
49 61
50 62 }
51 63 }
52 64
53 65 void ili9328setFrame(LCD_t* LCD,uint16_t X,uint16_t Y,uint16_t W,uint16_t H)
54 66 {
55 67 LCD->interface->writereg(ILI9328_REGISTER_HORIZONTALGRAMADDRESSSET,(uint32_t)X);
56 68 LCD->interface->writereg(ILI9328_REGISTER_VERTICALGRAMADDRESSSET,(uint32_t)Y);
57 69 LCD->interface->writereg(ILI9328_REGISTER_HORIZONTALADDRESSSTARTPOSITION,(uint32_t)X);
58 70 LCD->interface->writereg(ILI9328_REGISTER_HORIZONTALADDRESSENDPOSITION,(uint32_t)(W+X-1));
59 71 LCD->interface->writereg(ILI9328_REGISTER_VERTICALADDRESSSTARTPOSITION,(uint32_t)Y);
60 72 LCD->interface->writereg(ILI9328_REGISTER_VERTICALADDRESSENDPOSITION,(uint32_t)(Y+H-1));
61 73 }
62 74
63 75 void ili9328paint(LCD_t* LCD,void* buffer,uint16_t Xpos,uint16_t Ypos,uint16_t Width,uint16_t Height)
64 76 {
65 77 if((LCD!=NULL) && (LCD->interface!=NULL) && (LCD->interface->writeGRAM!=NULL) && (LCD->width>(Xpos+Width)) && (LCD->height>(Ypos+Height)))
66 78 {
67 79 ili9328setFrame(LCD,Xpos,Ypos,Width,Height);
68 80 LCD->interface->writeGRAM(buffer,Width*Height);
69 81 }
70 82 }
71 83
72 84 void ili9328paintFilCircMidPoint(LCD_t* LCD,uint16_t Xpos,uint16_t Ypos,uint16_t r,uint32_t contColor,uint16_t contSz,uint32_t fillColor)
73 85 {
86 //Based on the mid point circle algorithm from Wikipedia
87 //http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
88
74 89 if(contSz<r)
75 90 {
76 for(int i=0;i<(r/2);i++)
77 {
91 int f = 1 - r;
92 int ddF_x = 1;
93 int ddF_y = -2 * r;
94 int x = 0;
95 int y = r;
96 uint16_t tmp1[16];
97 uint16_t tmp2[16];
98 for(int i=0;i<16;i++)tmp1[i]=fillColor;
99 for(int i=0;i<16;i++)tmp2[i]=contColor;
100 ilipaintLine(LCD,Xpos-r,Ypos,2*r,tmp1,16);
101 ilipaintLine(LCD,Xpos-r,Ypos+1,2*r,tmp1,16);
102 ilipaintLine(LCD,Xpos-1,Ypos+r,2,tmp1,16);
103 ilipaintLine(LCD,Xpos,Ypos-r,2,tmp1,16);
104 setPixel(x0, y0 + radius);
105 setPixel(x0, y0 - radius);
106 setPixel(x0 + radius, y0);
107 setPixel(x0 - radius, y0);
78 108
79 }
109
80 110 }
81 111
82 112 }
83 113
84 114 void ili9328paintFilCirc(LCD_t* LCD,uint16_t Xpos,uint16_t Ypos,uint16_t r,uint32_t contColor,uint16_t contSz,uint32_t fillColor)
85 115 {
86 116 if(contSz<r)
87 117 {
88 118 uint16_t tmp1[16];
89 119 uint16_t tmp2[16];
90 120 int32_t rr=(r*r),rr2=((r-contSz)*(r-contSz)),contSz2,Val1,Val2,X1,W,rem;
91 121 for(int i=0;i<16;i++)tmp1[i]=fillColor;
92 122 for(int i=0;i<16;i++)tmp2[i]=contColor;
93 123 /* Y = b +/- sqrt[r^2 - (x - a)^2] */
94 124 for(int32_t line=-r;line<r;line++)
95 125 {
96 126 #ifdef __OPTIMIZED_MATH
97 127 Val1 = (uint32_t)optimised_sqrt((float32_t)(rr - (line*line)) );
98 128 Val2 = (uint32_t)optimised_sqrt((float32_t)(rr2 - (line*line)) );
99 129 #else
100 130 Val1 = sqrt( (double)(rr - ((line)*(line))) );
101 131 Val2 = sqrt( (double)(rr2 - ((line)*(line))) );
102 132 #endif
103 133 X1=Xpos - Val1;
104 134 contSz2= Val1-Val2;
105 135 ili9328setFrame(LCD,X1,line+Ypos,2*Val1,1);
106 136 rem=(contSz2)%16;
107 137 if(rem)LCD->interface->writeGRAM(tmp2,rem);
108 138 for(int i=rem;i<(contSz2);i+=16)
109 139 {
110 140 LCD->interface->writeGRAM(tmp2,16);
111 141 }
112 142
113 143 W=2*Val1;
114 144 if(W>(2*contSz2))
115 145 {
116 146 W-=2*contSz2;
117 147 rem=(W)%16;
118 148 if(rem)LCD->interface->writeGRAM(tmp1,rem);
119 149 for(int i=rem;i<(W);i+=16)
120 150 {
121 151 LCD->interface->writeGRAM(tmp1,16);
122 152 }
123 153 }
124 154
125 155 rem=(contSz2)%16;
126 156 if(rem)LCD->interface->writeGRAM(tmp2,rem);
127 157 for(int i=rem;i<(contSz2);i+=16)
128 158 {
129 159 LCD->interface->writeGRAM(tmp2,16);
130 160 }
131 161 }
132 162 }
133 163 }
134 164
135 165
136 166
137 167
138 168 void ili9328paintFilRect(LCD_t* LCD,uint16_t Xpos,uint16_t Ypos,uint16_t w,uint16_t h,uint32_t contColor,uint16_t contSz,uint32_t fillColor)
139 169 {
140 170 ili9328setFrame(LCD,Xpos,Ypos,w,h);
141 171 uint16_t tmp[32];
142 172 for(int i=0;i<32;i++)tmp[i]=fillColor;
143 173 for(int i=0;i<(h*w);i+=32)
144 174 {
145 175 LCD->interface->writeGRAM(tmp,32);
146 176 }
147 177 int rem=(w*h)%32;
148 178 if(rem)LCD->interface->writeGRAM(tmp,rem);
149 179 if(contSz)
150 180 {
151 181 ili9328setFrame(LCD,Xpos,Ypos,w,contSz);
152 182 for(int i=0;i<32;i++)tmp[i]=contColor;
153 183 rem=(w*contSz)%32;
154 184 if(rem)LCD->interface->writeGRAM(tmp,rem);
155 185 for(int i=rem;i<(w*contSz);i+=32)
156 186 {
157 187 LCD->interface->writeGRAM(tmp,32);
158 188 }
159 189
160 190 ili9328setFrame(LCD,Xpos,Ypos+h-contSz,w,contSz);
161 191 rem=(w*contSz)%32;
162 192 if(rem)LCD->interface->writeGRAM(tmp,rem);
163 193 for(int i=rem;i<(w*contSz);i+=32)
164 194 {
165 195 LCD->interface->writeGRAM(tmp,32);
166 196 }
167 197
168 198 ili9328setFrame(LCD,Xpos,Ypos,contSz,h);
169 199 rem=(h*contSz)%32;
170 200 if(rem)LCD->interface->writeGRAM(tmp,rem);
171 201 for(int i=rem;i<(h*contSz);i+=32)
172 202 {
173 203 LCD->interface->writeGRAM(tmp,32);
174 204 }
175 205
176 206 ili9328setFrame(LCD,Xpos+w-contSz,Ypos,contSz,h);
177 207 rem=(h*contSz)%32;
178 208 if(rem)LCD->interface->writeGRAM(tmp,rem);
179 209 for(int i=rem;i<(h*contSz);i+=32)
180 210 {
181 211 LCD->interface->writeGRAM(tmp,32);
182 212 }
183 213 }
184 214 }
185 215
186 216 void ili9328paintText(LCD_t* LCD,char* buffer,uint16_t Xpos,uint16_t Ypos,sFONT* font,uint32_t color)
187 217 {
188 218 int w=font->Width,h=font->Height,bpl=font->bytesPerLine,pix=0,tableoffset=0;
189 219 uint16_t tmp[w];
190 220 uint16_t linenum=0,charnum=0;
191 221 uint8_t line=0;
192 222 while(*buffer)
193 223 {
194 224 ili9328setFrame(LCD,Xpos+(charnum*w),Ypos-h,w,1);
195 225 LCD->interface->readGRAM(tmp,w);
196 226 for(int i=0;i<(h*w);i++)
197 227 {
198 228 if( ((i%w)==0) ) //read current line to apply text pixmap
199 229 {
200 230 if(linenum++>0)
201 231 {
202 232 ili9328setFrame(LCD,Xpos+(charnum*w),Ypos + linenum -h,w,1);
203 233 LCD->interface->writeGRAM(tmp,w);
204 234 ili9328setFrame(LCD,Xpos+(charnum*w),Ypos + linenum + 1-h,w,1);
205 235 LCD->interface->readGRAM(tmp,w);
206 236 pix=0;
207 237 }
208 238 }
209 239 if((pix%8) == 0)
210 240 {
211 241 line=font->table[(((*buffer)-32)*h*bpl)+tableoffset++];
212 242 }
213 243 if((line & (uint8_t)0x01)==(uint8_t)1)tmp[pix]=(uint16_t)color;
214 244 pix++;
215 245 line>>=1;
216 246 }
217 247 linenum=0;
218 248 tableoffset=0;
219 249 charnum++;
220 250 buffer++;
221 251 }
222 252 }
223 253
224 254 int ili9328init(struct LCD_t* LCD)
225 255 {
226 256 if((LCD!=NULL) && (LCD->interface!=NULL) && (LCD->interface->writereg!=NULL))
227 257 {
228 258 LCD->interface->writereg(ILI9328_REGISTER_DRIVEROUTPUTCONTROL1, 0x0100); // Driver Output Control Register (R01h)
229 259 LCD->interface->writereg(ILI9328_REGISTER_LCDDRIVINGCONTROL, 0x0700); // LCD Driving Waveform Control (R02h)
230 260 LCD->interface->writereg(ILI9328_REGISTER_ENTRYMODE, 0x1030); // Entry Mode (R03h)
231 261 LCD->interface->writereg(ILI9328_REGISTER_DISPLAYCONTROL2, 0x0202);
232 262 LCD->interface->writereg(ILI9328_REGISTER_DISPLAYCONTROL3, 0x0000);
233 263 LCD->interface->writereg(ILI9328_REGISTER_DISPLAYCONTROL4, 0x0000); // Fmark On
234 264 LCD->interface->writereg(ILI9328_REGISTER_POWERCONTROL1, 0x0000); // Power Control 1 (R10h)
235 265 LCD->interface->writereg(ILI9328_REGISTER_POWERCONTROL2, 0x0007); // Power Control 2 (R11h)
236 266 LCD->interface->writereg(ILI9328_REGISTER_POWERCONTROL3, 0x0000); // Power Control 3 (R12h)
237 267 LCD->interface->writereg(ILI9328_REGISTER_POWERCONTROL4, 0x0000); // Power Control 4 (R13h)
238 268 delay_100us(10);
239 269 LCD->interface->writereg(ILI9328_REGISTER_POWERCONTROL1, 0x14B0); // Power Control 1 (R10h)
240 270 delay_100us(10);
241 271 LCD->interface->writereg(ILI9328_REGISTER_POWERCONTROL2, 0x0007); // Power Control 2 (R11h)
242 272 delay_100us(10);
243 273 LCD->interface->writereg(ILI9328_REGISTER_POWERCONTROL3, 0x008E); // Power Control 3 (R12h)
244 274 LCD->interface->writereg(ILI9328_REGISTER_POWERCONTROL4, 0x0C00); // Power Control 4 (R13h)
245 275 LCD->interface->writereg(ILI9328_REGISTER_POWERCONTROL7, 0x0015); // NVM read data 2 (R29h)
246 276 delay_100us(500);
247 277 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL1, 0x0000); // Gamma Control 1
248 278 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL2, 0x0107); // Gamma Control 2
249 279 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL3, 0x0000); // Gamma Control 3
250 280 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL4, 0x0203); // Gamma Control 4
251 281 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL5, 0x0402); // Gamma Control 5
252 282 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL6, 0x0000); // Gamma Control 6
253 283 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL7, 0x0207); // Gamma Control 7
254 284 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL8, 0x0000); // Gamma Control 8
255 285 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL9, 0x0203); // Gamma Control 9
256 286 LCD->interface->writereg(ILI9328_REGISTER_GAMMACONTROL10, 0x0403); // Gamma Control 10
257 287 LCD->interface->writereg(ILI9328_REGISTER_HORIZONTALADDRESSSTARTPOSITION, 0x0000); // Window Horizontal RAM Address Start (R50h)
258 288 LCD->interface->writereg(ILI9328_REGISTER_HORIZONTALADDRESSENDPOSITION, 240 - 1); // Window Horizontal RAM Address End (R51h)
259 289 LCD->interface->writereg(ILI9328_REGISTER_VERTICALADDRESSSTARTPOSITION, 0X0000); // Window Vertical RAM Address Start (R52h)
260 290 LCD->interface->writereg(ILI9328_REGISTER_VERTICALADDRESSENDPOSITION, 320 - 1); // Window Vertical RAM Address End (R53h)
261 291 LCD->interface->writereg(ILI9328_REGISTER_DRIVEROUTPUTCONTROL2, 0xa700); // Driver Output Control (R60h)
262 292 LCD->interface->writereg(ILI9328_REGISTER_BASEIMAGEDISPLAYCONTROL, 0x0003); // Driver Output Control (R61h) - enable VLE
263 293 LCD->interface->writereg(ILI9328_REGISTER_PANELINTERFACECONTROL1, 0X0010); // Panel Interface Control 1 (R90h)
264 294 // Display On
265 295 LCD->interface->writereg(ILI9328_REGISTER_DISPLAYCONTROL1, 0x0133); // Display Control (R07h)
266 296 delay_100us(500);
267 297 LCD->interface->writereg(ILI9328_REGISTER_ENTRYMODE, 0x0038);
268 298 }
269 299 return 0;
270 300 }
271 301
272 302
@@ -1,358 +1,375
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the libuc, microcontroler library
3 3 -- Copyright (C) 2011, Alexis Jeandet
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------
19 19 -- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@gmail.com
21 21 -------------------------------------------------------------------------------*/
22 22 #include <core.h>
23 23 #include <stm32f4xx_rcc.h>
24 24 #include <stdint.h>
25 25 #include <stdlib.h>
26 26 #include <stdio.h>
27 27 #include <core_cm4.h>
28 28
29 29 extern uint32_t OSC0;
30 30 extern uint32_t INTOSC;
31 31 extern uint32_t RTCOSC;
32 32
33 33 volatile uint32_t tickCounter=0;
34 34
35 35
36 36 void SysTick_Handler(void)
37 37 {
38 38 tickCounter+=1;
39 39 }
40 40
41 void delay_us(uint32_t value)
42 {
43 extern uint32_t currentCpuFreq;
44 if(value)
45 {
46 uint32_t tickperus=currentCpuFreq/(1000*10);
47 uint32_t SysTickSnap = SysTick->VAL+((value%100)*tickperus);
48 uint32_t targetVal=tickCounterSnap +(value/100);
49 if(targetVal < tickCounterSnap)
50 {
51 while(tickCounter > targetVal);
52 }
53 while((tickCounter < targetVal) | (SysTick->VAL<SysTickSnap));
54 }
55 }
56
41 57 void delay_100us(uint32_t value)
42 58 {
43 59 if(value)
44 60 {
45 61 uint32_t tickCounterSnap = tickCounter;
62 uint32_t SysTickSnap = SysTick->VAL;
46 63 uint32_t targetVal=tickCounterSnap +(value);
47 64 if(targetVal < tickCounterSnap)
48 65 {
49 66 while(tickCounter > targetVal);
50 67 }
51 while(tickCounter < targetVal);
68 while((tickCounter < targetVal) | (SysTick->VAL<SysTickSnap));
52 69 }
53 70 }
54 71
55 72 uint32_t getAPB1Freq()
56 73 {
57 74 RCC_ClocksTypeDef RCC_ClocksStatus;
58 75 RCC_GetClocksFreq(&RCC_ClocksStatus);
59 76 return RCC_ClocksStatus.PCLK1_Frequency;
60 77 }
61 78
62 79 uint32_t getAPB2Freq()
63 80 {
64 81 RCC_ClocksTypeDef RCC_ClocksStatus;
65 82 RCC_GetClocksFreq(&RCC_ClocksStatus);
66 83 return RCC_ClocksStatus.PCLK2_Frequency;
67 84 }
68 85
69 86
70 87 uint32_t getCpuFreq()
71 88 {
72 89 uint32_t cpufreq = OSC0;
73 90 uint32_t PLLN,PLLM,PLLP;
74 91
75 92 if((RCC->CFGR & 0xC) == 8) //PLL used as sys clk
76 93 {
77 94 uint32_t pllinput=INTOSC;
78 95 if((RCC->PLLCFGR & (1<<22)) == (1<<22))
79 96 {
80 97 pllinput=OSC0;
81 98 }
82 99 PLLN = (RCC->PLLCFGR>>6) & 0x1FF;
83 100 PLLM = RCC->PLLCFGR & 0x3F;
84 101 PLLP = 1<<(((RCC->PLLCFGR>>16) & 3 )+1);
85 102 cpufreq = (pllinput * PLLN )/(PLLM*PLLP);
86 103 }
87 104 else if((RCC->CFGR & 0xC) == 0) //HSI used as sys clk
88 105 {
89 106 cpufreq=INTOSC;
90 107 }
91 108 if((RCC->CFGR & (1<<7))==1<<7)
92 109 {
93 110 return cpufreq>>((RCC->CFGR & (7<<4))>>4);
94 111 }
95 112 return cpufreq;
96 113 }
97 114
98 115 void reset_AHB1()
99 116 {
100 117 RCC->AHB1RSTR = -1;
101 118 RCC->AHB1RSTR = 0;
102 119 }
103 120
104 121 void reset_AHB2()
105 122 {
106 123 RCC->AHB2RSTR = -1;
107 124 RCC->AHB2RSTR = 0;
108 125 }
109 126
110 127 void reset_APB1()
111 128 {
112 129 RCC->APB1RSTR = -1;
113 130 RCC->APB1RSTR = 0;
114 131 }
115 132
116 133 void reset_APB2()
117 134 {
118 135 RCC->APB2RSTR = -1;
119 136 RCC->APB2RSTR = 0;
120 137 }
121 138
122 139
123 140
124 141 /*
125 142 | 2.7->3.6V
126 143 -------------------------
127 144 0WS | 0<HCLK<=30
128 145 1WS | 30<HCLK<=60
129 146 2WS | 60<HCLK<=90
130 147 3WS | 90<HCLK<=120
131 148 4WS | 120<HCLK<=150
132 149 5WS | 150<HCLK<=168
133 150
134 151 f(VCO clock) = f(PLL clock input) Γ— (PLLN / PLLM) [1]
135 152 64MHz <= f(VCO clock) <= 432MHz [2]
136 153
137 154 f(VCO clock input) must be between 1MHz and 2MHz and as close to 2MHz as possible!! [3]
138 155
139 156 f(PLL general clock output) = f(VCO clock) / PLLP [4]
140 157
141 158 CPU<168MHz AHB1<168MHz AHB2<168MHz APB1<42MHz APB2<84MHz [5]
142 159
143 160 ! 63<=PLLN<=432 [6]
144 161 ! 2<=PLLM<=63 [7]
145 162 ! PLLP=2,4,6,8 [8]
146 163 4<=PLLM*PLLP<=504
147 164
148 165 F= f(PLL clock input) * A/B with
149 166 63<=A<=432
150 167 4<=B<=504
151 168
152 169 */
153 170
154 171
155 172 int optimizePLLcfg(uint32_t freq, uint32_t srcfreq,uint32_t PLLM,uint32_t* PLLP, uint32_t* PLLN,uint8_t* AHBPRindx)
156 173 {
157 174 uint32_t AHBPRtbl[9]={1,2,4,8,16,64,128,256,512};
158 175 uint32_t AHBPR=0,AHBPR_r=0,PLLN_r=0,PLLP_r=0;
159 176 uint32_t Fplli=0;
160 177 int32_t f_error=100000000;
161 178 int32_t f_errornw=100000000;
162 179 Fplli = srcfreq / PLLM;
163 180 //not efficient but should find the best parameters
164 181 for((*AHBPRindx)=0;(*AHBPRindx)<9;(*AHBPRindx)++) //lowest priority
165 182 {
166 183 AHBPR = AHBPRtbl[(*AHBPRindx)];
167 184 for(*PLLP=2;*PLLP<9;*PLLP+=2)
168 185 {
169 186 *PLLN = (freq*(*PLLP)*AHBPR)/Fplli;
170 187 if(((*PLLN)>62) && ((*PLLN)<433) && ((Fplli * (*PLLN)) < 433000000))
171 188 {
172 189 f_errornw = abs((int32_t)((int32_t)((Fplli*(*PLLN))/((*PLLP)*AHBPR))-freq));
173 190 if( ( (f_error)>(f_errornw) ) || ( (*AHBPRindx==0)&&(*PLLP==2)&&(*PLLN==63) ) )
174 191 {
175 192 f_error=f_errornw;
176 193 PLLN_r = *PLLN;
177 194 PLLP_r = *PLLP;
178 195 AHBPR_r=*AHBPRindx;
179 196 if(f_error==0)
180 197 {
181 198 *PLLN = PLLN_r;
182 199 *PLLP = PLLP_r;
183 200 *AHBPRindx = AHBPR_r;
184 201 return 1;
185 202 }
186 203 }
187 204 }
188 205 }
189 206 }
190 207 *PLLN = PLLN_r;
191 208 *PLLP = PLLP_r;
192 209 *AHBPRindx = AHBPR_r;
193 210 return 1;
194 211 }
195 212
196 213
197 214 int setPll(uint32_t freq)
198 215 {
199 216 extern uint32_t OSC0;
200 217 extern uint32_t INTOSC;
201 218 uint32_t srcfreq = INTOSC;
202 219 uint8_t AHBPRindx;
203 220 uint32_t AHBPRtbl[9]={1,2,4,8,16,64,128,256,512};
204 221 uint32_t PLLN=0,PLLM=0,PLLP=0,AHBPR=0;
205 222 uint32_t Fplli=0;
206 223 if((RCC->PLLCFGR & (1<<22))==(1<<22))
207 224 {
208 225 srcfreq = OSC0;
209 226 }
210 227 PLLM = srcfreq / 1500000; // [3]
211 228 Fplli = srcfreq / PLLM;
212 229 optimizePLLcfg(freq,srcfreq,PLLM,&PLLP,&PLLN,&AHBPRindx);
213 230 srcfreq = (Fplli*PLLN)/(PLLP*AHBPRtbl[AHBPRindx]); //Put real clk freq in srcfreq for return value
214 231 //now switch to HSIs
215 232 if((RCC->CR & 1)==0)RCC->CR |= 1; //turn ON HSI
216 233 while((RCC->CR & 2)!=2); //wait for HSI Ready
217 234 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
218 235 RCC->CFGR |= RCC_CFGR_SW_HSI; //set HSI as main clk
219 236 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_HSI);
220 237 RCC->CR &= ~(1<<24); //Turn OFF PLL
221 238 RCC->PLLCFGR &= ~0x37FFF; //clear PLLP PLLM PLLN
222 239 RCC->PLLCFGR |= PLLM + (PLLN<<6) + (((PLLP>>1) -1)<<16);
223 240 RCC->CR |= RCC_CR_PLLON; //Turn ON PLL
224 241 while((RCC->CR & (1<<25))!=(1<<25)); //wait for PLL Ready
225 242 if(AHBPRindx!=0)AHBPRindx|=0x8;
226 243 RCC->CFGR &= ~(0xF<<4);
227 244 RCC->CFGR |= (uint32_t)(AHBPRindx<<4);
228 245 AHBPR=0;
229 246 while((srcfreq>>AHBPR)>42000000)AHBPR++; //[5] //Thune APB1 prescaler to keep APB1 CLK below 42MHz
230 247 if(AHBPR!=0)
231 248 {
232 249 AHBPR-=1;
233 250 AHBPR|=0x4;
234 251 }
235 252 RCC->CFGR &= ~(0x7<<10);
236 253 RCC->CFGR |= (uint32_t)(AHBPR<<10);
237 254 AHBPR=0;
238 255 while((srcfreq>>AHBPR)>84000000)AHBPR++; //[5] //Thune APB2 prescaler to keep APB2 CLK below 42MHz
239 256 if(AHBPR!=0)
240 257 {
241 258 AHBPR-=1;
242 259 AHBPR|=0x4;
243 260 }
244 261 RCC->CFGR &= ~(0x7<<13);
245 262 RCC->CFGR |= (uint32_t)(AHBPR<<13);
246 263 FLASH->ACR |= FLASH_ACR_LATENCY_7WS;
247 264 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));//Switch to PLL as main clk source
248 265 RCC->CFGR |= RCC_CFGR_SW_PLL;
249 266 /* Wait till the main PLL is used as system clock source */
250 267 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
251 268 if(srcfreq>150000000)
252 269 {
253 270 FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_5WS;
254 271 }
255 272 if((srcfreq<150000000) && (srcfreq>=120000000))
256 273 {
257 274 FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_4WS;
258 275 }
259 276 if((srcfreq<120000000) && (srcfreq>=90000000))
260 277 {
261 278 FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_3WS;
262 279 }
263 280 if((srcfreq<90000000) && (srcfreq>=60000000))
264 281 {
265 282 FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_2WS;
266 283 }
267 284 if((srcfreq<60000000) && (srcfreq>=30000000))
268 285 {
269 286 FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_1WS;
270 287 }
271 288 if(srcfreq<30000000)
272 289 {
273 290 FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_0WS;
274 291 }
275 292 return srcfreq;
276 293 }
277 294
278 295 void configureSysTick()
279 296 {
280 297 extern uint32_t currentCpuFreq;
281 298 uint32_t us=currentCpuFreq/(1000*10);
282 299 SysTick_Config(us);
283 300 }
284 301
285 302 int setCpuFreq(uint32_t freq)
286 303 {
287 304 extern uint32_t OSC0;
288 305 extern uint32_t INTOSC;
289 306 uint8_t i=0;
290 307 uint32_t curentFeq = getCpuFreq();
291 308 if(curentFeq==freq)return curentFeq;
292 309 if((freq>2000000) && (freq<=250000000)) //be carefull with 250MHz!!!
293 310 {
294 311 if((RCC->CFGR & 0xC) == 8) //PLL used as sys clk
295 312 {
296 313 return setPll(freq);
297 314 }
298 315 else if((RCC->CFGR & 0xC) == 0) //HSI used as sys clk
299 316 {
300 317 if((INTOSC%freq)==0) //now check if we can directly divide HSI
301 318 {
302 319 if(freq==INTOSC)
303 320 {
304 321 RCC->CFGR &= ~(0xF<<4);
305 322 return freq;
306 323 }
307 324 for(i=1;i<8;i++)
308 325 {
309 326 if((freq<<i)==INTOSC)
310 327 {
311 328 RCC->CFGR &= ~(0xF<<4);
312 329 RCC->CFGR |= ((0x8|i)<<4);
313 330 return freq;
314 331 }
315 332 }
316 333 }
317 334 else
318 335 return setPll(freq);
319 336 }
320 337 else //HSE used as sys clk
321 338 {
322 339 if((OSC0%freq)==0) //now check if we can directly divide HSI
323 340 {
324 341 if(freq==OSC0)
325 342 {
326 343 RCC->CFGR &= ~(0xF<<4);
327 344 return freq;
328 345 }
329 346 for(i=1;i<8;i++)
330 347 {
331 348 if((freq<<i)==OSC0)
332 349 {
333 350 RCC->CFGR &= ~(0xF<<4);
334 351 RCC->CFGR |= ((0x8|i)<<4);
335 352 return freq;
336 353 }
337 354 }
338 355 }
339 356 else
340 357 return setPll(freq);
341 358 }
342 359 }
343 360 return 0;
344 361 }
345 362
346 363
347 364 void enable_FPU()
348 365 {
349 366 SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
350 367 __asm__("dsb");
351 368 __asm__("isb");
352 369 }
353 370
354 371
355 372
356 373
357 374
358 375
General Comments 0
You need to be logged in to leave comments. Login now