Esempio n. 1
0
/**
*
* QSPI bus begin transaction function. 
*
* @param    dev          - QSPI device handle
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_transaction_begin(cyg_spi_device *dev)
{
    entry_debug();
    cyg_qspi_xc7z_device_t *xc7z_qspi_dev = (cyg_qspi_xc7z_device_t *) dev;
    cyg_qspi_xc7z_bus_t *qspi_bus =
      (cyg_qspi_xc7z_bus_t *)xc7z_qspi_dev->qspi_device.spi_bus;
    cyg_uint32 val;

    if (!xc7z_qspi_dev->init)
    {
        xc7z_qspi_dev->init = true;
        qspi_xc7z_calc_bratediv(xc7z_qspi_dev);
    }

    // Configure SPI channel 0 - this is the only channel we
    // use for all devices since we drive chip selects manually
    HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, val);
    
    val &= (~XQSPIPS_CR_CPOL_MASK) & (~XQSPIPS_CR_CPHA_MASK);

    if (1 == xc7z_qspi_dev->cl_pol)
        val |= XQSPIPS_CR_CPOL_MASK;

    if (1 == xc7z_qspi_dev->cl_pha)
        val |= XQSPIPS_CR_CPHA_MASK;

    // Write new settings
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, val);
}
Esempio n. 2
0
/**
*
* QSPI bus transfer function in poll mode without IRQ. 
*
* @param    qspi_bus     - QSPI bus handle
* @param    count        - Number of bytes to transmit.
* @param    tx_data      - Pointer to TX buffer.
* @param    rx_data      - Pointer to RX buffer.
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_transfer_polled(cyg_qspi_xc7z_device_t *dev,
                         cyg_uint32             count,
                         const cyg_uint8       *tx_data,
                         cyg_uint8             *rx_data)
{
    entry_debug();
    cyg_uint32 val;
    cyg_uint32 data;
    cyg_qspi_xc7z_bus_t *qspi_bus = (cyg_qspi_xc7z_bus_t *)dev->qspi_device.spi_bus;
   
    // Set tx buf pointer and counter
    if (NULL != tx_data)
      HAL_DCACHE_STORE(tx_data, count);
    // Set rx buf pointer and counter
    if (NULL != rx_data)
      HAL_DCACHE_FLUSH(rx_data, count);

    while(qspi_bus->us_rx_bytes)
    {
/*  if ((qspi_bus->us_tx_bytes) &&
        ((qspi_bus->uc_tx_instr != XQSPIPS_FLASH_OPCODE_FAST_READ) ||
         (qspi_bus->uc_tx_instr != XQSPIPS_FLASH_OPCODE_DUAL_READ) ||
         (qspi_bus->uc_tx_instr != XQSPIPS_FLASH_OPCODE_QUAD_READ))) {*/
	qspi_xc7z_fill_tx_fifo(qspi_bus, count);
//    }
        
        HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET,     val);

	val |= XQSPIPS_CR_MANSTRT_MASK | XQSPIPS_CR_SSFORCE_MASK;
        HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET,    val);
        
        /* Read out the data from the RX FIFO */

        HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, val);

        while ((val & XQSPIPS_IXR_RXNEMPTY_MASK) && (qspi_bus->us_rx_bytes > 0) ) {
            
            HAL_READ_UINT32(qspi_bus->base + XQSPIPS_RXD_OFFSET,    data);
		if (qspi_bus->lp_rx_buf != NULL) {

            if (qspi_bus->us_rx_bytes < 4)
                qspi_xc7z_copy_read_data(qspi_bus, data, qspi_bus->us_rx_bytes);
            else
                qspi_xc7z_copy_read_data(qspi_bus, data, 4);
            } else {
	    	qspi_bus->us_rx_bytes -=  (qspi_bus->us_rx_bytes < 4) ? qspi_bus->us_rx_bytes : 4;
	    }
            HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET,     val);
    }
    }

    
}
Esempio n. 3
0
/**
*
* QSPI bus finalize transaction function. 
*
* @param    dev          - QSPI device handle
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_transaction_end(cyg_spi_device* dev)
{
    entry_debug();
    cyg_qspi_xc7z_device_t * xc7z_qspi_dev = (cyg_qspi_xc7z_device_t *)dev;
    cyg_qspi_xc7z_bus_t *qspi_bus =
      (cyg_qspi_xc7z_bus_t *)xc7z_qspi_dev->qspi_device.spi_bus;

    qspi_xc7z_drop_cs((cyg_qspi_xc7z_device_t *) dev);

    // Disable device
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_ER_OFFSET, 0x00);

}
Esempio n. 4
0
/**
*
* QSPI bus RX prepare data (for Zynq specific FIFO).
* For correct working with unaligned data, used 1-byte transactions.
*
* @param    qspi_bus     - QSPI bus handle
* @param    data         - 4-byte variable which RX data has.
* @param    len_burst    - Size of data in bytes [1..4].
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_copy_read_data(cyg_qspi_xc7z_bus_t    *qspi_bus,
                         cyg_uint32             data,
                         cyg_uint8              len_burst
                         )
{
    entry_debug();
    cyg_uint8 btemp;

    if (qspi_bus->lp_rx_buf) {
        switch (len_burst) {
        case 1:
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = (data >> 24) & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            break;
        case 2:
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = (data >> 16) & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = (data >> 24) & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            break;
        case 3:
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = (data >> 8) & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = (data >> 16) & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = (data >> 24) & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            break;
        case 4:
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = data & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = (data >> 8) & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = (data >> 16) & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            *((cyg_uint8 *)qspi_bus->lp_rx_buf) = (data >> 24) & 0xFF;
            qspi_bus->lp_rx_buf += 1;
            break;
        default:
            /* This will never execute */
            break;
        }
    }
    if (qspi_bus->us_rx_bytes < len_burst)
        qspi_bus->us_rx_bytes = 0;
    else 
        qspi_bus->us_rx_bytes -= len_burst;
}
Esempio n. 5
0
internal void dl_list_debug( entry* head ) {

	printf("Debug list %p\n", (void*) head );

	if( head != NULL ) {
		entry* start = head;
		entry* current = head;
		do {
			entry_debug( current );
			node_debug( current->node );
			current = current->next;
		} while( current != start );

	}
}
Esempio n. 6
0
/**
*
* QSPI bus drop CS function
*
* @param    dev     - QSPI device handle
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_drop_cs(cyg_qspi_xc7z_device_t *dev)
{
	entry_debug();
    cyg_qspi_xc7z_bus_t *qspi_bus = (cyg_qspi_xc7z_bus_t *)dev->qspi_device.spi_bus;

    if (!qspi_bus->cs_up)
       return;

    // Drop CS

    CYGACC_CALL_IF_DELAY_US(dev->cs_dw_udly);
    qspi_xc7z_set_npcs(qspi_bus, 1);
    qspi_bus->cs_up = false;
}
Esempio n. 7
0
/**
*
* QSPI bus control chip select signal
*
* @param    qspi_bus     - QSPI bus handle
* @param    val          - 1-CS is High, 0-CS is Low.
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_set_npcs(cyg_qspi_xc7z_bus_t *qspi_bus,int val)
{
    entry_debug();
    cyg_uint32 reg;
    
    HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET,     reg);
    
    if (!val)
        reg &= ~(1 << XQSPIPS_CR_SSCTRL_SHIFT);
    else
        reg |= (1 << XQSPIPS_CR_SSCTRL_SHIFT);
    
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET,    reg);
    
}
Esempio n. 8
0
/**
*
* QSPI bus initialization function from eCOS
*
* @return   none
*
*****************************************************************************/
void cyg_qspi_xc7z_bus_init(void)
{
  entry_debug();
#ifdef CYGHWR_DEVS_QSPI_ARM_XC7Z
   // NOTE: here we let the SPI controller control
   //       the data in, out and clock signals, but
   //       we need to handle the chip selects manually
   //       in order to achieve better chip select control
   //       in between transactions.

   // Put SPI MISO, MOSI and SPCK pins into peripheral mode
   
   qspi_xc7z_init_bus(&cyg_qspi_xc7z_bus0);
#endif

}
Esempio n. 9
0
// Remove a node from the cache in order: clean data, clean index, dirty data, dirty index
// Make sure we don't evict ones with refcount > 0 as they are in use
node* node_cache_evict_node( node_cache* nc ) {

	node* result = NULL;

	u32 evict_order[4] = { NC_LIST_DATA_CLEAN, NC_LIST_INDEX_CLEAN, NC_LIST_DATA_DIRTY, NC_LIST_INDEX_DIRTY };

	for( u32 i=0; i<4; i++ ) {
		entry* list = nc->list[ evict_order[i] ];
		printf("Trying to evict from list %d\n", i);
		if( list != NULL ) {
			dl_list_debug( list );
			entry* current = list;
			do {
				if( current->refcount == 0 ) {
					node* to_be_evicted = current->node;
					printf("\tEviction candidate found: \n");
					entry_debug( current );
					node_debug( to_be_evicted );

					node_store_on_disk( to_be_evicted );
					to_be_evicted->flags = 0; // reset all, though only would need ~NODE_FLAG_USED
					result = to_be_evicted; // we can immediately reuse this one if needed

					u32 bucket_entry_index = index_from_node_pointer( nc, to_be_evicted );
					entry* bucket_entry = &nc->bucket_entries[bucket_entry_index];
					u32 bucket_index = bucket_index_from_node( to_be_evicted );
					nc->bucket[bucket_index] = dl_list_remove( nc->bucket[bucket_index], bucket_entry );
					nc->list[ evict_order[i] ] = dl_list_remove( list, current );
					dl_list_debug( nc->list[ evict_order[i] ] );
					c.evicts[ evict_order[i] ]++;
					goto DONE;
				}
				current = current->next;
			} while( current != list );
		}
	}

	assert( result != NULL );
	if( result == NULL ) {
		printf("[FAIL]: Could not evict any nodes. Maybe all are in use? (refcount > 0)\n");
	}

DONE:
	return result;
}
Esempio n. 10
0
/**
*
* QSPI bus send flash memory instruction function (for Zynq specific QSPI HW). 
*
* @param    qspi_bus     - QSPI bus handle
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_send_instruction(cyg_qspi_xc7z_bus_t    *qspi_bus)
{
    entry_debug();
    cyg_uint32 index;
    cyg_uint8  instruction;
    cyg_uint32 data = 0;
    
    qspi_bus->uc_tx_instr = 0;
    
    if ((!qspi_bus->lp_tx_buf) || (!qspi_bus->us_tx_bytes))
        return;
        
    if (*((cyg_uint8 *)qspi_bus->lp_tx_buf) == 0)
        return;
        
    instruction  = *((cyg_uint8 *)qspi_bus->lp_tx_buf);

    for (index = 0; index < ARRAY_SIZE(qpifFlashInst); index++)
        if (instruction == qpifFlashInst[index].OpCode)
            break;    
    
    if (index == ARRAY_SIZE(qpifFlashInst)) {
        diag_printf("illegal instruction %02X\n",instruction);
        return;
    }
        
    qspi_bus->uc_tx_instr = qpifFlashInst[index].OpCode;
    
    /* Get the instruction */
    qspi_xc7z_copy_write_data(qspi_bus, &data, qpifFlashInst[index].InstSize);

    /* Write the instruction to LSB of the FIFO. The core is
     * designed such that it is not necessary to check whether the
     * write FIFO is full before writing. However, write would be
     * delayed if the user tries to write when write FIFO is full
     */
    HAL_WRITE_UINT32(qspi_bus->base + qpifFlashInst[index].TxOffset, data);
}
Esempio n. 11
0
/**
*
* QSPI bus transaction transfer function. 
*
* @param    dev          - QSPI device handle
* @param    polled       - Poll mode flash: 1-Polled, 0-IRQ
* @param    count        - Number of bytes to transmit.
* @param    tx_data      - Pointer to TX buffer.
* @param    rx_data      - Pointer to RX buffer.
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_transaction_transfer(cyg_spi_device  *dev,
                              cyg_bool         polled,
                              cyg_uint32       count,
                              const cyg_uint8 *tx_data,
                              cyg_uint8       *rx_data,
                              cyg_bool         drop_cs)
{
    entry_debug();
    cyg_qspi_xc7z_device_t *xc7z_qspi_dev = (cyg_qspi_xc7z_device_t *) dev;
    cyg_qspi_xc7z_bus_t *qspi_bus =
      (cyg_qspi_xc7z_bus_t *)xc7z_qspi_dev->qspi_device.spi_bus;

    // Setup poiner to buffers
    qspi_bus->lp_tx_buf = tx_data;
    qspi_bus->lp_rx_buf = rx_data;
    qspi_bus->us_tx_bytes = count;
    qspi_bus->us_rx_bytes = count;

    // Select the device if not already selected
    qspi_xc7z_start_transfer(xc7z_qspi_dev);
    
    // Perform the transfer
    if (polled)
        qspi_xc7z_transfer_polled(xc7z_qspi_dev, count, tx_data, rx_data);
    else
        qspi_xc7z_transfer(xc7z_qspi_dev, count, tx_data, rx_data);

    // Deselect the device if requested
    if (drop_cs)
        qspi_xc7z_drop_cs(xc7z_qspi_dev);
        
    // Clear pointers
    qspi_bus->lp_tx_buf = 0;
    qspi_bus->lp_rx_buf = 0;
    qspi_bus->us_tx_bytes = 0;
    qspi_bus->us_rx_bytes = 0;
}
Esempio n. 12
0
/**
*
* QSPI bus start transfer function
*
* @param    dev     - QSPI device handle
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_start_transfer(cyg_qspi_xc7z_device_t *dev)
{
    entry_debug();

    cyg_qspi_xc7z_bus_t *qspi_bus = (cyg_qspi_xc7z_bus_t *)dev->qspi_device.spi_bus;

    if (qspi_bus->cs_up)
        return;
    
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_ER_OFFSET,    XQSPIPS_ER_ENABLE_MASK);

    // Force minimal delay between two transfers - in case two transfers
    // follow each other w/o delay, then we have to wait here in order for
    // the peripheral device to detect cs transition from inactive to active.
    CYGACC_CALL_IF_DELAY_US(dev->tr_bt_udly);

    // Raise CS
    qspi_xc7z_set_npcs(qspi_bus, 0);
    CYGACC_CALL_IF_DELAY_US(dev->cs_up_udly);

    qspi_bus->cs_up = true;
    qspi_bus->uc_tx_instr = 0;
}
Esempio n. 13
0
/**
*
* QSPI bus set config function. 
*
* @param    dev          - QSPI device handle
* @param    key          - IO control number of key
* @param    buf          - Pointer to BUF
* @param    len          - Pointer to length
*
* @return   Status of operation: ENOERR - all good, -EINVAL - fail to find IO control number
*
*****************************************************************************/
static int
qspi_xc7z_set_config(cyg_spi_device *dev,
                    cyg_uint32      key,
                    const void     *buf,
                    cyg_uint32     *len)
{
    entry_debug();
    cyg_qspi_xc7z_device_t *xc7z_qspi_dev = (cyg_qspi_xc7z_device_t *) dev;

    switch (key)
    {
        case CYG_IO_SET_CONFIG_SPI_CLOCKRATE:
        {
            if (*len != sizeof(cyg_uint32))
                return -EINVAL;
            else
            {
                cyg_uint32 cl_brate     = *((cyg_uint32 *)buf);
                cyg_uint32 old_cl_brate = xc7z_qspi_dev->cl_brate;

                xc7z_qspi_dev->cl_brate = cl_brate;

                if (!qspi_xc7z_calc_bratediv(xc7z_qspi_dev))
                {
                    xc7z_qspi_dev->cl_brate = old_cl_brate;
                    qspi_xc7z_calc_bratediv(xc7z_qspi_dev);
                    return -EINVAL;
                }
            }
        }
        break;
        default:
            return -EINVAL;
    }
    return ENOERR;
}
Esempio n. 14
0
/**
*
* QSPI bus transfer with IRQ function. 
*
* @param    qspi_bus     - QSPI bus handle
* @param    count        - Number of bytes to transmit.
* @param    tx_data      - Pointer to TX buffer.
* @param    rx_data      - Pointer to RX buffer.
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_transfer(cyg_qspi_xc7z_device_t *dev,
                  cyg_uint32             count,
                  const cyg_uint8       *tx_data,
                  cyg_uint8             *rx_data)
{	
    entry_debug();
    cyg_qspi_xc7z_bus_t *qspi_bus = (cyg_qspi_xc7z_bus_t *)dev->qspi_device.spi_bus;
    cyg_uint32 val;
    
    // Enable device
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_ER_OFFSET, XQSPIPS_ER_ENABLE_MASK);
    
    // Enable manual start
    HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET,  val);
    val |= XQSPIPS_CR_MANSTRTEN_MASK | XQSPIPS_CR_SSFORCE_MASK;
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, val);

    // Set tx buf pointer and counter
    if (NULL != tx_data)
        HAL_DCACHE_STORE(tx_data, count);

    // Set rx buf pointer and counter
    if (NULL != rx_data)
        HAL_DCACHE_FLUSH(rx_data, count);
        
    // Send first instruction
    if(qspi_bus->uc_tx_instr == 0) 	 
	    qspi_xc7z_send_instruction(qspi_bus);
    {
        
       if ((qspi_bus->us_tx_bytes) && 
        ((qspi_bus->uc_tx_instr != XQSPIPS_FLASH_OPCODE_FAST_READ) ||
         (qspi_bus->uc_tx_instr != XQSPIPS_FLASH_OPCODE_DUAL_READ) ||
         (qspi_bus->uc_tx_instr != XQSPIPS_FLASH_OPCODE_QUAD_READ) )) 
            qspi_xc7z_fill_tx_fifo(qspi_bus,count);
            
        // Enable the QSPI int events we are interested in
        HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_IER_OFFSET,
                        XQSPIPS_IXR_TXOW_MASK | XQSPIPS_IXR_MODF_MASK); 
                        
        HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET,     val);
        val |= XQSPIPS_CR_MANSTRT_MASK;
        HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET,    val);
        
        cyg_drv_mutex_lock(&qspi_bus->transfer_mx);
        {
            qspi_bus->transfer_end = false;

            // Unmask the SPI int
            cyg_drv_interrupt_unmask(qspi_bus->interrupt_number);
            
            // Wait for its completion
            cyg_drv_dsr_lock();
            {
                while (!qspi_bus->transfer_end)
                    cyg_drv_cond_wait(&qspi_bus->transfer_cond);
                
            }
            cyg_drv_dsr_unlock();
        }
        
        cyg_drv_mutex_unlock(&qspi_bus->transfer_mx);

    }
}
Esempio n. 15
0
/**
*
* QSPI bus TX prepare data function (for Zynq specific FIFO). 
*
* @param    qspi_bus     - QSPI bus handle
* @param    data         - 4-byte variable which TX data has.
* @param    len_burst    - Size of data in bytes [1..4].
*
* @return   none
*
*****************************************************************************/
static void
qspi_xc7z_copy_write_data(cyg_qspi_xc7z_bus_t    *qspi_bus,
                         cyg_uint32              *data,
                         cyg_uint8                len_burst
                         )
{
	entry_debug();
	cyg_uint8 *d = (cyg_uint8*)qspi_bus->lp_tx_buf;
	int i;
    if (qspi_bus->lp_tx_buf) {
        switch (len_burst) {
        case 1:
            *data = *((cyg_uint8 *)qspi_bus->lp_tx_buf);
            qspi_bus->lp_tx_buf += 1;
            *data |= 0xFFFFFF00;
            break;
        case 2:
            *data = d[0] | (d[1] << 8);
            qspi_bus->lp_tx_buf += 2;
            *data |= 0xFFFF0000;
            break;
        case 3:
            *data = *((cyg_uint16 *)qspi_bus->lp_tx_buf);
            qspi_bus->lp_tx_buf += 2;
            *data |= (*((cyg_uint8 *)qspi_bus->lp_tx_buf) << 16);
            qspi_bus->lp_tx_buf += 1;
            *data |= 0xFF000000;
            break;
        case 4:
            *data = *((cyg_uint32 *)qspi_bus->lp_tx_buf);
            qspi_bus->lp_tx_buf += 4;
            break;
        default:
            /* This will never execute */
            break;
        }
    } else {
        switch (len_burst) {
        case 1:
            *data = 0;
            *data |= 0xFFFFFF00;
            break;
        case 2:
            *data = 0;
            *data |= 0xFFFF0000;
            break;
        case 3:
            *data = 0;
            *data |= 0xFF000000;
            break;
        case 4:
            *data = 0;
            break;
        default:
            /* This will never execute */
            break;
        }    
    }
    if (qspi_bus->us_tx_bytes < len_burst)
        qspi_bus->us_tx_bytes = 0;
    else 
        qspi_bus->us_tx_bytes -= len_burst;
}
Esempio n. 16
0
/**
*
* QSPI bus initialization function
*
* @param    qspi_bus     - Driver handle
*
* @return   none
*
*****************************************************************************/
static void qspi_xc7z_init_bus(cyg_qspi_xc7z_bus_t * qspi_bus)
{
    entry_debug();
    volatile cyg_uint32 reg;
    
    // Create and attach SPI interrupt object
    cyg_drv_interrupt_create(qspi_bus->interrupt_number,
                             4,
                             (cyg_addrword_t)qspi_bus,
                             qspi_xc7z_ISR,
                             qspi_xc7z_DSR,
                             &qspi_bus->qspi_interrupt_handle,
                             &qspi_bus->qspi_interrupt);

    cyg_drv_interrupt_attach(qspi_bus->qspi_interrupt_handle);
    cyg_drv_interrupt_mask(qspi_bus->interrupt_number);  

    // Init transfer mutex and condition
    cyg_drv_mutex_init(&qspi_bus->transfer_mx);
    cyg_drv_cond_init(&qspi_bus->transfer_cond,
                      &qspi_bus->transfer_mx);

    // Init flags
    qspi_bus->transfer_end = true;
    qspi_bus->cs_up        = false;
    
    // Unlock SLCR regs
    HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCR_UNLOCK_OFFSET, XSLCR_UNLOCK_KEY);
    
    // Enable clock to QSPI module
    HAL_READ_UINT32( XC7Z_SYS_CTRL_BASEADDR + XSLCRAPER_CLK_CTRL_OFFSET, reg);
    reg |= XSLCRAPER_CLK_CTRL_QSPI_EN;
    HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRAPER_CLK_CTRL_OFFSET, reg);
    
    // Lock SLCR regs
    HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCR_LOCK_OFFSET, XSLCR_LOCK_KEY);
    
    // Soft reset the SPI controller
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_ER_OFFSET,        0x00);
   
    //TODO changed, originally was just setting a value without reading
    HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, reg);
    reg &= (1 << 17); // preserve the reserved bit which is described as "do not modify"
    reg |= (1 << 31); 
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, reg);
    
    // Disable linear mode
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_LQSPI_CR_OFFSET,  0x00);
    
    // Clear status
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET,        0x7F);
    
    // Clear the RX FIFO
    HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, reg);
    while (reg & XQSPIPS_IXR_RXNEMPTY_MASK)
    {
        HAL_READ_UINT32(qspi_bus->base + XQSPIPS_RXD_OFFSET, reg);
        HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET,  reg);
    }
    
    HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET,         reg);
    reg &= 0xFBFFFFFF; /* Set little endian mode of TX FIFO */
    reg |= (XQSPIPS_CR_IFMODE_MASK | XQSPIPS_CR_MANSTRTEN_MASK | XQSPIPS_CR_SSFORCE_MASK |
            XQSPIPS_CR_SSCTRL_MASK | XQSPIPS_CR_DATA_SZ_MASK | XQSPIPS_CR_MSTREN_MASK);
    HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET,         reg);
    
    // Configure SPI pins
    // All pins was configured in HAL

    // Call upper layer bus init
    CYG_SPI_BUS_COMMON_INIT(&qspi_bus->qspi_bus);
}