#include #include #include #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