/* * ================================================================= >>>>>>>>>>>>>>>>>>>>>>> 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 "spi_slave.h" #include "spi_slave_regs.h" #include "hal.h" uint8_t spi_slave_init(struct spis_instance *this_spis, uint32_t base_addr, uint32_t data_width, uint8_t clock_polarity, uint8_t clock_phase, uint32_t fifo_width, uint8_t daisy_chain, uint8_t ss_polarity,uint32_t *slave_tx_buf,uint32_t *slave_rx_buf) { uint8_t spi_config = 0; this_spis->base_addr = base_addr; this_spis->data_width = data_width; this_spis->fifo_width = fifo_width; this_spis->spi_cpol = clock_polarity; this_spis->spi_cpha = clock_phase; this_spis->daisy_chain = daisy_chain; this_spis->ss_polarity = ss_polarity; this_spis->rx_start_flag = 1; this_spis->tx_start_flag = 0; this_spis->tx_buffer=slave_tx_buf; this_spis->rx_buffer=slave_rx_buf; spi_config = (ss_polarity << 6) | (data_width << 4) | (daisy_chain << 2) | (clock_polarity << 1) | clock_phase; /** reg_8b_modify(this_spis->base_addr | SPI_SLAVE_CFG, SPI_SLAVE_SS_POL | SPI_SLAVE_DATA_WIDTH_MASK | SPI_SLAVE_DAISY_CHAIN | SPI_SLAVE_CPOL | SPI_SLAVE_CPHA, spi_config); */ reg_8b_write(this_spis->base_addr | SPI_SLAVE_FIFO_RST, SPI_SLAVE_TX_FIFO_RST | SPI_SLAVE_RX_FIFO_RST); reg_8b_write(this_spis->base_addr | SPI_SLAVE_BYTE_COUNT_RST, 0xff); reg_8b_write(this_spis->base_addr | SPI_SLAVE_FIFO_RST, 0); reg_8b_write(this_spis->base_addr | SPI_SLAVE_INT_ENABLE, 0x01);//enable all interrupts reg_8b_write(this_spis->base_addr | SPI_SLAVE_INT_STATUS, 0xff); return 0; } uint8_t spi_slave_config(struct spis_instance * this_spis, uint32_t data_width, uint8_t clock_polarity, uint8_t clock_phase, uint8_t daisy_chain, uint8_t ss_polarity) { uint8_t spi_slave_config = 0x00; spi_slave_config = (ss_polarity << 6) | (data_width << 4) | (daisy_chain << 2) | (clock_polarity << 1)| clock_phase; //reg_8b_modify(this_spis->base_addr | SPI_SLAVE_CFG,SPI_SLAVE_SS_POL | SPI_SLAVE_DATA_WIDTH_MASK| SPI_SLAVE_DAISY_CHAIN | SPI_SLAVE_CPOL| SPI_SLAVE_CPHA, spi_slave_config); reg_8b_write(this_spis->base_addr | SPI_SLAVE_CFG, spi_slave_config); // set the byte count register //reg_8b_write(this_spis->base_addr | SPI_SLAVE_TARGET_WORD_COUNT, 4); return 0; } void spi_slave_callback(struct spis_instance *this_spis) { if (this_spis->rx_buffer[0] != 0) { this_spis->tx_start_flag = 1; } } uint8_t spi_slave_data_read(struct spis_instance *this_spis,uint32_t *data,uint8_t length) { uint8_t count = 0; if(this_spis == NULL) return -1; /* data get*/ while(countbase_addr | SPI_SLAVE_RD_DATA, &data[count]); count++; } #if 0 count=0; /*data parse*/ if(data[0]==0x03) { for(count=0;count<4;count++) { reg_32b_write(this_spis->base_addr | SPI_SLAVE_WR_DATA,data[count]); } } #endif this_spis->status=SPI_SLAVE_READ; return 0; } uint8_t spi_slave_data_write(struct spis_instance *this_spis,uint32_t *data,uint8_t length) { uint8_t count = 0; if(this_spis == NULL) return -1; for(count=0;countbase_addr | SPI_SLAVE_WR_DATA,data[count]); } this_spis->status=SPI_SLAVE_WRITE; return 0; } uint8_t spi_slave_get_status(struct spis_instance *this_spis,uint8_t *status) { if(this_spis == NULL) return -1; *status=this_spis->status; return 0; } void spi_slave_isr(void *ctx) { volatile struct spis_instance *this_spis = (struct spis_instance *) ctx; uint8_t buffer_status; uint8_t fifo_status; uint32_t byte_tx_cnt = 0; uint32_t byte_rx_cnt = 0; reg_8b_write(this_spis->base_addr | SPI_SLAVE_FIFO_RST, SPI_SLAVE_TX_FIFO_RST | SPI_SLAVE_RX_FIFO_RST); reg_8b_write(this_spis->base_addr | SPI_SLAVE_FIFO_RST, 0); while (this_spis->rx_start_flag) { reg_8b_read(this_spis->base_addr | SPI_SLAVE_INT_STATUS, &buffer_status); reg_8b_read(this_spis->base_addr | SPI_SLAVE_FIFO_STATUS, &fifo_status); if (buffer_status & SPI_INT_RX_BUFFER_READY) { while((fifo_status & SPI_SLAVE_RX_FIFO_EMPTY)==0x00) { reg_32b_read(this_spis->base_addr | SPI_SLAVE_RD_DATA, this_spis->rx_buffer); this_spis->rx_buffer++; byte_rx_cnt++; if(byte_rx_cnt==4) break; } reg_8b_write(this_spis->base_addr | SPI_SLAVE_BYTE_COUNT_RST, 0xff); reg_8b_write(this_spis->base_addr | SPI_SLAVE_TARGET_WORD_COUNT, 4); reg_8b_write(this_spis->base_addr | SPI_SLAVE_INT_STATUS, 0xff); for(byte_tx_cnt=0;byte_tx_cnt<4;byte_tx_cnt++) { reg_32b_write(this_spis->base_addr | SPI_SLAVE_WR_DATA, *(this_spis->tx_buffer)); this_spis->tx_buffer++; } this_spis->rx_start_flag=0; this_spis->tx_start_flag=1; } } if(this_spis->tx_start_flag) { if (buffer_status & SPI_INT_TR_COMPLETE) { reg_8b_write(this_spis->base_addr | SPI_SLAVE_FIFO_RST, SPI_SLAVE_TX_FIFO_RST | SPI_SLAVE_RX_FIFO_RST); reg_8b_write(this_spis->base_addr | SPI_SLAVE_BYTE_COUNT_RST, 0xff); reg_8b_write(this_spis->base_addr | SPI_SLAVE_FIFO_RST, 0); reg_8b_write(this_spis->base_addr | SPI_SLAVE_INT_STATUS, 0xff); } } }