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