コード例 #1
0
ファイル: spi_dw_legacy.c プロジェクト: zmole945/zephyr
void spi_dw_isr(void *arg)
{
	struct device *dev = (struct device *)arg;
	const struct spi_dw_config *info = dev->config->config_info;
	u32_t error = 0;
	u32_t int_status;

	int_status = read_isr(info->regs);

	SYS_LOG_DBG("SPI int_status 0x%x - (tx: %d, rx: %d)",
		    int_status, read_txflr(info->regs), read_rxflr(info->regs));

	if (int_status & DW_SPI_ISR_ERRORS_MASK) {
		error = 1;
		goto out;
	}

	if (int_status & DW_SPI_ISR_RXFIS) {
		pull_data(dev);
	}

	if (int_status & DW_SPI_ISR_TXEIS) {
		push_data(dev);
	}

out:
	clear_interrupts(info->regs);
	completed(dev, error);
}
コード例 #2
0
ファイル: spi_dw.c プロジェクト: coldnew/zephyr-project-fork
static void push_data(struct device *dev)
{
	struct spi_dw_config *info = dev->config->config_info;
	struct spi_dw_data *spi = dev->driver_data;
	uint32_t data = 0;
	uint32_t f_tx;
	DBG_COUNTER_INIT();

	f_tx = DW_SPI_FIFO_DEPTH - read_txflr(info->regs) -
					read_rxflr(info->regs) - 1;
	while (f_tx) {
		if (spi->tx_buf && spi->tx_buf_len > 0) {
			switch (spi->dfs) {
			case 1:
				data = UNALIGNED_GET((uint8_t *)(spi->tx_buf));
				break;
			case 2:
				data = UNALIGNED_GET((uint16_t *)(spi->tx_buf));
				break;
#ifndef CONFIG_ARC
			case 4:
				data = UNALIGNED_GET((uint32_t *)(spi->tx_buf));
				break;
#endif
			}

			spi->tx_buf += spi->dfs;
			spi->tx_buf_len--;
		} else if (spi->rx_buf && spi->rx_buf_len > 0) {
			/* No need to push more than necessary */
			if (spi->rx_buf_len - spi->fifo_diff <= 0) {
				break;
			}

			data = 0;
		} else {
			/* Nothing to push anymore */
			break;
		}

		write_dr(data, info->regs);
		f_tx--;
		spi->fifo_diff++;
		DBG_COUNTER_INC();
	}

	if (!spi->tx_buf_len && !spi->rx_buf_len) {
		write_txftlr(0, info->regs);
	}

	DBG("Pushed: %d\n", DBG_COUNTER_RESULT());
}
コード例 #3
0
ファイル: spi_dw_legacy.c プロジェクト: zmole945/zephyr
static void push_data(struct device *dev)
{
	const struct spi_dw_config *info = dev->config->config_info;
	struct spi_dw_data *spi = dev->driver_data;
	u32_t data = 0;
	u32_t f_tx;
	DBG_COUNTER_INIT();

	if (spi->rx_buf) {
		f_tx = DW_SPI_FIFO_DEPTH - read_txflr(info->regs) -
					read_rxflr(info->regs);
		if ((int)f_tx < 0) {
			f_tx = 0; /* if rx-fifo is full, hold off tx */
		}
	} else {
		f_tx = DW_SPI_FIFO_DEPTH - read_txflr(info->regs);
	}

	if (f_tx && (spi->tx_buf_len == 0)) {
		/* room in fifo, yet nothing to send */
		spi->last_tx = 1; /* setting last_tx indicates TX is done */
	}

	while (f_tx) {
		if (spi->tx_buf && spi->tx_buf_len > 0) {
			switch (spi->dfs) {
			case 1:
				data = UNALIGNED_GET((u8_t *)(spi->tx_buf));
				break;
			case 2:
				data = UNALIGNED_GET((u16_t *)(spi->tx_buf));
				break;
#ifndef CONFIG_ARC
			case 4:
				data = UNALIGNED_GET((u32_t *)(spi->tx_buf));
				break;
#endif
			}

			spi->tx_buf += spi->dfs;
			spi->tx_buf_len--;
		} else if (spi->rx_buf && spi->rx_buf_len > 0) {
			/* No need to push more than necessary */
			if (spi->rx_buf_len - spi->fifo_diff <= 0) {
				break;
			}

			data = 0;
		} else {
			/* Nothing to push anymore */
			break;
		}

		write_dr(data, info->regs);
		f_tx--;
		spi->fifo_diff++;
		DBG_COUNTER_INC();
	}

	if (spi->last_tx) {
		write_txftlr(0, info->regs);
		/* prevents any further interrupts demanding TX fifo fill */
	}

	SYS_LOG_DBG("Pushed: %d", DBG_COUNTER_RESULT());
}
コード例 #4
0
ファイル: spi_dw.c プロジェクト: milinddeore/zephyr
static void push_data(struct device *dev)
{
	const struct spi_dw_config *info = dev->config->config_info;
	struct spi_dw_data *spi = dev->driver_data;
	u32_t data = 0U;
	u32_t f_tx;

	DBG_COUNTER_INIT();

	if (spi_context_rx_on(&spi->ctx)) {
		f_tx = DW_SPI_FIFO_DEPTH - read_txflr(info->regs) -
			read_rxflr(info->regs);
		if ((int)f_tx < 0) {
			f_tx = 0U; /* if rx-fifo is full, hold off tx */
		}
	} else {
		f_tx = DW_SPI_FIFO_DEPTH - read_txflr(info->regs);
	}

	while (f_tx) {
		if (spi_context_tx_buf_on(&spi->ctx)) {
			switch (spi->dfs) {
			case 1:
				data = UNALIGNED_GET((u8_t *)
						     (spi->ctx.tx_buf));
				break;
			case 2:
				data = UNALIGNED_GET((u16_t *)
						     (spi->ctx.tx_buf));
				break;
#ifndef CONFIG_ARC
			case 4:
				data = UNALIGNED_GET((u32_t *)
						     (spi->ctx.tx_buf));
				break;
#endif
			}
		} else if (spi_context_rx_on(&spi->ctx)) {
			/* No need to push more than necessary */
			if ((int)(spi->ctx.rx_len - spi->fifo_diff) <= 0) {
				break;
			}

			data = 0U;
		} else if (spi_context_tx_on(&spi->ctx)) {
			data = 0U;
		} else {
			/* Nothing to push anymore */
			break;
		}

		write_dr(data, info->regs);

		spi_context_update_tx(&spi->ctx, spi->dfs, 1);
		spi->fifo_diff++;

		f_tx--;

		DBG_COUNTER_INC();
	}

	if (!spi_context_tx_on(&spi->ctx)) {
		/* prevents any further interrupts demanding TX fifo fill */
		write_txftlr(0, info->regs);
	}

	LOG_DBG("Pushed: %d", DBG_COUNTER_RESULT());
}