##// END OF EJS Templates
Added ARM CMSIS for fast math and circle drawing function for ili9328 driver.
Added ARM CMSIS for fast math and circle drawing function for ili9328 driver.

File last commit:

r30:62c112128e59 default
r41:27c5438a4566 dev_alexis
Show More
i2c.c
341 lines | 8.9 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
-- Mail : alexis.jeandet@gmail.com
-------------------------------------------------------------------------------*/
#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); \
RCC_APB1PeriphResetCmd(_RCC_, DISABLE); \
RCC_APB1PeriphClockCmd(_RCC_, ENABLE);
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);
i2cenable(count);
//I2C_TypeDef* _dev_ = _i2c_dev_table[(int)dev];
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)
{
if((dev<3)&&(dev>=0))
{
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)
{
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))
{
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
{
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
sync
r23 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)
{
if((dev<3)&&(dev>=0))
{
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)
{
if((dev<3)&&(dev>=0))
{
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))
{
if(0==(timeout--))return -1;
}
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)))
{
if(0==(timeout--))return -1;
}
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)))
{
if(0==(timeout--))return -1;
}
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)))
{
if(0==(timeout--))return -1;
}
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))
{
if(0==(timeout--))return -1;
}
timeout=i2ctimeout;
while(!i2cStatusCheck(dev,1<<2))
{
if(0==(timeout--))return -1;
}
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)
{
if((dev<3)&&(dev>=0))
{
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))
{
if(0==(timeout--))return -1;
}
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))
{
if(0==(timeout--))return -1;
}
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))
{
if(0==(timeout--))return -1;
}
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))
{
if(0==(timeout--))return -1;
}
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))
{
if(0==(timeout--))return -1;
}
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))
{
if(0==(timeout--))return -1;
}
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;
if((dev<3)&&(dev>=0))
{
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