/* * ================================================================== >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< ------------------------------------------------------------------ Copyright (c) 2006-2018 by Lattice Semiconductor Corporation ALL RIGHTS RESERVED ------------------------------------------------------------------ IMPORTANT: THIS FILE IS AUTO-GENERATED BY LATTICE RADIANT Software. Permission: Lattice grants permission to use this code pursuant to the terms of the Lattice Corporation Open Source License Agreement. Disclaimer: Lattice provides no warranty regarding the use or functionality of this code. It is the user's responsibility to verify the user Software design for consistency and functionality through the use of formal Software validation methods. ------------------------------------------------------------------ Lattice Semiconductor Corporation 111 SW Fifth Avenue, Suite 700 Portland, OR 97204 U.S.A Email: techsupport@latticesemi.com Web: http://www.latticesemi.com/Home/Support/SubmitSupportTicket.aspx ================================================================== */ #include #include "i2c_slave_regs.h" #include "hal.h" uint8_t i2c_slave_clk_stretch(struct i2c_slave_instance *this_i2cs,uint8_t stretch_enable) { if (this_i2cs == NULL) return I2C_SLV_PTR_ERROR; reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_CTRL, stretch_enable); return I2C_SLV_SUCCESS; } uint8_t i2c_slave_data_write(struct i2c_slave_instance *this_i2cs,uint8_t *tx_buf,uint8_t length) { uint8_t count=0; if (this_i2cs == NULL) return I2C_SLV_PTR_ERROR; while (count < length) { reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_DATA_BUFFER, tx_buf[count++]); } return I2C_SLV_SUCCESS; } uint8_t i2c_slave_data_read(struct i2c_slave_instance *this_i2cs,uint8_t *rx_buf,uint8_t *length) { uint8_t count=0; if (this_i2cs == NULL) return I2C_SLV_PTR_ERROR; while (count < this_i2cs->rx_idx) { *rx_buf=this_i2cs->rx_buffer[count++]; rx_buf++; } *length= this_i2cs->rx_idx; this_i2cs->rx_idx=0; return I2C_SLV_SUCCESS; } uint8_t i2c_slave_status_get(struct i2c_slave_instance *this_i2cs,uint8_t *status) { if (this_i2cs == NULL) return I2C_SLV_PTR_ERROR; *status=this_i2cs->status; return I2C_SLV_SUCCESS; } uint8_t i2c_slave_init(struct i2c_slave_instance *this_i2cs, uint32_t base_addr, uint16_t slave_addr, uint8_t addr_mode,uint8_t *rx_buffer, uint8_t rx_size, uint8_t *tx_buffer, uint8_t tx_size) { if (this_i2cs == NULL) return I2C_SLV_PTR_ERROR; this_i2cs->base_addr = base_addr; this_i2cs->slave_addr = slave_addr; this_i2cs->addr_mode = addr_mode; this_i2cs->rx_idx = 0; this_i2cs->tx_idx = 0; this_i2cs->rx_buffer = rx_buffer; this_i2cs->rx_size = rx_size; this_i2cs->tx_buffer = tx_buffer; this_i2cs->tx_size = tx_size; this_i2cs->status = I2C_IDLE; return I2C_SLV_SUCCESS; } uint8_t i2c_slave_config(struct i2c_slave_instance *this_i2cs, uint32_t base_addr, uint16_t slave_addr, uint8_t addr_mode) { if (this_i2cs == NULL) return I2C_SLV_PTR_ERROR; reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_CTRL, this_i2cs->addr_mode); reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_ADDR_LOW, this_i2cs->slave_addr); reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_TARGET_BYTE_COUNT, 0);//0 :the amount of data is unknown reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_INT_ENABLE, I2C_SLAVE_STOP_DET|I2C_SLAVE_RX_FIFO_READY|I2C_SLAVE_RX_FIFO_AFULL|I2C_SLAVE_RX_FIFO_FULL); //the amount of data is unknown,enable rx fifo int reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_INT_ENABLE2, I2C_SLAVE_STOP_ERR|I2C_SLAVE_START_ERR); while (this_i2cs->tx_idx < this_i2cs->tx_size) { reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_DATA_BUFFER, this_i2cs->tx_buffer [this_i2cs->tx_idx++]); } this_i2cs->tx_idx=0; return I2C_SLV_SUCCESS; } void i2c_slave_isr(void *ctx) { struct i2c_slave_instance *this_i2cs = (struct i2c_slave_instance*)ctx; uint8_t int_status; uint8_t int_status2; uint8_t data; uint8_t rx_count=0; uint8_t fifo_status; reg_8b_read(this_i2cs->base_addr | I2C_SLAVE_INT_STATUS2, &int_status2);//check err status if(int_status2 & (I2C_SLAVE_STOP_ERR|I2C_SLAVE_START_ERR)) { this_i2cs->status = I2C_ERROR; reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_INT_STATUS2, int_status2 & SET_ALL_BITS);//clear all int bits return; } reg_8b_read(this_i2cs->base_addr | I2C_SLAVE_INT_STATUS, &int_status); reg_8b_read(this_i2cs->base_addr | I2C_SLAVE_FIFO_STATUS, &fifo_status); reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_INT_STATUS, int_status & SET_ALL_BITS);//clear all int bits if (int_status & I2C_SLAVE_STOP_DET/*I2C_SLAVE_RD_DONR*/) { while (this_i2cs->rx_idx < this_i2cs->rx_size) { reg_8b_read(this_i2cs->base_addr | I2C_SLAVE_FIFO_STATUS, &fifo_status); if(fifo_status&I2C_SLAVE_RX_FIFO_EMPTY) break; reg_8b_read(this_i2cs->base_addr | I2C_SLAVE_DATA_BUFFER, &data); this_i2cs->rx_buffer[this_i2cs->rx_idx++] = data; } if(this_i2cs->status == I2C_WRITE) this_i2cs->status = I2C_READY; } if(int_status & I2C_SLAVE_RX_FIFO_AFULL/*I2C_SLAVE_RD_DONR*/) { reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_INT_STATUS, int_status & SET_ALL_BITS);//clear all int bits while (this_i2cs->rx_idx < this_i2cs->rx_size) { reg_8b_read(this_i2cs->base_addr | I2C_SLAVE_FIFO_STATUS, &fifo_status); if(fifo_status&I2C_SLAVE_RX_FIFO_EMPTY) break; reg_8b_read(this_i2cs->base_addr | I2C_SLAVE_DATA_BUFFER, &data); this_i2cs->rx_buffer[this_i2cs->rx_idx++] = data; } return; } if(int_status & I2C_SLAVE_RX_FIFO_READY) { this_i2cs->status = I2C_WRITE; reg_8b_write(this_i2cs->base_addr | I2C_SLAVE_INT_STATUS, int_status & SET_ALL_BITS);//clear all int bits reg_8b_read(this_i2cs->base_addr | I2C_SLAVE_DATA_BUFFER, &data); this_i2cs->rx_buffer[this_i2cs->rx_idx++] = data;//get one byte first /*if data is need to parse if(data == READ_CMD) { i2c_slave_clk_stretch(this_i2cs,1); i2c_slave_data_write(this_i2cs,this_i2cs->tx_buffer,this_i2cs->tx_size); i2c_slave_clk_stretch(this_i2cs,0); } */ } return; }