|
|
|
|
#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();
|
|
|
|
|
}
|