#include "eeprom.h" #include "gd32f30x_libopt.h" #include "SysTick.h" #include "main.h" #define ACK 1 #define NACK 0 #define IIC_WP_PIN GPIO_PIN_8 #define IIC_DATA_IO GPIOB #define IIC_SDA_PIN GPIO_PIN_7 #define IIC_SCL_PIN GPIO_PIN_6 #define PAGE_SZIE_32 (32) #define PAGE_SIZE_16 (16) #define IIC_READ_SDA() gpio_input_bit_get(IIC_DATA_IO, IIC_SDA_PIN) #define IIC_SCL_SET gpio_bit_set(IIC_DATA_IO, IIC_SCL_PIN) #define IIC_SCL_CLR gpio_bit_reset(IIC_DATA_IO, IIC_SCL_PIN) #define IIC_SDA_SET gpio_bit_set(IIC_DATA_IO, IIC_SDA_PIN) #define IIC_SDA_CLR gpio_bit_reset(IIC_DATA_IO, IIC_SDA_PIN) #define AT24C01 127 #define AT24C02 255 #define AT24C04 511 #define AT24C08 1023 #define AT24C16 2047 #define AT24C32 4095 #define AT24C64 8191 #define AT24C128 16383 #define AT24C256 32767 #define USER_DEFINE_EEPROM_TYPE AT24C64 #define PAGE_SIZE PAGE_SZIE_32 static void iic_init(void); static void iic_start_signal(void); static void iic_stop_signal(void); static void iic_send_byte(uint8_t data); static uint8_t iic_read_byte(uint8_t ack); static uint8_t iic_wait_ack(void); static void iic_send_ack(void); static void iic_send_nack(void); static uint8_t eeprom_read_1_byte(uint16_t addr); static void eeprom_write_1_byte(uint16_t addr,uint8_t data); static void eeprom_write(uint16_t w_addr,uint8_t *data,uint16_t lenth); static void eeprom_read(uint16_t r_addr,uint8_t *data,uint16_t lenth); static void check_threshold(uint8_t in_out,uint8_t channel); static uint8_t eeprom_page_read(uint16_t addr,uint8_t *data,uint16_t lenth); static uint8_t eeprom_write_page(uint16_t addr,uint8_t *data,uint16_t chuank); static void eeprom_auto_page_write(uint16_t addr,uint8_t *data,uint16_t lenth); static void eeprom_auto_page_read(uint16_t addr,uint8_t *data,uint16_t lenth); static inline void iic_set_sda_input() { // gpio_mode_set(IIC_DATA_IO, GPIO_MODE_INPUT, GPIO_PUPD_NONE, IIC_SDA_PIN); gpio_init(GPIOB,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,IIC_SDA_PIN); } static inline void iic_set_sda_output() { // gpio_mode_set(IIC_DATA_IO, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, IIC_SDA_PIN); // gpio_output_options_set(IIC_DATA_IO, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, IIC_SDA_PIN); gpio_init(GPIOB,GPIO_MODE_OUT_OD,GPIO_OSPEED_50MHZ,IIC_SDA_PIN); gpio_bit_set(GPIOB,IIC_SDA_PIN); } void eeprom_init(void) { sts_data_t *board =get_sts(); iic_init(); board->read_eeprom = eeprom_read; board->write_eeprom = eeprom_write; board->read_eeprom_page = eeprom_auto_page_read; board->write_eeprom_page = eeprom_auto_page_write; } static void iic_init(void) { rcu_periph_clock_enable(RCU_GPIOB); //使能GPIOC的时钟 gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,IIC_WP_PIN); gpio_bit_reset(GPIOB,IIC_WP_PIN); //配置PB7 gpio_init(GPIOB,GPIO_MODE_OUT_OD,GPIO_OSPEED_50MHZ,IIC_SDA_PIN); //设置GPIO输出模式及速度 SDA gpio_bit_set(GPIOB,IIC_SDA_PIN); //配置PB6 gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,IIC_SCL_PIN); //设置GPIO输出模式及速度 SCL gpio_bit_set(GPIOB,IIC_SCL_PIN); } /***************************************************************************************** * start data transport signal * 1 2 3 4 * __________ * SCL : __/ \_____ * ________ * SDA : \___________ ******************************************************************************************/ static void iic_start_signal(void) { iic_set_sda_output(); IIC_SDA_SET; IIC_SCL_SET; DelayNus(4); IIC_SDA_CLR; DelayNus(4); IIC_SCL_CLR; } /***************************************************************************************** * stop data transport signal * 1 2 3 4 * _______________ * SCL : ______/ * __ ____________ * SDA : \______/ * ^ * | * ******************************************************************************************/ static void iic_stop_signal(void) { iic_set_sda_output(); IIC_SCL_CLR; IIC_SDA_CLR; DelayNus(4); IIC_SCL_SET; DelayNus(4); IIC_SDA_SET; DelayNus(4); } /***************************************************************************************** * iic send 1 byte * 1 2 3 4 * ______ * SCL: ________/ \______ * ______________________ * SDA: \\\___________________ * ******************************************************************************************/ static void iic_send_byte(uint8_t data) { iic_set_sda_output(); IIC_SCL_CLR; uint8_t t; for(t = 0; t < 8; t++){ if((data & 0x80) >> 7) { IIC_SDA_SET; }else { IIC_SDA_CLR; } data <<= 1; DelayNus(2); IIC_SCL_SET; DelayNus(2); IIC_SCL_CLR; DelayNus(2); } } /***************************************************************************************** * read 1 byte * 1 2 3 4 * ______ * SCL: ______/ \___ * ____________________ * SDA: \\\\______________\\\ * ******************************************************************************************/ static uint8_t iic_read_byte(uint8_t ack) { uint8_t i; uint8_t receive = 0; iic_set_sda_input(); for(i = 0; i < 8; i++ ){ IIC_SCL_CLR; DelayNus(2); IIC_SCL_SET; receive <<= 1; if(IIC_READ_SDA()) { receive ++; } DelayNus(1); } if(NACK == ack) { iic_send_nack(); }else{ iic_send_ack(); } return receive; } /***************************************************************************************** * wait ack signal * _______|____ * SCL: | \_________ * _______| * SDA: \_____________ * ******************************************************************************************/ static uint8_t iic_wait_ack(void) { uint8_t err_time = 0; iic_set_sda_input(); IIC_SCL_SET; DelayNus(1); while(IIC_READ_SDA()) { err_time++; if(err_time >250) { iic_stop_signal(); return 1; } } IIC_SCL_CLR; return 0; } /***************************************************************************************** * send ack signal * 1 2 3 4 * ______ * SCL: ________/ \______ * __ * SDA: \___________________ ******************************************************************************************/ static void iic_send_ack(void) { IIC_SCL_CLR; iic_set_sda_output(); IIC_SDA_CLR; DelayNus(2); IIC_SCL_SET; DelayNus(2); IIC_SCL_CLR; } /***************************************************************************************** * send nack signal * 1 2 3 4 * ______ * SCL: ________/ \______ * ______________________ * SDA: __/ ******************************************************************************************/ static void iic_send_nack(void) { IIC_SCL_CLR; iic_set_sda_output(); IIC_SDA_SET; DelayNus(2); IIC_SCL_SET; DelayNus(2); IIC_SCL_CLR; } static uint8_t eeprom_read_1_byte(uint16_t addr) { uint8_t temp =0; iic_start_signal(); if(USER_DEFINE_EEPROM_TYPE > AT24C16) { iic_send_byte(0XA0); iic_wait_ack(); iic_send_byte(addr >> 8); }else { iic_send_byte(0XA0 + ((addr / 256) << 1)); } iic_wait_ack(); iic_send_byte(addr % 256); iic_wait_ack(); iic_start_signal(); iic_send_byte(0XA1); iic_wait_ack(); temp = iic_read_byte(0); iic_stop_signal(); return temp; } static void eeprom_write_1_byte(uint16_t addr,uint8_t data) { iic_start_signal(); if(USER_DEFINE_EEPROM_TYPE > AT24C16) { iic_send_byte(0XA0); iic_wait_ack(); iic_send_byte(addr >> 8); }else { iic_send_byte(0XA0 + ((addr / 256) << 1)); } iic_wait_ack(); iic_send_byte(addr % 256); iic_wait_ack(); iic_send_byte(data); iic_wait_ack(); iic_stop_signal(); DelayNms(7); } static void eeprom_write(uint16_t w_addr,uint8_t *data,uint16_t lenth) { while(lenth) { eeprom_write_1_byte(w_addr,*data); w_addr++; data++; lenth--; } } static void eeprom_read(uint16_t r_addr,uint8_t *data,uint16_t lenth) { while(lenth) { *data = eeprom_read_1_byte(r_addr); data++; r_addr++; lenth--; } } static uint8_t eeprom_page_read(uint16_t addr,uint8_t *data,uint16_t lenth) { if(lenth == 0 || lenth > PAGE_SIZE || ((addr % PAGE_SIZE) + lenth > PAGE_SIZE)) { return 1; } iic_start_signal(); if(USER_DEFINE_EEPROM_TYPE > AT24C16) { iic_send_byte(0XA0); if(iic_wait_ack()) goto failed; iic_send_byte(addr >> 8); }else { iic_send_byte(0XA0 + ((addr / 256) << 1)); } if(iic_wait_ack()) goto failed; iic_send_byte(addr % 256); if(iic_wait_ack()) goto failed; iic_start_signal(); iic_send_byte(0XA1); if(iic_wait_ack()) goto failed; for(int i = 0; i < lenth;i++) { if(i == lenth -1) { data[i] = iic_read_byte(0); }else { data[i] = iic_read_byte(1); } } iic_stop_signal(); return 0; failed: iic_stop_signal(); return 1; } static uint8_t eeprom_write_page(uint16_t addr,uint8_t *data,uint16_t chuank) { if(chuank == 0 || chuank > PAGE_SIZE || ((addr % PAGE_SIZE) + chuank > PAGE_SIZE)) { return 1; } iic_start_signal(); if(USER_DEFINE_EEPROM_TYPE > AT24C16) { iic_send_byte(0XA0); if(iic_wait_ack()) goto failed; iic_send_byte(addr >> 8); }else { iic_send_byte(0XA0 + ((addr / 256) << 1)); } if(iic_wait_ack()) goto failed; iic_send_byte(addr % 256); if(iic_wait_ack()) goto failed; for(uint16_t i = 0; i < chuank;i++) { iic_send_byte(data[i]); if(iic_wait_ack()) goto failed; } iic_stop_signal(); vTaskDelay(7); return 0; failed: iic_stop_signal(); return 1; } static void eeprom_auto_page_write(uint16_t addr,uint8_t *data,uint16_t lenth) { uint16_t remaining = lenth; uint8_t *p = data; uint8_t count = 5; while(remaining > 0) { uint8_t chunk = PAGE_SIZE - (addr % PAGE_SIZE); if(chunk > remaining) chunk = remaining; do{ if(!eeprom_write_page(addr, p,chunk)) { break; } }while(count--); addr += chunk; p += chunk; remaining -= chunk; } } static void eeprom_auto_page_read(uint16_t addr,uint8_t *data,uint16_t lenth) { uint16_t remaining = lenth; uint8_t *p = data; uint8_t count = 5; while(remaining > 0) { uint8_t chunk = PAGE_SIZE - (addr % PAGE_SIZE); if(chunk > remaining) chunk = remaining; do{ if(!eeprom_page_read(addr, p, chunk)) { break; } }while(count--); addr += chunk; p += chunk; remaining -= chunk; } } void read_config_from_eeprom(void) { sts_data_t *sts_d = get_sts(); uint16_t device_info = 0xFFFF; eeprom_auto_page_read(EEP_DEVICE_INFO,&device_info,sizeof(uint16_t)); if(device_info != sts_d->m_data.m_r.r_data.dev) { //EEP_MD_START memset(&sts_d->m_data.m_rw.rw_data.md_eep,0,sizeof(md_eep_data_t)); sts_d->m_data.m_rw.rw_data.md_eep.out_status = 1; for(int i = 0; i < 2;i++) { sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_max_1 = (240*1000); sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_max_2 = (260*1000); sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_min_1 = (200*1000); sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_min_2 = (180*1000); sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_max_1 = (55*1000); sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_max_2 = (65*1000); sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_min_1 = (47*1000); sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_min_2 = (45*1000); sts_d->m_data.m_rw.rw_data.md_eep.input_arg[i].i_k = 10000; sts_d->m_data.m_rw.rw_data.md_eep.input_arg[i].v_k = 3135; } sts_d->m_data.m_rw.rw_data.md_eep.temp_th.max_temp = (50)*10; // sts_d->m_data.m_rw.rw_data.md_eep.temp_th.min_temp = (36)*10; //control fans sts_d->m_data.m_rw.rw_data.md_eep.out_status = 1; sts_d->m_data.m_rw.rw_data.md_eep.output_th.voltage_max_1 = (240*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_th.voltage_max_2 = (260*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_th.voltage_min_1 = (200*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_th.voltage_min_2 = (180*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_th.power_max_1 = (7000*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_th.power_max_2 = (10000*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_th.current_max_1 = (10*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_th.current_max_2 = (16*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_th.consumer_max_1 = (10000*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_th.consumer_max_2 = (90000*1000); sts_d->m_data.m_rw.rw_data.md_eep.output_arg.i_k = 10000; sts_d->m_data.m_rw.rw_data.md_eep.output_arg.v_k = 3135; eeprom_auto_page_write(EEP_MD_START,(uint8_t*)(&sts_d->m_data.m_rw.rw_data.md_eep),sizeof(md_eep_data_t)); iic_consumer_data_t chache = {0}; for(int i = 0; i < MAX_ROW;i++) { eeprom_auto_page_write(IIC_CONSUMER_START+(IIC_CONSUMER_PAGE*i),&chache,sizeof(iic_consumer_data_t)); } } eeprom_auto_page_read(EEP_MD_START,&sts_d->m_data.m_rw.rw_data.md_eep.out_status,sizeof(md_eep_data_t)); iic_consumer_data_t chache = {0}; for(uint8_t i = 0 ; i < MAX_ROW;i++) { eeprom_auto_page_read(IIC_CONSUMER_START+(IIC_CONSUMER_PAGE*i),&chache,sizeof(iic_consumer_data_t)); if(sts_d->kwh.index <= chache.recode_index1) { sts_d->kwh.index = chache.recode_index1; sts_d->kwh.row = i; } } eeprom_auto_page_read(IIC_CONSUMER_START+(IIC_CONSUMER_PAGE*sts_d->kwh.row),&chache,sizeof(iic_consumer_data_t)); sts_d->iic_consumer = chache.iic_consumer; for(uint8_t i = 0 ;i < 2 ;i ++) { if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_max_1 > INVALID_VALUE) sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_max_1 = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_max_2 > INVALID_VALUE) sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_max_2 = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_min_1 > INVALID_VALUE) sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_min_1 = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_min_2 > INVALID_VALUE) sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_min_2 = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_max_1 > INVALID_VALUE) sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_max_1 = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_max_2 > INVALID_VALUE) sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_max_2 = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_min_2 > INVALID_VALUE) sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_min_2 = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_min_1 > INVALID_VALUE) sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_min_1 = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_max_1 <= SMALL_VALUE) sts_d->input_wanning_en[i].vmax_en = 0; else sts_d->input_wanning_en[i].vmax_en = 1; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].voltage_min_1 <= SMALL_VALUE) sts_d->input_wanning_en[i].vmin_en = 0; else sts_d->input_wanning_en[i].vmin_en = 1; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_max_1 <= SMALL_VALUE) sts_d->input_wanning_en[i].freqmax_en = 0; else sts_d->input_wanning_en[i].freqmax_en = 1; if(sts_d->m_data.m_rw.rw_data.md_eep.input_th[i].freq_min_1 <= SMALL_VALUE) sts_d->input_wanning_en[i].freqmin_en = 0; else sts_d->input_wanning_en[i].freqmin_en = 1; } *(uint8_t*)(&sts_d ->output_wanning_en) = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.output_th.voltage_max_1 <= SMALL_VALUE) sts_d->output_wanning_en.vmax_en = 0; else sts_d->output_wanning_en.vmax_en = 1; if(sts_d->m_data.m_rw.rw_data.md_eep.output_th.voltage_min_1 <= SMALL_VALUE) sts_d->output_wanning_en.vmin_en = 0; else sts_d->output_wanning_en.vmin_en = 1; if(sts_d->m_data.m_rw.rw_data.md_eep.output_th.current_max_1 <= SMALL_VALUE) sts_d->output_wanning_en.imax_en = 0; else sts_d->output_wanning_en.imax_en = 1; if(sts_d->m_data.m_rw.rw_data.md_eep.output_th.power_max_1 <= SMALL_VALUE) sts_d->output_wanning_en.pmax_en = 0; else sts_d->output_wanning_en.pmax_en = 1; if(sts_d->m_data.m_rw.rw_data.md_eep.output_th.consumer_max_1 <= SMALL_VALUE) sts_d->output_wanning_en.cmax_en = 0; else sts_d->output_wanning_en.cmax_en = 1; if(sts_d->m_data.m_rw.rw_data.md_eep.temp_th.max_temp > 0x7fff) sts_d->m_data.m_rw.rw_data.md_eep.temp_th.max_temp = 0; if(sts_d->m_data.m_rw.rw_data.md_eep.temp_th.min_temp > 0x7fff) sts_d->m_data.m_rw.rw_data.md_eep.temp_th.min_temp = 0; }