Files
1CAR/interface_24c02.c

429 lines
10 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.

#include <sdrv_gpio.h>
#include <udelay/udelay.h>
#include <debug.h>
#include "sdrv_spi.h"
#include "irq_num.h"
#include "clock_ip.h"
#include "interface_config.h"
#define _nop_() udelay(1);
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}
#define bit bool
#define MASTER_TEST_LEN 100//连续最多发送100个字节的数据
static uint8_t m_rx_buf_u8[MASTER_TEST_LEN] __attribute__((__aligned__(32)));
static uint8_t m_tx_buf_u8[MASTER_TEST_LEN] __attribute__((__aligned__(32)));
static struct sdrv_spi g_master;
void iic_start(void);
void iic_stop(void);
void iic_ack(bit ackbit);
void iic_sendbyte(unsigned char byt);
//void wrbyte_24c02(unsigned int add,unsigned char dat);
void delay(unsigned char t);
bit iic_waitack(void);
unsigned char i2c_recbyte(void);
unsigned char rdbyte_24c02(unsigned int add);
unsigned char wrEE_CRC_Bak(unsigned char add,unsigned char *eeData,unsigned char len,unsigned char addbak);
unsigned char rdEE_CRC_Bak(unsigned char add,unsigned char *eeData,unsigned char len,unsigned char addbak);
////FM25CL64指令定义
#define FM25CL64_WREN 0x06 //使能
#define FM25CL64_WRDI 0x04 //失能
#define FM25CL64_RDSR 0x05 //读状态
#define FM25CL64_WRSR 0x01 //写状态
#define FM25CL64_READ 0x03 //读数据
#define FM25CL64_WRITE 0x02 //写数据
#define MAX_FM25CL64_LEN 8192//8k字节
static const struct spi_device_config device_mode0_8bits_ss0 = {
.sclk_freq = 1000000,
.cpol = SCK_IDLE_LOW,
.cpha = DATA_CPT_ON_FIRST_SCK_EDGE,
.cs_pol = CS_ACTIVE_LOW,
.cs_sel = CS_SEL_SS0,
.width = SPI_DATA_WIDTH_BYTE,
.fream_delay = 0,
.clk2cs_delay = 0,
.clk2cs_end_delay = 0,
.is_lsb_mode = false,
};
static struct spi_common_config spi_master = {
.is_spi_mode = true,
.is_half_mode = false,
.is_master = true,
.base = APB_SPI6_BASE,
.irq = SPI6_SPI_INTR_NUM,
#if CONFIG_E3
.clk = &g_ckgen_ip_spi_sf_1_to_4,
#else
.clk = &g_ckgen_ip_spi_sf_1_to_3,
#endif
};
void initSpi()
{
/* Init Spi Instance */
sdrv_spi_init(&g_master, &spi_master);
sdrv_spi_config_device(&g_master, &device_mode0_8bits_ss0);
}
void SDAOut(bit c)
{
// sdrv_pinctrl_set_input_select(GPIO_Y3, PIN_IS_CMOS);
// sdrv_gpio_set_pin_direction(GPIO_Y3, GPIO_DIR_OUT);
sdrv_gpio_set_pin_output_level(GPIO_Y3, c);
}
void SCLOut(bit c)
{
sdrv_gpio_set_pin_output_level(GPIO_Y2, c);
}
void iic_start(void)
{
SDAOut(1);
_nop_();
SCLOut(1);
somenop;
SDAOut(0);
somenop;
SCLOut(0);
}
void iic_stop(void)
{
SDAOut(0);
_nop_();
SCLOut(1);
somenop;
SDAOut(1);
}
void iic_ack(bit ackbit)
{
if(ackbit)
SDAOut(0);
else
SDAOut(1);
somenop;
SCLOut(1);
somenop;
SCLOut(0);
SDAOut(1);
somenop;
}
bit iic_waitack(void)
{
SDAOut(1);
somenop;
SCLOut(1);
// sdrv_pinctrl_set_input_select(GPIO_Y3, PIN_IS_CMOS_SCHMITT);
// sdrv_gpio_set_pin_direction(GPIO_Y3, GPIO_DIR_IN);
somenop;
if(sdrv_gpio_read_pin_input_level(GPIO_Y3))
{
SCLOut(0);
iic_stop();
return 0;
}
else
{
SCLOut(0);
return 1;
}
}
void iic_sendbyte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
SDAOut(1);
else
SDAOut(0);
somenop;
SCLOut(1);
byt <<= 1;
somenop;
SCLOut(0);
}
}
unsigned char iic_recbyte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCLOut(1);
// sdrv_pinctrl_set_input_select(GPIO_Y3, PIN_IS_CMOS_SCHMITT);
// sdrv_gpio_set_pin_direction(GPIO_Y3, GPIO_DIR_IN);
somenop;
da <<= 1;
// P1_IOCR01 = 0x0020; // load port control register 1
if(sdrv_gpio_read_pin_input_level(GPIO_Y3))
da |= 0x01;
SCLOut(0);
somenop;
}
return da;
}
unsigned char wrbyte_24c02(unsigned int add,unsigned char dat)
{
#if EN_24C02
unsigned char eeprom_page = 0;
unsigned char eeprom_add = 0;
unsigned char device_add = 0;
//-------------------------------------------------
eeprom_page = add/256;//页
eeprom_add = add%256;
if(eeprom_page >= 3)//目前E2一共4页。1k
{
eeprom_page = 3;
}
// Device Address 1100 0 p1 p0 R/W
device_add = (0xa0 | (eeprom_page << 1));//
// ssdk_printf(SSDK_CRIT, "eeprom_page:0x%x\r\n", eeprom_page);
// ssdk_printf(SSDK_CRIT, "eeprom_add:0x%x\r\n", eeprom_add);
// ssdk_printf(SSDK_CRIT, "device_add:0x%x\r\n", device_add);
iic_start();
iic_sendbyte(device_add);
iic_waitack();
iic_sendbyte(eeprom_add);
iic_waitack();
iic_sendbyte(dat);
iic_waitack();
iic_stop();
#else
if(add >= MAX_FM25CL64_LEN)//最大地址限制
{
printf("E2 len error!\r\n");
}
else
{
m_tx_buf_u8[0] = FM25CL64_WREN;//写使能
if (sdrv_spi_sync_transmit(&g_master, m_tx_buf_u8, m_rx_buf_u8,1,1))
{
printf("E2 write Failed!\r\n");
}
m_tx_buf_u8[0] = FM25CL64_WRITE;//写数据
m_tx_buf_u8[1] = (uint8_t)( add >> 8);// 高8位地址
m_tx_buf_u8[2] = (uint8_t)( add );//
m_tx_buf_u8[3] = dat;//
if (sdrv_spi_sync_transmit(&g_master, m_tx_buf_u8, m_rx_buf_u8,4,4))
{
printf("E2 write Failed!\r\n");
}
}
#endif
return 0;
}
unsigned char rdbyte_24c02(unsigned int add)
{
#if EN_24C02
unsigned char eeprom_page = 0;
unsigned char eeprom_add = 0;
unsigned char device_add = 0;
unsigned char da;
//-------------------------------------------------
eeprom_page = add/256;//页
eeprom_add = add%256;
if(eeprom_page >= 3)//目前E2一共4页。1k
{
eeprom_page = 3;
}
// Device Address 1100 000 R/W
iic_start();
device_add = (0xa0 | (eeprom_page << 1));// 伪写操作
iic_sendbyte(device_add);
iic_waitack();
iic_sendbyte(eeprom_add);
iic_waitack();
iic_start();
device_add = (0xa1 | (eeprom_page << 1));//
ssdk_printf(SSDK_CRIT, "device_add:0x%x\r\n", device_add);
iic_sendbyte(device_add);
iic_waitack();
da = iic_recbyte();
iic_ack(0);
iic_stop();
//CAN_sendAck(add, da);
return da;
#else
if(add >= MAX_FM25CL64_LEN)//最大地址限制
{
printf("E2 len error!\r\n");
}
else
{
m_tx_buf_u8[0] = FM25CL64_READ;//读数据
m_tx_buf_u8[1] = (uint8_t)( add >> 8);// 高8位地址
m_tx_buf_u8[2] = (uint8_t)( add );//
m_tx_buf_u8[3] = 0xFF;//
if (sdrv_spi_sync_transmit(&g_master, m_tx_buf_u8, m_rx_buf_u8,4,4))
{
printf("E2 write Failed!\r\n");
}
return m_rx_buf_u8[3];
}
#endif
return 0xFF;
}
#ifdef _EEROM_CRC_
#define POLY 0x1021
/**
* Calculating CRC-16 in 'C'
* @para addr, start of data
* @para num, length of data
* @para crc, incoming CRC
*/
unsigned int crc16(unsigned char *addr, int num, unsigned int crc)
{
int i;
for (; num > 0; num--) /* Step through bytes in memory */
{
crc = crc ^ ((*addr) << 8); /* Fetch byte from memory, XOR into CRC top byte*/
addr++;
for (i = 0; i < 8; i++) /* Prepare to rotate 8 bits */
{
if (crc & 0x8000) /* b15 is set... */
crc = (crc << 1) ^ POLY; /* rotate and XOR with polynomic */
else /* b15 is clear... */
crc <<= 1; /* just rotate */
} /* Loop for 8 bits */
crc &= 0xFFFF; /* Ensure CRC remains 16-bit value */
} /* Loop until num=0 */
return(crc); /* Return updated CRC */
}
//写入正确会自动写一个备份,写入有问题就不会写备份
unsigned char wrEE_CRC_Bak(unsigned char add,unsigned char *eeData,unsigned char len,unsigned char addbak)
{
uword crc_Res;
unsigned char index;
unsigned char flagEEwrOK;
crc_Res = crc16(eeData, len-2, 0xffff); //计算数据的校验
eeData[len-2] = (ubyte)(crc_Res );
eeData[len-1] = (ubyte)(crc_Res >> 8);
for(index=0;index<len;index++) //写数据
{WDT_vServiceWDT();
wrbyte_24c02( add + index, eeData[index]);
}
flagEEwrOK = 1;
for(index=0;index<len;index++) //校验数据
{WDT_vServiceWDT();
if(rdbyte_24c02( add + index) != eeData[index])
{
flagEEwrOK = 0;
break;
}
}
if(1 == flagEEwrOK) //
{
for(index=0;index<len;index++) //写数据和校验数据
{WDT_vServiceWDT();
wrbyte_24c02( addbak + index, eeData[index]);
}
flagEEwrOK = 2;
for(index=0;index<len;index++)
{WDT_vServiceWDT();
if(rdbyte_24c02( addbak + index) != eeData[index])
{ flagEEwrOK = 0;
break;
}
}
}
else
{
flagEEwrOK = 0;
//.........
}
return flagEEwrOK;
}
unsigned char rdEE_CRC_Bak(unsigned char add,unsigned char *eeData,unsigned char len,unsigned char addbak)
{
uword crc_Res;
unsigned char index;
unsigned char reEEok = 0;
for(index=0;index<len;index++) //读数据和校验数据
{WDT_vServiceWDT();
eeData[index] = rdbyte_24c02(add + index);
}
crc_Res = crc16(eeData, len-2, 0xffff); //计算数据的校验
if( crc_Res == ((uword)eeData[len-1] << 8) + (uword)eeData[len-2]) //对比读取的校验值 正确采用EE值不正确...
{
reEEok = 1;
}
else
{
for(index=0;index<len;index++) //读备份数据和校验数据
{WDT_vServiceWDT();
eeData[index] = rdbyte_24c02(addbak + index);
}
crc_Res = crc16(eeData, len-2, 0xffff); //计算数据的校验
if( crc_Res == ((uword)eeData[len-1] << 8) + (uword)eeData[len-2]) //对比读取的校验值 正确采用EE值不正确...
{
reEEok = 2;
}
else
{
reEEok = 0;
}
}
return reEEok;
}
#endif