You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
6.7 KiB
C

#include "SWM221.h"
#include "IOI2C_MST.h"
static char TxBuff[128] = {0};
static uint32_t TxSize = 0;
static volatile uint32_t TxIndx = 0;
static char *RxBuff = 0;
static uint32_t RxSize = 0;
static volatile uint32_t RxIndx = 0;
static volatile uint32_t BitTim = 0;
static volatile uint32_t IsRead = 0;
static volatile uint32_t IsBusy = 0;
static void (*IOI2C_MST_Func)(void);
static void IOI2C_MST_Start(void);
static void IOI2C_MST_SendByte(void);
static void IOI2C_MST_ReadByte(void);
static void IOI2C_MST_Stop(void);
static void delayuS(uint32_t dly) { uint32_t i; for(i = 0; i < SystemCoreClock/1000000 * dly; i++) __NOP(); }
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: IOI2C_MST_Init()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: IOI2C<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: uint32_t baud IOI2C<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><EFBFBD><EFBFBD>λbps
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
void IOI2C_MST_Init(uint32_t baud)
{
#define IOI2C_PORT GPIOA
#define IOI2C_SCL PIN2
#define IOI2C_SDA PIN3
#define IOI2C_TMR BTIMR0
#define IOI2C_ISR BTIMR0_Handler
GPIO_Init(IOI2C_PORT, IOI2C_SCL, 1, 0, 0, 0);
#define I2C_SCL_LOW() { GPIO_ClrBit(IOI2C_PORT, IOI2C_SCL); delayuS(1); }
#define I2C_SCL_HIGH() { GPIO_SetBit(IOI2C_PORT, IOI2C_SCL); delayuS(1); }
GPIO_Init(IOI2C_PORT, IOI2C_SDA, 0, 1, 0, 1);
#define I2C_SDA_OUTPUT() IOI2C_PORT->DIR |= (1 << IOI2C_SDA);
#define I2C_SDA_LOW() GPIO_ClrBit(IOI2C_PORT, IOI2C_SDA)
#define I2C_SDA_HIGH() GPIO_SetBit(IOI2C_PORT, IOI2C_SDA)
#define I2C_SDA_INPUT() IOI2C_PORT->DIR &=~(1 << IOI2C_SDA)
#define I2C_SDA_Value() GPIO_GetBit(IOI2C_PORT, IOI2C_SDA)
I2C_SDA_HIGH();
I2C_SCL_HIGH();
TIMR_Init(IOI2C_TMR, TIMR_MODE_TIMER, 10, SystemCoreClock/10/(baud*2), 1); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊbaud<75><64><EFBFBD><EFBFBD>ʱ<EFBFBD>ӷ<EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>Ϊbaud*2
NVIC_SetPriority(BTIMR0_IRQn, 3); // <20><>I2C<32><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD>õıȴӻ<C8B4><D3BB>ͣ<EFBFBD><CDA3><EFBFBD>Ϊ<EFBFBD>ӻ<EFBFBD><D3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><E1B7B5>NAK
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: IOI2C_MST_Send()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: IOI2C<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: char slvaddr <EFBFBD>ӻ<EFBFBD><EFBFBD><EFBFBD>ַ
* char buff[] Ҫ<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* uint32_t size Ҫ<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>128<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> IOI2C_MST_IsBusy() == 0 ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
******************************************************************************************************************************************/
void IOI2C_MST_Send(char slvaddr, char buff[], uint32_t size)
{
uint32_t i;
TxBuff[0] = (slvaddr << 1) | 0;
for(i = 1; i <= size; i++)
TxBuff[i] = buff[i-1];
TxSize = i;
TxIndx = 0;
BitTim = 0;
IsRead = 0;
IsBusy = 1;
IOI2C_MST_Func = IOI2C_MST_Start;
TIMR_Start(IOI2C_TMR);
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: IOI2C_MST_Read()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: IOI2C<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: char slvaddr <EFBFBD>ӻ<EFBFBD><EFBFBD><EFBFBD>ַ
* char buff[] <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* uint32_t size Ҫ<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>128<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> IOI2C_MST_IsBusy() == 0 ʱ<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٴ<EFBFBD> IOI2C_MST_IsBusy() == 0 ʱ<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>buff[]<EFBFBD><EFBFBD>
******************************************************************************************************************************************/
void IOI2C_MST_Read(char slvaddr, char buff[], uint32_t size)
{
uint32_t i;
TxBuff[0] = (slvaddr << 1) | 1;
for(i = 1; i <= size; i++)
TxBuff[i] = buff[i-1];
TxSize = i;
TxIndx = 0;
RxBuff = buff;
for(i = 0; i < size; i++)
RxBuff[i] = 0;
RxSize = i;
RxIndx = 0;
BitTim = 0;
IsRead = 1;
IsBusy = 1;
IOI2C_MST_Func = IOI2C_MST_Start;
TIMR_Start(IOI2C_TMR);
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: IOI2C_MST_IsBusy()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: IOI2C<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: uint32_t 1 IOI2C<EFBFBD><EFBFBD>æ<EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0 IOI2C<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD><EFBFBD>µķ<EFBFBD><EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
uint32_t IOI2C_MST_IsBusy(void)
{
return IsBusy;
}
static void IOI2C_MST_Start(void)
{
I2C_SDA_LOW();
IOI2C_MST_Func = IOI2C_MST_SendByte;
}
static void IOI2C_MST_SendByte(void)
{
if(BitTim < 16)
{
if((BitTim % 2) == 0)
{
I2C_SCL_LOW();
if(BitTim == 0) I2C_SDA_OUTPUT(); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD>ʱ<EFBFBD>ὫSDA<44>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD>ACK
if(TxBuff[TxIndx] & (1 << (7 - BitTim/2)))
I2C_SDA_HIGH();
else
I2C_SDA_LOW();
}
else
{
I2C_SCL_HIGH();
}
}
else if(BitTim == 16)
{
I2C_SCL_LOW();
I2C_SDA_INPUT();
}
else if(BitTim == 17)
{
I2C_SCL_HIGH();
}
else
{
if(I2C_SDA_Value()) //NACK
{
IOI2C_MST_Func = IOI2C_MST_Stop;
}
else if((TxIndx == 0) && IsRead)
{
IOI2C_MST_Func = IOI2C_MST_ReadByte;
}
else
{
if(++TxIndx == TxSize)
{
IOI2C_MST_Func = IOI2C_MST_Stop;
}
}
BitTim = 0;
goto noinc;
}
BitTim++;
noinc:
;
}
static void IOI2C_MST_ReadByte(void)
{
if(BitTim < 16)
{
if((BitTim % 2) == 0)
{
I2C_SCL_LOW();
if(BitTim == 0) I2C_SDA_INPUT(); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD>ʱ<EFBFBD>ὫSDA<44>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><D4B7><EFBFBD>ACK
}
else
{
I2C_SCL_HIGH();
RxBuff[RxIndx] |= I2C_SDA_Value() << (7 - BitTim/2);
}
}
else if(BitTim == 16)
{
I2C_SCL_LOW();
I2C_SDA_OUTPUT();
if(++RxIndx < RxSize)
{
I2C_SDA_LOW();
}
else
{
I2C_SDA_HIGH();
}
}
else if(BitTim == 17)
{
I2C_SCL_HIGH();
}
else
{
if(RxIndx == RxSize)
{
IOI2C_MST_Func = IOI2C_MST_Stop;
}
BitTim = 0;
goto noinc;
}
BitTim++;
noinc:
;
}
static void IOI2C_MST_Stop(void)
{
if(BitTim == 0)
{
I2C_SCL_LOW();
I2C_SDA_LOW();
I2C_SDA_OUTPUT(); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD>ʱ<EFBFBD>ὫSDA<44>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD>ACK
}
else
{
I2C_SCL_HIGH();
I2C_SDA_HIGH();
IsBusy = 0;
TIMR_Stop(IOI2C_TMR);
}
BitTim++;
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: IOI2C_ISR()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: TIMER<EFBFBD>жϷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><EFBFBD>SCLʱ<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
void IOI2C_ISR(void)
{
TIMR_INTClr(IOI2C_TMR);
if(IsBusy) IOI2C_MST_Func();
}