##// END OF EJS Templates
Removed error on fat32 library, seems now to be able navigate among sectors in...
Removed error on fat32 library, seems now to be able navigate among sectors in both directions. Improved SDLCD drawing performances by almost 1000x.

File last commit:

r64:b702edc52366 dev_alexis
r68:104125d87b89 dev_alexis
Show More
i2c.c
386 lines | 10.2 KiB | text/x-c | CLexer
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 /*------------------------------------------------------------------------------
-- 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
Jeandet Alexis
sync
r64 -- Mail : alexis.jeandet@member.fsf.org
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 -------------------------------------------------------------------------------*/
#include <i2c.h>
#include <stm32f4xx_usart.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_gpio.h>
#include <gpio.h>
#include <core.h>
#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)
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 int i2ctimeout=1000*1000;
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22
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); \
Corrected bug #591
r56 RCC_APB1PeriphResetCmd(_RCC_, DISABLE);
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22
switch(count)
{
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 case i2c1:
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 _INIT_DEV(RCC_APB1Periph_I2C1);
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 return i2c1;
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 break;
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 case i2c2:
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 _INIT_DEV(RCC_APB1Periph_I2C2);
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 return i2c2;
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 break;
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 case i2c3:
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 _INIT_DEV(RCC_APB1Periph_I2C3);
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 return i2c3;
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 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);
if(dev!=-1)
{
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r24 i2cclose(dev);
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 i2csetpins(dev,SDA,SCL);
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r24 i2copen(count);
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 i2csetspeed(dev,speed);
i2cenable(count);
}
return dev;
}
int i2cclose(i2c_t dev)
{
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 switch(dev)
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 {
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 case i2c1:
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
break;
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 case i2c2:
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
break;
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 case i2c3:
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C3, ENABLE);
break;
default:
break;
}
return 1;
}
int i2csetpins(i2c_t dev, uint32_t SDA, uint32_t SCL)
{
Corrected bug #591
r56 if((dev<i2c4)&&(dev>=i2c1))
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 {
gpio_t SDApin,SCLpin;
SDApin = gpioopen(SDA);
SCLpin = gpioopen(SCL);
SDApin |= gpiolowspeed | gpioaf | gpioopendraintype | gpionopulltype;
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 SCLpin |= gpiolowspeed | gpiooutdir | gpioopendraintype | gpionopulltype;
gpiosetconfig(&SCLpin);
for(int i=0;i<32;i++)
{
gpioclr(SCLpin);
for(int l=0;l<200;l++)
{__asm__("nop");}
gpioset(SCLpin);
for(int l=0;l<200;l++)
{__asm__("nop");}
}
SCLpin = gpioopen(SCL);
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 SCLpin |= gpiolowspeed | gpioaf | gpioopendraintype | gpionopulltype;
gpiosetconfig(&SDApin);
gpiosetconfig(&SCLpin);
uint8_t gpioAFi2cx = GPIO_AF_I2C1;
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 switch(dev)
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 {
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 case i2c1:
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 gpioAFi2cx = GPIO_AF_I2C1;
break;
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 case i2c2:
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 gpioAFi2cx = GPIO_AF_I2C2;
break;
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 case i2c3:
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 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)
{
Corrected bug #591
r56 if((dev<i2c4)&&(dev>=i2c1))
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 {
I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev];
_dev_->CR1 |=1 ;
return 0;
}
return -1;
}
int i2cdisable(i2c_t dev)
{
Corrected bug #591
r56 if((dev<i2c4)&&(dev>=i2c1))
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 {
I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev];
_dev_->CR1 &= ~1;
return 0;
}
return -1;
}
int i2csetspeed(i2c_t dev,uint32_t speed)
{
Corrected bug #591
r56 if((dev<i2c4)&&(dev>=i2c1))
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 {
I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev];
int32_t APB1Freq=getAPB1Freq()/1000000;
if((APB1Freq>1)&&(APB1Freq<43))
{
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r24
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r23 uint16_t tmpreg=_dev_->CR2;
tmpreg &= ~(0x1f);
tmpreg |= APB1Freq;
_dev_->CR2=tmpreg;
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r24 i2cdisable(dev);
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r23 tmpreg=_dev_->CCR;
APB1Freq=getAPB1Freq();
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 if(speed>100000) //100kHz= standard mode, 400kHz= fast mode
{
if(speed<=400000)
{
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r23 tmpreg |= 1<<15;
tmpreg &= ~(1<<14);
tmpreg &= ~(0xfff);
tmpreg |= 0xfff & (APB1Freq/(3*speed));
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 }
}
else
{
Corrected bug #591
r56 tmpreg &= ~(1<<15);
tmpreg &= ~(0xfff);
tmpreg |= 0xfff & (APB1Freq/(2*speed));
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 }
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r23 _dev_->CCR=tmpreg;
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r24 tmpreg=_dev_->TRISE;
tmpreg &= ~(0x3f);
tmpreg |= (APB1Freq/1000000)+1;
_dev_->TRISE = tmpreg;
i2cenable(dev);
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 return 0;
}
}
return -1;
}
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r24 int i2cbusy(i2c_t dev)
{
Corrected bug #591
r56 if((dev<i2c4)&&(dev>=i2c1))
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r24 {
I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev];
if((_dev_->SR2 & 2) ==2) return 1; /* Dev is busy */
return 0; /* Dev isn't busy */
}
return -1; /* Error, dev is out of range */
}
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 int i2cwrite(i2c_t dev,char address,char* data,int count)
{
Corrected bug #591
r56 if((dev<i2c4)&&(dev>=i2c1))
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 {
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 int timeout=i2ctimeout;
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev];
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 while(i2cbusy(dev))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 _dev_->CR1 |= 1<<8;
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 timeout=i2ctimeout;
while(!i2cStatusCheck(dev,((uint32_t)0x00030001)))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 _dev_->DR= address<<1;
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 timeout=i2ctimeout;
while(!i2cStatusCheck(dev, ((uint32_t)0x00070082)))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 address=_dev_->SR2;
for(int i=0;i<count;i++)
{
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 timeout=i2ctimeout;
while(!i2cStatusCheck(dev,((uint32_t)0x00070080)))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 _dev_->DR= data[i];
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 timeout=i2ctimeout;
while(!i2cStatusCheck(dev,1<<7))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
timeout=i2ctimeout;
while(!i2cStatusCheck(dev,1<<2))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 _dev_->CR1 |= 1<<9;
return count;
}
return -1;
}
int i2cread(i2c_t dev,char address,char* data,int count)
{
Corrected bug #591
r56 if((dev<i2c4)&&(dev>=i2c1))
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 {
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r28 int i=0;
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 int timeout=i2ctimeout;
while(i2cbusy(dev))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev];
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r28 _dev_->CR1 |= (1<<8) + (1<<10);
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 timeout=i2ctimeout;
while(!i2cStatusCheck(dev,0x00030001))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 _dev_->DR= (address<<1) + 1;
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 while(!i2cStatusCheck(dev,0x000002))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 if(count==1)
{
_dev_->CR1 &= ~(1<<10);
}
address=_dev_->SR2;
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r28 for(i=0;i<(count-1);i++)
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 {
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 timeout=i2ctimeout;
while(!i2cStatusCheck(dev,0x0000040))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 data[i]=_dev_->DR;
}
_dev_->CR1 &= ~(1<<10);
_dev_->CR1 |= 1<<9;
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 timeout=i2ctimeout;
while(!i2cStatusCheck(dev,0x0000040))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r28 data[i]=_dev_->DR;
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 timeout=i2ctimeout;
while(_dev_->CR1 & ((uint16_t)0x0200))
{
Corrected bug #591
r56 if(0==(timeout--))
{
printf("Exited on timeout @ line %d\n\r",__LINE__);
return -1;
}
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
I2C library partially validated, ina226 library partially validated.
r30 }
jeandet@PC-DE-JEANDET.lab-lpp.local
Sync
r27 _dev_->CR1 |= 1<<10;
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22 return count;
}
return -1;
}
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r24 int i2cStatusCheck(i2c_t dev,int32_t flagMask)
{
int32_t flag;
Corrected bug #591
r56 if((dev<i2c4)&&(dev>=i2c1))
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r24 {
I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev];
flag= _dev_->SR1 + (_dev_->SR2<<16);
if(flagMask==(flag & flagMask))
return 1;
return 0;
}
return -1;
}
jeandet@PC-DE-JEANDET.lab-lpp.local
sync
r22