diff --git a/bsp/includes/SOLAR_LFR_PSU/bsp.h b/bsp/includes/SOLAR_LFR_PSU/bsp.h --- a/bsp/includes/SOLAR_LFR_PSU/bsp.h +++ b/bsp/includes/SOLAR_LFR_PSU/bsp.h @@ -37,8 +37,11 @@ #endif */ -#define LED1 PD8 -#define LED2 PD9 +#define LED1 PD12 +#define LED2 PD13 +#define LED3 PD14 +#define LED4 PD15 + #define LED3ON GPIOB->BSRRH = GPIO_Pin_15 #define LED2ON GPIOD->BSRRH = GPIO_Pin_8 diff --git a/bsp/src/SOLAR_LFR_PSU/bsp.c b/bsp/src/SOLAR_LFR_PSU/bsp.c --- a/bsp/src/SOLAR_LFR_PSU/bsp.c +++ b/bsp/src/SOLAR_LFR_PSU/bsp.c @@ -25,6 +25,8 @@ #include #include #include +#include + uint32_t OSC0 =8000000; uint32_t INTOSC =16000000; uint32_t RTCOSC =32768; @@ -42,6 +44,7 @@ int bsp_init() } bsp_GPIO_init(); bsp_uart_init(); + bsp_iic_init(); printf("\r================================================================\n\r"); printf("================================================================\n\r"); printf(BSP); @@ -90,7 +93,8 @@ void bsp_spi_init() void bsp_iic_init() { - + if(0==i2copenandconfig(i2c1,0,100000,PB9,PB6))printf("I2C1 opened\n\r"); + i2cenable(i2c1); } void bsp_SD_init() diff --git a/examples/BeagleSynthHello/BeagleSynthHello.pro b/examples/BeagleSynthHello/BeagleSynthHello.pro new file mode 100644 --- /dev/null +++ b/examples/BeagleSynthHello/BeagleSynthHello.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +CONFIG += console +CONFIG -= qt + +#BSP = BEAGLESYNTH +BSP = SOLAR_LFR_PSU +include($$(libuc2)/bsp/cfg/$$BSP/bsp.pri) +#include($$(libuc2)/rules/stm32f4-arm-none-eabi-gcc/rules.pri) + +SOURCES += \ + main.c + diff --git a/examples/BeagleSynthHello/bin/dfu.py b/examples/BeagleSynthHello/bin/dfu.py new file mode 100644 --- /dev/null +++ b/examples/BeagleSynthHello/bin/dfu.py @@ -0,0 +1,121 @@ +#!/usr/bin/python + +# Written by Antonio Galea - 2010/11/18 +# Distributed under Gnu LGPL 3.0 +# see http://www.gnu.org/licenses/lgpl-3.0.txt + +import sys,struct,zlib,os +from optparse import OptionParser + +DEFAULT_DEVICE="0x0483:0xdf11" + +def named(tuple,names): + return dict(zip(names.split(),tuple)) +def consume(fmt,data,names): + n = struct.calcsize(fmt) + return named(struct.unpack(fmt,data[:n]),names),data[n:] +def cstring(string): + return string.split('\0',1)[0] +def compute_crc(data): + return 0xFFFFFFFF & -zlib.crc32(data) -1 + +def parse(file,dump_images=False): + print 'File: "%s"' % file + data = open(file,'rb').read() + crc = compute_crc(data[:-4]) + prefix, data = consume('<5sBIB',data,'signature version size targets') + print '%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix + for t in range(prefix['targets']): + tprefix, data = consume('<6sBI255s2I',data,'signature altsetting named name size elements') + tprefix['num'] = t + if tprefix['named']: + tprefix['name'] = cstring(tprefix['name']) + else: + tprefix['name'] = '' + print '%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix + tsize = tprefix['size'] + target, data = data[:tsize], data[tsize:] + for e in range(tprefix['elements']): + eprefix, target = consume('<2I',target,'address size') + eprefix['num'] = e + print ' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix + esize = eprefix['size'] + image, target = target[:esize], target[esize:] + if dump_images: + out = '%s.target%d.image%d.bin' % (file,t,e) + open(out,'wb').write(image) + print ' DUMPED IMAGE TO "%s"' % out + if len(target): + print "target %d: PARSE ERROR" % t + suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc') + print 'usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix + if crc != suffix['crc']: + print "CRC ERROR: computed crc32 is 0x%08x" % crc + data = data[16:] + if data: + print "PARSE ERROR" + +def build(file,targets,device=DEFAULT_DEVICE): + data = '' + for t,target in enumerate(targets): + tdata = '' + for image in target: + tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data'] + tdata = struct.pack('<6sBI255s2I','Target',0,1,'ST...',len(tdata),len(target)) + tdata + data += tdata + data = struct.pack('<5sBIB','DfuSe',1,len(data)+11,len(targets)) + data + v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1)) + data += struct.pack('<4H3sB',0,d,v,0x011a,'UFD',16) + crc = compute_crc(data) + data += struct.pack(' +#include +#include +#include +#include +#include +#include + + +extern streamdevice* __opnfiles__[]; + +int main() +{ + //gpioset(PSU_DISABLE); + printf("i2C Control register 1 (I2C_CR1) = %x\n\r",I2C1->CR1); + printf("i2C Control register 2 (I2C_CR2) = %x\n\r",I2C1->CR2); + printf("i2C Status register 1 (I2C_SR1) = %x\n\r",I2C1->SR1); + printf("i2C Status register 2 (I2C_SR2) = %x\n\r",I2C1->SR2); + printf("i2C Clock control register (I2C_CCR) = %x\n\r",I2C1->CCR); + while(1) + { + for(volatile int i=0;i<1024*2048;i++); + gpioset(LED1); + gpioclr(LED2); + for(volatile int i=0;i<1024*2048;i++); + gpioclr(LED1); + gpioset(LED2); + i2cwrite(i2c1,0x4a,"test",4); + } + printf("hello world\n\r"); + return 0; +} + + + + + + + + + diff --git a/examples/SOLAR_PSU_HELLO/hello.pro b/examples/SOLAR_PSU_HELLO/hello.pro --- a/examples/SOLAR_PSU_HELLO/hello.pro +++ b/examples/SOLAR_PSU_HELLO/hello.pro @@ -2,7 +2,8 @@ TEMPLATE = app CONFIG += console CONFIG -= qt -BSP = BEAGLESYNTH +#BSP = BEAGLESYNTH +BSP = SOLAR_LFR_PSU include($$(libuc2)/bsp/cfg/$$BSP/bsp.pri) #include($$(libuc2)/rules/stm32f4-arm-none-eabi-gcc/rules.pri) diff --git a/examples/SOLAR_PSU_HELLO/main.c b/examples/SOLAR_PSU_HELLO/main.c --- a/examples/SOLAR_PSU_HELLO/main.c +++ b/examples/SOLAR_PSU_HELLO/main.c @@ -10,7 +10,7 @@ extern streamdevice* __opnfiles__[]; int main() { - gpioset(PSU_DISABLE); + //gpioset(PSU_DISABLE); while(1) { for(volatile int i=0;i<1024*2048;i++); diff --git a/examples/examples.pro b/examples/examples.pro --- a/examples/examples.pro +++ b/examples/examples.pro @@ -3,7 +3,8 @@ CONFIG += ordered SUBDIRS += QtTest/test.pro \ SOLAR_PSU_HELLO/hello.pro \ SDCARD \ - STM32F4IT + STM32F4IT \ + BeagleSynthHello diff --git a/lib/includes/core.h b/lib/includes/core.h --- a/lib/includes/core.h +++ b/lib/includes/core.h @@ -33,8 +33,17 @@ extern "C" { #endif -extern void coresetCpuFreq(unsigned int freq); -extern unsigned int coregetCpuFreq(); +extern uint32_t getAPB1Freq(); +extern uint32_t getAPB2Freq(); +extern uint32_t getCpuFreq(); +extern int setCpuFreq(uint32_t freq); +extern int optimizePLLcfg(uint32_t freq, uint32_t srcfreq,uint32_t PLLM,uint32_t* PLLP, uint32_t* PLLN,uint8_t* AHBPRindx); +extern int setPll(uint32_t freq); +extern void enable_FPU(); +extern void reset_AHB1(); +extern void reset_AHB2(); +extern void reset_APB1(); +extern void reset_APB2(); #ifdef __cplusplus } diff --git a/lib/includes/i2c.h b/lib/includes/i2c.h new file mode 100644 --- /dev/null +++ b/lib/includes/i2c.h @@ -0,0 +1,71 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the libuc, microcontroler library +-- Copyright (C) 2012, 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 +-------------------------------------------------------------------------------*/ +#ifndef I2C_H +#define I2C_H +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +typedef int i2c_t; + +#define i2c1 0 +#define i2c2 1 +#define i2c3 2 +#define i2c4 3 +#define i2c5 4 +#define i2c6 5 +#define i2c7 6 +#define i2c8 7 +#define i2c9 8 + +extern i2c_t i2copen(int count); +extern i2c_t i2copenandconfig(int count ,uint32_t cfg,uint32_t speed,uint32_t SDA,uint32_t SCL); +extern int i2cclose(i2c_t dev); +extern int i2csetpins(i2c_t dev,uint32_t SDA,uint32_t SCL); +extern int i2cenable(i2c_t dev); +extern int i2cdisable(i2c_t dev); +//extern int i2csetconfig(i2c_t dev); +extern int i2csetspeed(i2c_t dev,uint32_t speed); +//extern int i2csetdatabits(i2c_t* dev,uartbits_t databits); +extern int i2cwrite(i2c_t dev,char address,char* data,int count); +extern int i2cread(i2c_t dev,char address,char* data,int count); + +#ifdef __cplusplus + } +#endif +#endif //I2C_H + + + + + + + + + + + + diff --git a/lib/src/stm32f4/CORE/core.c b/lib/src/stm32f4/CORE/core.c --- a/lib/src/stm32f4/CORE/core.c +++ b/lib/src/stm32f4/CORE/core.c @@ -21,25 +21,305 @@ -------------------------------------------------------------------------------*/ #include "core.h" #include +#include +#include +#include -//extern uint32_t OSC0; +extern uint32_t OSC0; extern uint32_t INTOSC; extern uint32_t RTCOSC; -void coresetCpuFreq(unsigned int freq) + +uint32_t getAPB1Freq() { + 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; +} +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; } +/* + | 2.7->3.6V +------------------------- + 0WS | 062) && ((*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) { - RCC_ClocksTypeDef RCC_ClocksStatus; - RCC_GetClocksFreq(&RCC_ClocksStatus); - return RCC_ClocksStatus.SYSCLK_Frequency; + 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; + /* Wait till the main PLL is used as system clock source */ + 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; +} + +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<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<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"); } @@ -47,13 +327,3 @@ unsigned int coregetCpuFreq() - - - - - - - - - - diff --git a/lib/src/stm32f4/CPU/stm32f4xxxG/cpuinit.c b/lib/src/stm32f4/CPU/stm32f4xxxG/cpuinit.c --- a/lib/src/stm32f4/CPU/stm32f4xxxG/cpuinit.c +++ b/lib/src/stm32f4/CPU/stm32f4xxxG/cpuinit.c @@ -4,288 +4,10 @@ #include #include #include - -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; -} - - - -uint32_t getCpuFreq() -{ - extern uint32_t OSC0; - extern uint32_t INTOSC; - 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; -} - - -/* - | 2.7->3.6V -------------------------- - 0WS | 062) && ((*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; -} +#include +extern int main(); -int setPll(uint32_t freq) -{ - 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; - /* Wait till the main PLL is used as system clock source */ - 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; -} - -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<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<CFGR &= ~(0xF<<4); - RCC->CFGR |= ((0x8|i)<<4); - return freq; - } - } - } - else - return setPll(freq); - } - } - return 0; -} - -#include -extern int main(); - -inline void enable_FPU() -{ - SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ - __asm__("dsb"); - __asm__("isb"); -} void cpu_init() { diff --git a/lib/src/stm32f4/I2C/i2c.c b/lib/src/stm32f4/I2C/i2c.c new file mode 100644 --- /dev/null +++ b/lib/src/stm32f4/I2C/i2c.c @@ -0,0 +1,246 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the libuc, microcontroler library +-- Copyright (C) 2012, 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 +-------------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include + +#define GPIOGETPORT(gpio) ((GPIO_TypeDef*)(((((uint32_t)gpio) & (uint32_t)0x0000FF00)*(uint32_t)4) + (uint32_t)GPIOA)) +#define GPIOPORTNUM(gpio) (((uint32_t)(gpio) & (uint32_t)0x0000FF00)>>(uint32_t)8) + + +I2C_TypeDef* _i2c_dev_table[3]={I2C1,I2C2,I2C3}; + +i2c_t i2copen(int count) +{ +#define _INIT_DEV(_RCC_) \ + RCC_APB1PeriphClockCmd(_RCC_, ENABLE); \ + RCC_APB1PeriphResetCmd(_RCC_, ENABLE); \ + RCC_APB1PeriphResetCmd(_RCC_, DISABLE); \ + RCC_APB1PeriphClockCmd(_RCC_, ENABLE); + + switch(count) + { + case 0: + _INIT_DEV(RCC_APB1Periph_I2C1); + return (i2c_t) 0; + break; + case 1: + _INIT_DEV(RCC_APB1Periph_I2C2); + return (i2c_t) 1; + break; + case 2: + _INIT_DEV(RCC_APB1Periph_I2C3); + return (i2c_t) 2; + break; + default: + break; + } + return -1; +} + +i2c_t i2copenandconfig(int count,uint32_t cfg,uint32_t speed,uint32_t SDA,uint32_t SCL) +{ + i2c_t dev = i2copen(count); + printf("dev = %d\n\r",dev); + if(dev!=-1) + { + i2cenable(count); + I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev]; + _dev_->CR1 = (1<<15); + _dev_->CR1 &=~(1<<15); + i2cdisable(count); + i2csetpins(dev,SDA,SCL); + i2csetspeed(dev,speed); + i2cenable(count); + } + return dev; +} + +int i2cclose(i2c_t dev) +{ + switch((int)dev) + { + case (int)0: + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); + break; + case (int)1: + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); + break; + case (int)2: + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C3, ENABLE); + break; + default: + break; + } + return 1; +} + +int i2csetpins(i2c_t dev, uint32_t SDA, uint32_t SCL) +{ + if((dev<3)&&(dev>=0)) + { + gpio_t SDApin,SCLpin; + SDApin = gpioopen(SDA); + SCLpin = gpioopen(SCL); + SDApin |= gpiolowspeed | gpioaf | gpioopendraintype | gpionopulltype; + SCLpin |= gpiolowspeed | gpioaf | gpioopendraintype | gpionopulltype; + gpiosetconfig(&SDApin); + gpiosetconfig(&SCLpin); + uint8_t gpioAFi2cx = GPIO_AF_I2C1; + switch((int)dev) + { + case 0: + gpioAFi2cx = GPIO_AF_I2C1; + break; + case 1: + gpioAFi2cx = GPIO_AF_I2C2; + break; + case 2: + gpioAFi2cx = GPIO_AF_I2C3; + break; + default: + break; + } + GPIO_PinAFConfig(GPIOGETPORT(SDApin), (uint8_t)(SDApin & 0xF), gpioAFi2cx); + GPIO_PinAFConfig(GPIOGETPORT(SCLpin), (uint8_t)(SCLpin & 0xF), gpioAFi2cx); + return 0; + } + return -1; +} + +int i2cenable(i2c_t dev) +{ + if((dev<3)&&(dev>=0)) + { + I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev]; + _dev_->CR1 |=1 ; + return 0; + } + return -1; +} + +int i2cdisable(i2c_t dev) +{ + if((dev<3)&&(dev>=0)) + { + I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev]; + _dev_->CR1 &= ~1; + return 0; + } + return -1; +} + + +int i2csetspeed(i2c_t dev,uint32_t speed) +{ + if((dev<3)&&(dev>=0)) + { + I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev]; + int32_t APB1Freq=getAPB1Freq()/1000000; + if((APB1Freq>1)&&(APB1Freq<43)) + { + int enabled=((_dev_->CR1&1)==1); + i2cdisable(dev); + _dev_->CR2 &= ~(0x1f); + _dev_->CR2 |= APB1Freq; + if(speed>100000) //100kHz= standard mode, 400kHz= fast mode + { + if(speed<=400000) + { + _dev_->CCR |= 1<<15; + _dev_->CCR &= ~(1<<14); + _dev_->CCR &= ~(0xfff); + _dev_->CCR |= 0xfff & (APB1Freq/(3*speed)); + } + } + else + { + _dev_->CCR &= ~(1<<15); + _dev_->CCR &= ~(0xfff); + _dev_->CCR |= 0xfff & (APB1Freq/(2*speed)); + } + if(enabled)i2cenable(dev); + return 0; + } + } + return -1; +} + +int i2cwrite(i2c_t dev,char address,char* data,int count) +{ + if((dev<3)&&(dev>=0)) + { + I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev]; + _dev_->CR1 |= 1<<8; + while((_dev_->SR1&1)==0); + _dev_->DR= address<<1; + while((_dev_->SR1 & (1<<3))==0); + address=_dev_->SR2; + for(int i=0;iSR1 & (1<<7))==0); + _dev_->DR= data[i]; + } + while((_dev_->SR1 & (1<<7))==0); + while((_dev_->SR1 & (1<<2))==0); + _dev_->CR1 |= 1<<9; + return count; + } + return -1; +} + +int i2cread(i2c_t dev,char address,char* data,int count) +{ + if((dev<3)&&(dev>=0)) + { + I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev]; + _dev_->CR1 |= (1<<8) | (1<<10); + if(count==1) + { + _dev_->CR1 &= ~(1<<10); + } + while((_dev_->SR1&1)==0); + _dev_->DR= (address<<1) + 1; + while((_dev_->SR1 & (1<<3))==0); + address=_dev_->SR2; + for(int i=0;iSR1 & (1<<6))==0); + data[i]=_dev_->DR; + } + _dev_->CR1 &= ~(1<<10); + _dev_->CR1 |= 1<<9; + while((_dev_->SR1 & (1<<6))==0); + data[count-1]=_dev_->DR; + return count; + } + return -1; +} + + + + + diff --git a/lib/src/stm32f4/I2C/i2c.pro b/lib/src/stm32f4/I2C/i2c.pro new file mode 100644 --- /dev/null +++ b/lib/src/stm32f4/I2C/i2c.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += console +CONFIG -= qt +include($$(libuc2)/rules/stm32f4-arm-none-eabi-gcc/rules.pri) + +SOURCES += \ + i2c.c + + +HEADERS += \ + $$(libuc2)/lib/includes/i2c.h + + diff --git a/lib/src/stm32f4/UART/uart.c b/lib/src/stm32f4/UART/uart.c --- a/lib/src/stm32f4/UART/uart.c +++ b/lib/src/stm32f4/UART/uart.c @@ -165,7 +165,7 @@ int uartsetpins(uart_t* uart,uint32_t TX break; } GPIO_PinAFConfig(GPIOGETPORT(TX), (uint8_t)(TX & 0xF), gpioAFuartx); - GPIO_PinAFConfig(GPIOGETPORT(TX), (uint8_t)(RX & 0xF), gpioAFuartx); + GPIO_PinAFConfig(GPIOGETPORT(RX), (uint8_t)(RX & 0xF), gpioAFuartx); if((gpioAFuartx!=GPIO_AF_UART5) && (gpioAFuartx!=GPIO_AF_UART4)) { if(CTSpin!=-1) diff --git a/lib/src/stm32f4/stm32f4.pro b/lib/src/stm32f4/stm32f4.pro --- a/lib/src/stm32f4/stm32f4.pro +++ b/lib/src/stm32f4/stm32f4.pro @@ -4,7 +4,8 @@ SUBDIRS = CORE/core.pro \ CPU/cpu.pro \ GPIO/gpio.pro \ UART/uart.pro \ - SPI/spi.pro + SPI/spi.pro \ + I2C/i2c.pro diff --git a/rules/common/librules.pri b/rules/common/librules.pri --- a/rules/common/librules.pri +++ b/rules/common/librules.pri @@ -8,7 +8,6 @@ INCLUDEPATH += $$LIBUC_LIBS_DIR/includes LIBUC_BIN_LIBS_DIR = $$LIBUC_LIBS_DIR/bin/$$ARCH - LIBS += -L$$LIBUC_LIBS_DIR/bin/$$ARCH \ -lsdcard @@ -22,6 +21,9 @@ LIBS += -L$$LIBUC_LIBS_DIR/bin/$$ARCH \ -luart LIBS += -L$$LIBUC_LIBS_DIR/bin/$$ARCH \ + -li2c + +LIBS += -L$$LIBUC_LIBS_DIR/bin/$$ARCH \ -lgpio LIBS += -L$$LIBUC_LIBS_DIR/bin/$$ARCH \ @@ -30,6 +32,9 @@ LIBS += -L$$LIBUC_LIBS_DIR/bin/$$ARCH \ LIBS += -L$$LIBUC_LIBS_DIR/bin/$$ARCH \ -lcpu +LIBS += -L$$LIBUC_LIBS_DIR/bin/$$ARCH \ + -lcore +