mirror of
https://github.com/fanhuanji/VUSION4.2BWR_GL340.git
synced 2025-12-06 08:22:50 +08:00
312 lines
6.3 KiB
C
312 lines
6.3 KiB
C
|
|
#include "i2c.h"
|
|
#include "time/time.h"
|
|
|
|
void I2C_HalfClk(void)
|
|
{
|
|
__asm__("NOP");
|
|
|
|
//__asm__("NOP");
|
|
//__asm__("NOP");
|
|
//__asm__("NOP");
|
|
|
|
//__asm__("NOP");
|
|
// __asm__("NOP");
|
|
// __asm__("NOP");
|
|
// __asm__("NOP");
|
|
}
|
|
|
|
void I2C_init(void)
|
|
{
|
|
P0DIR |= BV(4) | BV(6);
|
|
SDA = 1;
|
|
SCL = 1;
|
|
}
|
|
|
|
void I2C_start(void)
|
|
{
|
|
I2C_HalfClk();
|
|
SDA_OUT();
|
|
SDA = 0;
|
|
I2C_HalfClk();
|
|
SCL = 0;
|
|
I2C_HalfClk();
|
|
}
|
|
|
|
void I2C_stop(void)
|
|
{
|
|
SDA_OUT();
|
|
SDA = 0;
|
|
SCL = 1;
|
|
I2C_HalfClk();
|
|
SDA = 1;
|
|
I2C_HalfClk();
|
|
}
|
|
|
|
void I2C_ack(void)
|
|
{
|
|
SCL = 0;
|
|
SDA_OUT();
|
|
SDA = 0;
|
|
I2C_HalfClk();
|
|
SCL = 1;
|
|
I2C_HalfClk();
|
|
SCL = 0;
|
|
}
|
|
|
|
void I2C_nack(void)
|
|
{
|
|
SCL = 0;
|
|
SDA_OUT();
|
|
SDA = 1;
|
|
I2C_HalfClk();
|
|
SCL = 1;
|
|
I2C_HalfClk();
|
|
SCL = 0;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
*
|
|
* @param Data
|
|
* @return uint8_t 0=ACK 1=NACK
|
|
*/
|
|
uint8_t I2C_write(unsigned char Data)
|
|
{
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
if ((Data & 0x80) == 0) {
|
|
SDA = 0;
|
|
} else {
|
|
SDA = 1;
|
|
}
|
|
__asm__("NOP");
|
|
SCL = 1;
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
// I2C_HalfClk();
|
|
SCL = 0;
|
|
Data <<= 1;
|
|
}
|
|
SDA = 0;
|
|
SDA_IN();
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
SCL = 1;
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
volatile uint8_t ack = SDA;
|
|
SCL = 0;
|
|
__asm__("NOP");
|
|
SDA_OUT();
|
|
return ack;
|
|
}
|
|
|
|
uint8_t I2C_read(void)
|
|
{
|
|
SDA_IN();
|
|
unsigned char i;
|
|
volatile uint8_t Data = 0;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
SCL = 0;
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
SCL = 1;
|
|
__asm__("NOP");
|
|
if (SDA) {
|
|
Data |= 1;
|
|
}
|
|
if (i < 7) {
|
|
Data <<= 1;
|
|
}
|
|
}
|
|
__asm__("NOP");
|
|
__asm__("NOP");
|
|
SCL = 0;
|
|
I2C_HalfClk();
|
|
return Data;
|
|
}
|
|
|
|
// bool Nfc_MemRead(uint8_t mema, uint8_t *buf)
|
|
// {
|
|
// bool ret = true;
|
|
// I2C_start();
|
|
// ret &= !I2C_write(NFC_W_ADDR);
|
|
// ret &= !I2C_write(mema); // MEMA
|
|
// I2C_stop();
|
|
// delayMs(1);
|
|
// I2C_start();
|
|
// ret &= !I2C_write(NFC_R_ADDR);
|
|
// for (uint8_t i = 0; i < 16; ++i) {
|
|
// buf[i] = I2C_read();
|
|
// I2C_ack();
|
|
// }
|
|
// I2C_stop();
|
|
// return ret;
|
|
// }
|
|
// bool Nfc_MemWrite(uint8_t mema, uint8_t *buf)
|
|
// {
|
|
// bool ret = true;
|
|
// I2C_start();
|
|
// ret &= !I2C_write(NFC_W_ADDR);
|
|
// ret &= !I2C_write(mema); // MEMA
|
|
// for (uint8_t i = 0; i < 16; ++i) {
|
|
// ret &= !I2C_write(buf[i]);
|
|
// }
|
|
// I2C_stop();
|
|
// delayMs(5);
|
|
// return ret;
|
|
// }
|
|
|
|
bool Nfc_MemReadBlk(uint8_t mema, NfcMemoryBlk buf)
|
|
{
|
|
bool ret = true;
|
|
I2C_start();
|
|
ret &= !I2C_write(NFC_W_ADDR);
|
|
ret &= !I2C_write(mema); // MEMA
|
|
I2C_stop();
|
|
// delayMs(1); // SRAM无需延时
|
|
I2C_start();
|
|
ret &= !I2C_write(NFC_R_ADDR);
|
|
for (uint8_t i = 0; i < 16; ++i) {
|
|
buf[i] = I2C_read();
|
|
I2C_ack();
|
|
}
|
|
I2C_stop();
|
|
return ret;
|
|
}
|
|
bool Nfc_MemWriteBlk(uint8_t mema, const NfcMemoryBlk buf)
|
|
{
|
|
bool ret = true;
|
|
I2C_start();
|
|
ret &= !I2C_write(NFC_W_ADDR);
|
|
ret &= !I2C_write(mema); // MEMA
|
|
for (uint8_t i = 0; i < 16; ++i) {
|
|
ret &= !I2C_write(buf[i]);
|
|
}
|
|
I2C_stop();
|
|
// delayMs(5); // 写RAM无需延时
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
*
|
|
* @param mema
|
|
* @param rega
|
|
* @param regdat
|
|
* @return true ACK
|
|
* @return false NACK
|
|
*/
|
|
bool Nfc_ReadReg(uint8_t mema, uint8_t rega, uint8_t *regdat)
|
|
{
|
|
uint8_t ret = false;
|
|
I2C_start();
|
|
ret |= I2C_write(NFC_W_ADDR);
|
|
ret |= I2C_write(mema); // MEMA
|
|
ret |= I2C_write(rega); // REGA
|
|
I2C_stop();
|
|
// if (ret) {
|
|
// return false;
|
|
// }
|
|
I2C_start();
|
|
ret |= I2C_write(NFC_R_ADDR);
|
|
*regdat = I2C_read();
|
|
I2C_ack();
|
|
I2C_stop();
|
|
return !ret;
|
|
}
|
|
bool Nfc_WriteReg(uint8_t mema, uint8_t rega, uint8_t mask, uint8_t regdat)
|
|
{
|
|
bool ret = true;
|
|
I2C_start();
|
|
ret &= !I2C_write(NFC_W_ADDR);
|
|
ret &= !I2C_write(mema); // MEMA
|
|
ret &= !I2C_write(rega); // REGA
|
|
ret &= !I2C_write(mask); // MASK
|
|
ret &= !I2C_write(regdat);
|
|
I2C_stop();
|
|
return ret;
|
|
}
|
|
|
|
// bool Nfc_FullDump(uint8_t *buf, uint16_t bufLen)
|
|
// {
|
|
// if (bufLen < 1024) {
|
|
// return false;
|
|
// }
|
|
// bool ret = true;
|
|
// for (uint16_t blk = 0; blk < 0x3B; ++blk) {
|
|
// ret &= !Nfc_MemRead(blk, (buf[16 * blk]));
|
|
// }
|
|
// return ret;
|
|
// }
|
|
|
|
|
|
/**
|
|
* @brief 通过Session寄存器开启pass-through功能
|
|
*
|
|
* @param enable
|
|
*/
|
|
bool Nfc_ConfigurePassThru(bool enable)
|
|
{
|
|
uint8_t reg = 0;
|
|
if (enable) {
|
|
reg = NFC_SESSION_NC_REG_PTHRU_ON_OFF;
|
|
} else {
|
|
reg = (uint8_t)~NFC_SESSION_NC_REG_PTHRU_ON_OFF;
|
|
}
|
|
return Nfc_WriteReg(NFC_SESSION_REG_MEMA, NFC_SESSION_NC_REG_REGA, NFC_SESSION_NC_REG_PTHRU_ON_OFF, reg);
|
|
// }
|
|
}
|
|
|
|
bool Nfc_DirSet(bool nfc2iic)
|
|
{
|
|
uint8_t reg = 0;
|
|
if (nfc2iic) {
|
|
reg = 1;
|
|
} else {
|
|
reg = (uint8_t)~1;
|
|
}
|
|
return Nfc_WriteReg(NFC_SESSION_REG_MEMA, NFC_SESSION_NC_REG_REGA, 1, reg);
|
|
}
|
|
|
|
bool Nfc_I2cLock(bool enable)
|
|
{
|
|
uint8_t reg = 0;
|
|
if (enable) {
|
|
reg = NFC_SESSION_NS_REG_I2C_LOCKED;
|
|
} else {
|
|
reg = (uint8_t)~NFC_SESSION_NS_REG_I2C_LOCKED;
|
|
}
|
|
return Nfc_WriteReg(NFC_SESSION_REG_MEMA, NFC_SESSION_NS_REG_REGA, NFC_SESSION_NS_REG_I2C_LOCKED, reg);
|
|
}
|
|
|
|
/**
|
|
* @brief 通过NS_REG判断当前是否有NFC存在
|
|
* @return true
|
|
* @return false
|
|
*/
|
|
bool Nfc_IsFieldActive(void)
|
|
{
|
|
uint8_t reg = 0;
|
|
if (Nfc_ReadReg(NFC_SESSION_REG_MEMA, NFC_SESSION_NS_REG_REGA, ®)) {
|
|
return reg & NFC_SESSION_NS_REG_RF_FIELD_PRESENT;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool Nfc_SetFdPin(uint8_t on, uint8_t off)
|
|
{
|
|
uint8_t reg = (on << 2) | (off << 4);
|
|
return Nfc_WriteReg(NFC_SESSION_REG_MEMA, NFC_SESSION_NC_REG_REGA, NFC_SESSION_NC_REG_FD_ON_OFF, reg);
|
|
}
|