##// END OF EJS Templates
Added Simulator target to run code on x86 and debug functions....
Added Simulator target to run code on x86 and debug functions. Fixed some bugs on terminal widget.

File last commit:

r63:68dfbccdd813 dev_alexis
r63:68dfbccdd813 dev_alexis
Show More
core.c
378 lines | 10.4 KiB | text/x-c | CLexer
jeandet@PC-DE-JEANDET.lpp.polytechnique.fr
Added STM32F4 target, improved rules files, added additional Include folder var...
r14 /*------------------------------------------------------------------------------
-- This file is a part of the libuc, microcontroler library
-- Copyright (C) 2011, Alexis Jeandet
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-------------------------------------------------------------------------------
-- Author : Alexis Jeandet
-- Mail : alexis.jeandet@gmail.com
-------------------------------------------------------------------------------*/
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Sync
r39 #include <core.h>
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Now uses qmake to compile an Qt-creator compatible!
r18 #include <stm32f4xx_rcc.h>
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 #include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
jeandet@PC-DE-JEANDET.lab-lpp.local
added Systick handler with 100us period
r40 #include <core_cm4.h>
Added Simulator target to run code on x86 and debug functions....
r63 #include <gpio.h>
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Now uses qmake to compile an Qt-creator compatible!
r18
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 extern uint32_t OSC0;
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Now uses qmake to compile an Qt-creator compatible!
r18 extern uint32_t INTOSC;
extern uint32_t RTCOSC;
jeandet@PC-DE-JEANDET.lpp.polytechnique.fr
Added STM32F4 target, improved rules files, added additional Include folder var...
r14
jeandet@PC-DE-JEANDET.lab-lpp.local
added Systick handler with 100us period
r40 volatile uint32_t tickCounter=0;
void SysTick_Handler(void)
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Sync
r39 {
jeandet@PC-DE-JEANDET.lab-lpp.local
added Systick handler with 100us period
r40 tickCounter+=1;
Added Simulator target to run code on x86 and debug functions....
r63 if((tickCounter&0xFFF)==0x800)
gpiosetval(PC15,!gpiogetval(PC15));
jeandet@PC-DE-JEANDET.lab-lpp.local
added Systick handler with 100us period
r40 }
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r45 void delay_us(uint32_t value)
{
extern uint32_t currentCpuFreq;
if(value)
{
uint32_t tickperus=currentCpuFreq/(1000*10);
New version totaly integrated to Qt through custom sdk build!...
r47 uint32_t tickCounterSnap = SysTick->VAL+((value%100)*tickperus);
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r45 uint32_t targetVal=tickCounterSnap +(value/100);
if(targetVal < tickCounterSnap)
{
while(tickCounter > targetVal);
}
New version totaly integrated to Qt through custom sdk build!...
r47 while((tickCounter < targetVal) | (SysTick->VAL<tickCounterSnap));
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r45 }
}
jeandet@PC-DE-JEANDET.lab-lpp.local
added Systick handler with 100us period
r40 void delay_100us(uint32_t value)
{
if(value)
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Sync
r39 {
jeandet@PC-DE-JEANDET.lab-lpp.local
added Systick handler with 100us period
r40 uint32_t tickCounterSnap = tickCounter;
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r45 uint32_t SysTickSnap = SysTick->VAL;
jeandet@PC-DE-JEANDET.lab-lpp.local
added Systick handler with 100us period
r40 uint32_t targetVal=tickCounterSnap +(value);
if(targetVal < tickCounterSnap)
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Sync
r39 {
jeandet@PC-DE-JEANDET.lab-lpp.local
added Systick handler with 100us period
r40 while(tickCounter > targetVal);
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Sync
r39 }
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r45 while((tickCounter < targetVal) | (SysTick->VAL<SysTickSnap));
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Sync
r39 }
}
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22
uint32_t getAPB1Freq()
jeandet@PC-DE-JEANDET.lpp.polytechnique.fr
Added STM32F4 target, improved rules files, added additional Include folder var...
r14 {
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 RCC_ClocksTypeDef RCC_ClocksStatus;
RCC_GetClocksFreq(&RCC_ClocksStatus);
return RCC_ClocksStatus.PCLK1_Frequency;
}
uint32_t getAPB2Freq()
{
RCC_ClocksTypeDef RCC_ClocksStatus;
RCC_GetClocksFreq(&RCC_ClocksStatus);
return RCC_ClocksStatus.PCLK2_Frequency;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Now uses qmake to compile an Qt-creator compatible!
r18
jeandet@PC-DE-JEANDET.lpp.polytechnique.fr
Added STM32F4 target, improved rules files, added additional Include folder var...
r14
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 uint32_t getCpuFreq()
{
uint32_t cpufreq = OSC0;
uint32_t PLLN,PLLM,PLLP;
if((RCC->CFGR & 0xC) == 8) //PLL used as sys clk
{
uint32_t pllinput=INTOSC;
if((RCC->PLLCFGR & (1<<22)) == (1<<22))
{
pllinput=OSC0;
}
PLLN = (RCC->PLLCFGR>>6) & 0x1FF;
PLLM = RCC->PLLCFGR & 0x3F;
PLLP = 1<<(((RCC->PLLCFGR>>16) & 3 )+1);
cpufreq = (pllinput * PLLN )/(PLLM*PLLP);
}
else if((RCC->CFGR & 0xC) == 0) //HSI used as sys clk
{
cpufreq=INTOSC;
}
if((RCC->CFGR & (1<<7))==1<<7)
{
return cpufreq>>((RCC->CFGR & (7<<4))>>4);
}
return cpufreq;
}
void reset_AHB1()
{
RCC->AHB1RSTR = -1;
RCC->AHB1RSTR = 0;
}
void reset_AHB2()
{
RCC->AHB2RSTR = -1;
RCC->AHB2RSTR = 0;
}
void reset_APB1()
{
RCC->APB1RSTR = -1;
RCC->APB1RSTR = 0;
}
void reset_APB2()
{
RCC->APB2RSTR = -1;
RCC->APB2RSTR = 0;
jeandet@PC-DE-JEANDET.lpp.polytechnique.fr
Added STM32F4 target, improved rules files, added additional Include folder var...
r14 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 /*
| 2.7->3.6V
-------------------------
0WS | 0<HCLK<=30
1WS | 30<HCLK<=60
2WS | 60<HCLK<=90
3WS | 90<HCLK<=120
4WS | 120<HCLK<=150
5WS | 150<HCLK<=168
jeandet@PC-DE-JEANDET.lpp.polytechnique.fr
Added STM32F4 target, improved rules files, added additional Include folder var...
r14
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 f(VCO clock) = f(PLL clock input) × (PLLN / PLLM) [1]
64MHz <= f(VCO clock) <= 432MHz [2]
f(VCO clock input) must be between 1MHz and 2MHz and as close to 2MHz as possible!! [3]
f(PLL general clock output) = f(VCO clock) / PLLP [4]
CPU<168MHz AHB1<168MHz AHB2<168MHz APB1<42MHz APB2<84MHz [5]
! 63<=PLLN<=432 [6]
! 2<=PLLM<=63 [7]
! PLLP=2,4,6,8 [8]
4<=PLLM*PLLP<=504
F= f(PLL clock input) * A/B with
63<=A<=432
4<=B<=504
*/
int optimizePLLcfg(uint32_t freq, uint32_t srcfreq,uint32_t PLLM,uint32_t* PLLP, uint32_t* PLLN,uint8_t* AHBPRindx)
{
uint32_t AHBPRtbl[9]={1,2,4,8,16,64,128,256,512};
uint32_t AHBPR=0,AHBPR_r=0,PLLN_r=0,PLLP_r=0;
uint32_t Fplli=0;
int32_t f_error=100000000;
int32_t f_errornw=100000000;
Fplli = srcfreq / PLLM;
//not efficient but should find the best parameters
for((*AHBPRindx)=0;(*AHBPRindx)<9;(*AHBPRindx)++) //lowest priority
{
AHBPR = AHBPRtbl[(*AHBPRindx)];
for(*PLLP=2;*PLLP<9;*PLLP+=2)
{
*PLLN = (freq*(*PLLP)*AHBPR)/Fplli;
if(((*PLLN)>62) && ((*PLLN)<433) && ((Fplli * (*PLLN)) < 433000000))
{
f_errornw = abs((int32_t)((int32_t)((Fplli*(*PLLN))/((*PLLP)*AHBPR))-freq));
if( ( (f_error)>(f_errornw) ) || ( (*AHBPRindx==0)&&(*PLLP==2)&&(*PLLN==63) ) )
{
f_error=f_errornw;
PLLN_r = *PLLN;
PLLP_r = *PLLP;
AHBPR_r=*AHBPRindx;
if(f_error==0)
{
*PLLN = PLLN_r;
*PLLP = PLLP_r;
*AHBPRindx = AHBPR_r;
return 1;
}
}
}
}
}
*PLLN = PLLN_r;
*PLLP = PLLP_r;
*AHBPRindx = AHBPR_r;
return 1;
}
int setPll(uint32_t freq)
jeandet@PC-DE-JEANDET.lpp.polytechnique.fr
Added STM32F4 target, improved rules files, added additional Include folder var...
r14 {
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 extern uint32_t OSC0;
extern uint32_t INTOSC;
uint32_t srcfreq = INTOSC;
uint8_t AHBPRindx;
uint32_t AHBPRtbl[9]={1,2,4,8,16,64,128,256,512};
uint32_t PLLN=0,PLLM=0,PLLP=0,AHBPR=0;
uint32_t Fplli=0;
if((RCC->PLLCFGR & (1<<22))==(1<<22))
{
srcfreq = OSC0;
}
PLLM = srcfreq / 1500000; // [3]
Fplli = srcfreq / PLLM;
optimizePLLcfg(freq,srcfreq,PLLM,&PLLP,&PLLN,&AHBPRindx);
srcfreq = (Fplli*PLLN)/(PLLP*AHBPRtbl[AHBPRindx]); //Put real clk freq in srcfreq for return value
//now switch to HSIs
if((RCC->CR & 1)==0)RCC->CR |= 1; //turn ON HSI
while((RCC->CR & 2)!=2); //wait for HSI Ready
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_HSI; //set HSI as main clk
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_HSI);
RCC->CR &= ~(1<<24); //Turn OFF PLL
RCC->PLLCFGR &= ~0x37FFF; //clear PLLP PLLM PLLN
RCC->PLLCFGR |= PLLM + (PLLN<<6) + (((PLLP>>1) -1)<<16);
RCC->CR |= RCC_CR_PLLON; //Turn ON PLL
while((RCC->CR & (1<<25))!=(1<<25)); //wait for PLL Ready
if(AHBPRindx!=0)AHBPRindx|=0x8;
RCC->CFGR &= ~(0xF<<4);
RCC->CFGR |= (uint32_t)(AHBPRindx<<4);
AHBPR=0;
while((srcfreq>>AHBPR)>42000000)AHBPR++; //[5] //Thune APB1 prescaler to keep APB1 CLK below 42MHz
if(AHBPR!=0)
{
AHBPR-=1;
AHBPR|=0x4;
}
RCC->CFGR &= ~(0x7<<10);
RCC->CFGR |= (uint32_t)(AHBPR<<10);
AHBPR=0;
while((srcfreq>>AHBPR)>84000000)AHBPR++; //[5] //Thune APB2 prescaler to keep APB2 CLK below 42MHz
if(AHBPR!=0)
{
AHBPR-=1;
AHBPR|=0x4;
}
RCC->CFGR &= ~(0x7<<13);
RCC->CFGR |= (uint32_t)(AHBPR<<13);
FLASH->ACR |= FLASH_ACR_LATENCY_7WS;
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));//Switch to PLL as main clk source
RCC->CFGR |= RCC_CFGR_SW_PLL;
Factorised stream device structure to reduce memory usage....
r51 /* Wait untill the main PLL is used as system clock source */
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
if(srcfreq>150000000)
{
FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_5WS;
}
if((srcfreq<150000000) && (srcfreq>=120000000))
{
FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_4WS;
}
if((srcfreq<120000000) && (srcfreq>=90000000))
{
FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_3WS;
}
if((srcfreq<90000000) && (srcfreq>=60000000))
{
FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_2WS;
}
if((srcfreq<60000000) && (srcfreq>=30000000))
{
FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_1WS;
}
if(srcfreq<30000000)
{
FLASH->ACR &= (~7)|FLASH_ACR_LATENCY_0WS;
}
return srcfreq;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Sync
r39 void configureSysTick()
{
jeandet@PC-DE-JEANDET.lab-lpp.local
added Systick handler with 100us period
r40 extern uint32_t currentCpuFreq;
uint32_t us=currentCpuFreq/(1000*10);
SysTick_Config(us);
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Sync
r39 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 int setCpuFreq(uint32_t freq)
{
extern uint32_t OSC0;
extern uint32_t INTOSC;
uint8_t i=0;
uint32_t curentFeq = getCpuFreq();
if(curentFeq==freq)return curentFeq;
if((freq>2000000) && (freq<=250000000)) //be carefull with 250MHz!!!
{
if((RCC->CFGR & 0xC) == 8) //PLL used as sys clk
{
return setPll(freq);
}
else if((RCC->CFGR & 0xC) == 0) //HSI used as sys clk
{
if((INTOSC%freq)==0) //now check if we can directly divide HSI
{
if(freq==INTOSC)
{
RCC->CFGR &= ~(0xF<<4);
return freq;
}
for(i=1;i<8;i++)
{
if((freq<<i)==INTOSC)
{
RCC->CFGR &= ~(0xF<<4);
RCC->CFGR |= ((0x8|i)<<4);
return freq;
}
}
}
else
return setPll(freq);
}
else //HSE used as sys clk
{
if((OSC0%freq)==0) //now check if we can directly divide HSI
{
if(freq==OSC0)
{
RCC->CFGR &= ~(0xF<<4);
return freq;
}
for(i=1;i<8;i++)
{
if((freq<<i)==OSC0)
{
RCC->CFGR &= ~(0xF<<4);
RCC->CFGR |= ((0x8|i)<<4);
return freq;
}
}
}
else
return setPll(freq);
}
}
return 0;
}
void enable_FPU()
{
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
__asm__("dsb");
__asm__("isb");
jeandet@PC-DE-JEANDET.lpp.polytechnique.fr
Added STM32F4 target, improved rules files, added additional Include folder var...
r14 }
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
Now uses qmake to compile an Qt-creator compatible!
r18