/* * ================================================================= >>>>>>>>>>>>>>>>>>>>>>> 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_master.h" #include "spi_master_regs.h" #include "hal.h" uint8_t spi_master_init(struct spim_instance *this_spim, uint32_t base_addr, uint8_t slave_count, uint8_t data_width, uint8_t clk_polarity, uint8_t clk_phase, uint8_t interrupts_en) { if(this_spim == NULL) return -1; this_spim->base_address = base_addr; this_spim->slave_count = slave_count; this_spim->data_width = data_width; this_spim->spi_clk_polarity = clk_polarity; this_spim->spi_clk_phase = clk_phase; this_spim->interrupts_en_bits = interrupts_en; // clear the tx/rx fifo reg_8b_write(this_spim->base_address | SPI_MASTER_FIFO_RST, SPI_MASTER_TX_FIFO_RST|SPI_MASTER_RX_FIFO_RST); // enable all the INTs by default reg_8b_write(this_spim->base_address | SPI_MASTER_INT_ENABLE,0xff); reg_8b_write(this_spim->base_address | SPI_MASTER_BYTE_COUNT_RST, 0xff); // manually clear the FIFO reset flag reg_8b_write(this_spim->base_address | SPI_MASTER_FIFO_RST, 0); return 0; } uint8_t spi_master_config(struct spim_instance *this_spim, spim_data_width data_width, uint16_t prescaler, uint8_t clk_polarity, uint8_t clk_phase,uint8_t ssnp) { uint8_t spi_config = 0; uint8_t status = 0; if(this_spim == NULL) return -1; spi_config = (data_width << 3) | (ssnp<<2) |(clk_polarity << 1) | clk_phase; reg_8b_modify(this_spim->base_address | SPI_MASTER_SPI_CFG,SPI_CFG_DATA_WIDTH_MASK | SPI_CFG_CPOL_MASK | SPI_CFG_CPHA_MASK | SPI_CFG_SSNP_MASK, spi_config); //reg_8b_write(this_spim->base_address | SPI_MASTER_SPI_CFG,0); reg_8b_write(this_spim->base_address | SPI_MASTER_CLK_PRESCALER_LOW, prescaler & 0xff); reg_8b_write(this_spim->base_address | SPI_MASTER_CLK_PRESCALER_HIGH, prescaler >> 8); reg_8b_write(this_spim->base_address | SPI_MASTER_BYTE_COUNT_RST, 0xff); return status; } void delay(unsigned int count) { for(unsigned int i=0;ibase_address | SPI_MASTER_FIFO_RST, SPI_MASTER_TX_FIFO_RST|SPI_MASTER_RX_FIFO_RST); // clear all the interrupt bits reg_8b_write(this_spim->base_address | SPI_MASTER_INT_STATUS, 0xff); // clear the tx/rx fifo reset flag reg_8b_write(this_spim->base_address | SPI_MASTER_FIFO_RST, 0); reg_8b_write(this_spim->base_address | SPI_MASTER_BYTE_COUNT_RST, 0xff); // set the byte count register reg_8b_write(this_spim->base_address | SPI_MASTER_TARGET_WORD_COUNT,byte_out_size+byte_in_size); while(1) { reg_8b_read(this_spim->base_address | SPI_MASTER_INT_STATUS, &int_status); // write the data into the out buffer if(int_status & (SPI_INT_TX_BUFFER_FULL)) { reg_8b_write(this_spim->base_address | SPI_MASTER_INT_STATUS, int_status & 0xff); break; } if(int_status & (SPI_INT_TRAN_CMP)) { reg_8b_read(this_spim->base_address | SPI_MASTER_FIFO_STATUS, &fifo); if((fifo & SPI_MASTER_RX_FIFO_EMPTY) == 0) { for(byte_in_cnt=0;byte_in_cnt < byte_in_size;byte_in_cnt++) { reg_32b_read(this_spim->base_address | SPI_MASTER_RD_DATA, data_buffer_in); data_buffer_in++; } } reg_8b_write(this_spim->base_address | SPI_MASTER_INT_STATUS, int_status & 0xff); break; } else { if(byte_out_cnt < byte_out_size) { reg_32b_write(this_spim->base_address | SPI_MASTER_WR_DATA, *data_buffer_out); delay(100); data_buffer_out++; } else if(byte_out_cnt < byte_in_size + byte_out_size) { reg_32b_write(this_spim->base_address | SPI_MASTER_WR_DATA, 0xffffffff); // write dummy byte delay(100); } byte_out_cnt++; } } return ret_val; } uint8_t spi_device_select(struct spim_instance *this_spim, uint8_t enable_slave) { uint8_t status = 0; if(this_spim == NULL) return -1; reg_8b_write(this_spim->base_address | SPI_MASTER_SLAVE_SEL, enable_slave); return status; } void spi_master_isr(void* ctx) { return; }