STS-TMG/STM32CubeIDE/Application/User/mlx90640/MLX90640_SWI2C_Driver.cpp

355 lines
6.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @copyright (C) 2017 Melexis N.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/**
* As the timings depend heavily on the MCU in use, it is recommended
* to make sure that the proper timings are achieved. For that purpose
* an oscilloscope might be needed to strobe the SCL and SDA signals.
* The Wait(int) function could be modified in order to better
* trim the frequency. For coarse setting of the frequency or
* dynamic frequency change using the default function implementation,
* freqCnt argument should be changed lower value results in
* higher frequency.
*/
#if 0
#include "MLX90640_I2C_Driver.h"
#include "main.h"
#define SCL_HIGH HAL_GPIO_WritePin(SWI2C_SCL_GPIO_Port,SWI2C_SCL_Pin,GPIO_PIN_SET)
#define SCL_LOW HAL_GPIO_WritePin(SWI2C_SCL_GPIO_Port,SWI2C_SCL_Pin,GPIO_PIN_RESET)
#define SDA_HIGH HAL_GPIO_WritePin(SWI2C_SDA_GPIO_Port,SWI2C_SDA_Pin,GPIO_PIN_SET)
#define SDA_LOW HAL_GPIO_WritePin(SWI2C_SDA_GPIO_Port,SWI2C_SDA_Pin,GPIO_PIN_RESET)
#define SDA_IN {SWI2C_SDA_GPIO_Port->MODER&=~(3<<(7*2));SWI2C_SDA_GPIO_Port->MODER|=0<<7*2;}
#define SDA_OUT {SWI2C_SDA_GPIO_Port->MODER&=~(3<<(7*2));SWI2C_SDA_GPIO_Port->MODER|=1<<7*2;}
#define sda HAL_GPIO_ReadPin(SWI2C_SDA_GPIO_Port,SWI2C_SDA_Pin)
int I2CSendByte(int8_t);
void I2CReadBytes(int, char *);
void I2CStart(void);
void I2CStop(void);
void I2CRepeatedStart(void);
void I2CSendACK(void);
void I2CSendNack(void);
int I2CReceiveAck(void);
void Wait(int);
static int freqCnt = 8;
void MLX90640_I2CInit()
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pins : PB6 SCL */
GPIO_Initure.Pin = SWI2C_SCL_Pin;
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SWI2C_SCL_GPIO_Port, &GPIO_Initure);
/*Configure GPIO pins : PB7 SDA*/
GPIO_Initure.Pin = SWI2C_SDA_Pin;
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SWI2C_SDA_GPIO_Port, &GPIO_Initure);
HAL_GPIO_WritePin(SWI2C_SDA_GPIO_Port, SWI2C_SDA_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(SWI2C_SCL_GPIO_Port, SWI2C_SCL_Pin, GPIO_PIN_SET);
I2CStop();
}
int MLX90640_I2CRead(uint8_t slaveAddr, uint16_t startAddress,uint16_t nMemAddressRead, uint16_t *data)
{
uint8_t sa;
int ack = 0;
int cnt = 0;
int i = 0;
char cmd[2] = {0,0};
char i2cData[1664] = {0};
uint16_t *p;
p = data;
sa = (slaveAddr << 1);
cmd[0] = startAddress >> 8;
cmd[1] = startAddress & 0x00FF;
I2CStop();
Wait(freqCnt);
I2CStart();
Wait(freqCnt);
ack = I2CSendByte(sa)!=0;
if(ack != 0)
{
return -1;
}
ack = I2CSendByte(cmd[0])!=0;
if(ack != 0)
{
return -1;
}
ack = I2CSendByte(cmd[1])!=0;
if(ack != 0)
{
return -1;
}
I2CRepeatedStart();
sa = sa | 0x01;
ack = I2CSendByte(sa);
if(ack != 0)
{
return -1;
}
I2CReadBytes((nMemAddressRead << 1), i2cData);
I2CStop();
for(cnt=0; cnt < nMemAddressRead; cnt++)
{
i = cnt << 1;
*p++ = (int)i2cData[i]*256 + (int)i2cData[i+1];
}
return 0;
}
void MLX90640_I2CFreqSet(int freq)
{
freqCnt = freq>>1;
}
int MLX90640_I2CWrite(uint8_t slaveAddr, uint16_t writeAddress, uint16_t data)
{
uint8_t sa;
int ack = 0;
char cmd[4] = {0,0,0,0};
static uint16_t dataCheck;
sa = (slaveAddr << 1);
cmd[0] = writeAddress >> 8;
cmd[1] = writeAddress & 0x00FF;
cmd[2] = data >> 8;
cmd[3] = data & 0x00FF;
I2CStop();
Wait(freqCnt);
I2CStart();
ack = I2CSendByte(sa);
if (ack != 0x00)
{
return 1;
}
for(int i = 0; i<4; i++)
{
ack = I2CSendByte(cmd[i]);
if (ack != 0x00)
{
return -1;
}
}
I2CStop();
MLX90640_I2CRead(slaveAddr,writeAddress,1, &dataCheck);
if ( dataCheck != data)
{
return -2;
}
return 0;
}
int I2CSendByte(int8_t data)
{
int ack = 1;
int8_t byte = data;
for(int i=0;i<8;i++)
{
Wait(freqCnt);
if(byte & 0x80)
{
SDA_HIGH;
}
else
{
SDA_LOW;
}
Wait(freqCnt);
SCL_HIGH;
Wait(freqCnt);
Wait(freqCnt);
SCL_LOW;
byte = byte<<1;
}
Wait(freqCnt);
ack = I2CReceiveAck();
return ack;
}
void I2CReadBytes(int nBytes, char *dataP)
{
char data;
for(int j=0;j<nBytes;j++)
{
Wait(freqCnt);
SDA_HIGH;
data = 0;
for(int i=0;i<8;i++){
Wait(freqCnt);
SCL_HIGH;
Wait(freqCnt);
data = data<<1;
if(sda == 1){
data = data+1;
}
Wait(freqCnt);
SCL_LOW;
Wait(freqCnt);
}
if(j == (nBytes-1))
{
I2CSendNack();
}
else
{
I2CSendACK();
}
*(dataP+j) = data;
}
}
void Wait(int freqCnt)
{
int cnt;
// for(int i = 0;i<freqCnt;i++)
// {
// cnt = cnt++;
// }
while(freqCnt--)
for(cnt=20;cnt>0;cnt--);
}
void I2CStart(void)
{
SDA_HIGH;
SCL_HIGH;
Wait(freqCnt);
Wait(freqCnt);
SDA_LOW;
Wait(freqCnt);
SCL_LOW;
Wait(freqCnt);
}
void I2CStop(void)
{
SCL_LOW;
SDA_LOW;
Wait(freqCnt);
SCL_HIGH;
Wait(freqCnt);
SDA_HIGH;
Wait(freqCnt);
}
void I2CRepeatedStart(void)
{
SCL_LOW;
Wait(freqCnt);
SDA_HIGH;
Wait(freqCnt);
SCL_HIGH;
Wait(freqCnt);
SDA_LOW;
Wait(freqCnt);
SCL_LOW;
}
void I2CSendACK(void)
{
SDA_LOW;
Wait(freqCnt);
SCL_HIGH;
Wait(freqCnt);
Wait(freqCnt);
SCL_LOW;
Wait(freqCnt);
SDA_HIGH;
}
void I2CSendNack(void)
{
SDA_HIGH;
Wait(freqCnt);
SCL_HIGH;
Wait(freqCnt);
Wait(freqCnt);
SCL_LOW;
Wait(freqCnt);
SDA_HIGH;
}
int I2CReceiveAck(void)
{
int ack;
SDA_HIGH;
Wait(freqCnt);
SCL_HIGH;
Wait(freqCnt);
if(sda == 0)
{
ack = 0;
}
else
{
ack = 1;
}
Wait(freqCnt);
SCL_LOW;
SDA_LOW;
return ack;
}
#endif