Esempio n. 1
0
/**
 * @brief SPI module data pull (read) operation.
 * @param dev Pointer to the device structure for the driver instance
 * @return None.
 */
static void spi_k64_pull_data(struct device *dev)
{
	struct spi_k64_config *info = dev->config->config_info;
	struct spi_k64_data *spi_data = dev->driver_data;
	uint16_t data;
#ifdef CONFIG_SPI_DEBUG
	uint32_t cnt = 0;		/* # of bytes pulled */
#endif

	DBG("spi_k64_pull_data - ");

	do {	/* initial status already checked by spi_k64_isr() */

		if (spi_data->rx_buf && spi_data->rx_buf_len > 0) {

			data = (uint16_t)sys_read32(info->regs + SPI_K64_REG_POPR);

			if (spi_data->frame_sz > CHAR_BIT) {

				/* store 2nd byte with frame sizes larger than 8 bits  */

				*((uint16_t *)(spi_data->rx_buf)) = data;
				spi_data->rx_buf += 2;
				spi_data->rx_buf_len -= 2;

#ifdef CONFIG_SPI_DEBUG
				cnt+=2;
#endif
			} else {

				*(spi_data->rx_buf) = (uint8_t)data;
				spi_data->rx_buf++;
				spi_data->rx_buf_len--;

#ifdef CONFIG_SPI_DEBUG
				cnt++;
#endif
			}

			/* Clear interrupt */

			sys_write32(SPI_K64_SR_RFDF, (info->regs + SPI_K64_REG_SR));

		} else {

			/* No buffer to store data to */

			break;
		}

	} while (sys_read32(info->regs + SPI_K64_REG_SR) & SPI_K64_SR_RFDF);


	DBG("pulled: %d\n", cnt);
}
ssize_t _impl_hwinfo_get_device_id(u8_t *buffer, size_t length)
{
	uint32_t fuse_rdata[] = {
		sys_read32(EFUSE_BLK0_RDATA1_REG),
		sys_read32(EFUSE_BLK0_RDATA2_REG),
	};

	if (length > sizeof(fuse_rdata)) {
		length = sizeof(fuse_rdata);
	}

	memcpy(buffer, fuse_rdata, length);

	return length;
}
Esempio n. 3
0
/**
 * @brief SPI module interrupt handler.
 * @param arg Pointer to the device structure for the driver instance
 * @return None.
 */
void spi_k64_isr(void *arg)
{
	struct device *dev = arg;
	struct spi_k64_config *info = dev->config->config_info;
	uint32_t error = 0;
	uint32_t status;

	status = sys_read32(info->regs + SPI_K64_REG_SR);

	DBG("spi_k64_isr: dev %p, status 0x%x\n", dev, status);

	if (status & (SPI_K64_SR_RFOF | SPI_K64_SR_TFUF)) {

		/* Unrecoverable error: Rx overflow, Tx underflow */

		error = 1;

	} else {

		if (status & SPI_K64_SR_TFFF) {
			spi_k64_push_data(dev);
		}

		if (status & SPI_K64_SR_RFDF) {
			spi_k64_pull_data(dev);
		}

	}

	/* finish processing, if data transfer is complete */

	spi_k64_complete(dev, error);
}
Esempio n. 4
0
File: mvic.c Progetto: 01org/zephyr
void _arch_irq_disable(unsigned int irq)
{
	if (irq == CONFIG_MVIC_TIMER_IRQ) {
		sys_write32(sys_read32(MVIC_LVTTIMER) | MVIC_LVTTIMER_MASK,
			    MVIC_LVTTIMER);
	} else {
		_mvic_rte_update(irq, MVIC_IOWIN_MASK, MVIC_IOWIN_MASK);
	}
}
Esempio n. 5
0
File: mvic.c Progetto: 01org/zephyr
/**
 * @brief Find the currently executing interrupt vector, if any
 *
 * This routine finds the vector of the interrupt that is being processed.
 * The ISR (In-Service Register) register contain the vectors of the interrupts
 * in service. And the higher vector is the identification of the interrupt
 * being currently processed.
 *
 * MVIC ISR registers' offsets:
 * --------------------
 * | Offset | bits    |
 * --------------------
 * | 0110H  |  32:63  |
 * --------------------
 *
 * @return The vector of the interrupt that is currently being processed, or
 * -1 if this can't be determined
 */
int __irq_controller_isr_vector_get(void)
{
	/* In-service register value */
	int isr;

	isr = sys_read32(MVIC_ISR);
	if (unlikely(!isr)) {
		return -1;
	}
	return 32 + (find_msb_set(isr) - 1);
}
Esempio n. 6
0
File: soc.c Progetto: agatti/zephyr
/* Setup power and clock for needed hardware modules. */
static void setup_modules_prcm(void)
{
#if defined(CONFIG_GPIO_CC2650) || \
	defined(CONFIG_SERIAL)

	/* Setup power */
#if defined(CONFIG_GPIO_CC2650)
	sys_set_bit(pdctl0, CC2650_PRCM_PDCTL0_PERIPH_ON_POS);
#endif
#ifdef CONFIG_SERIAL
	sys_set_bit(pdctl0, CC2650_PRCM_PDCTL0_SERIAL_ON_POS);
#endif

	/* Setup clocking */
#ifdef CONFIG_GPIO_CC2650
	sys_set_bit(gpioclkgr, CC2650_PRCM_GPIOCLKGR_CLK_EN_POS);
#endif
#ifdef CONFIG_SERIAL
	sys_set_bit(uartclkgr, CC2650_PRCM_UARTCLKGR_CLK_EN_POS);
#endif
	/* Reload clocking configuration for device */
	sys_set_bit(clkloadctl, CC2650_PRCM_CLKLOADCTL_LOAD_POS);

	/* Wait for power to be completely on, to avoid bus faults
	 * when accessing modules' registers.
	 */
#if defined(CONFIG_GPIO_CC2650)
	while (!(sys_read32(pdstat0) &
	       BIT(CC2650_PRCM_PDSTAT0_PERIPH_ON_POS))) {
		continue;
	}
#endif
#if defined(CONFIG_SERIAL)
	while (!(sys_read32(pdstat0) &
	       BIT(CC2650_PRCM_PDSTAT0_SERIAL_ON_POS))) {
		continue;
	}
#endif

#endif
}
Esempio n. 7
0
/**
 * @brief Halt SPI module operation.
 * @param dev Pointer to the device structure for the driver instance
 * @return None.
 */
static inline void spi_k64_halt(struct device *dev)
{
	struct spi_k64_config *info = dev->config->config_info;

	/* Ensure module operation is stopped */

	sys_set_bit((info->regs + SPI_K64_REG_MCR), SPI_K64_MCR_HALT_BIT);

	while (sys_read32(info->regs + SPI_K64_REG_SR) & SPI_K64_SR_TXRXS) {
		DBG("SPI Controller dev %p is running.  Waiting for Halt.\n", dev);
	}

}
Esempio n. 8
0
/**
 * @brief Find the currently executing interrupt vector, if any
 *
 * This routine finds the vector of the interrupt that is being processed.
 * The ISR (In-Service Register) register contain the vectors of the interrupts
 * in service. And the higher vector is the identification of the interrupt
 * being currently processed.
 *
 * This function must be called with interrupts locked in interrupt context.
 *
 * ISR registers' offsets:
 * --------------------
 * | Offset | bits    |
 * --------------------
 * | 0100H  |   0:31  |
 * | 0110H  |  32:63  |
 * | 0120H  |  64:95  |
 * | 0130H  |  96:127 |
 * | 0140H  | 128:159 |
 * | 0150H  | 160:191 |
 * | 0160H  | 192:223 |
 * | 0170H  | 224:255 |
 * --------------------
 *
 * @return The vector of the interrupt that is currently being processed, or -1
 * if no IRQ is being serviced.
 */
int __irq_controller_isr_vector_get(void)
{
	int pReg, block;

	/* Block 0 bits never lit up as these are all exception or reserved
	 * vectors
	 */
	for (block = 7; likely(block > 0); block--) {
		pReg = sys_read32(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_ISR +
				  (block * 0x10));
		if (pReg) {
			return (block * 32) + (find_msb_set(pReg) - 1);
		}

	}
	return -1;
}
Esempio n. 9
0
/**
 * @brief Suspend SPI host controller operations.
 * @param dev Pointer to the device structure for the driver instance
 * @return DEV_OK if successful, another DEV_* code otherwise.
 */
static int spi_k64_suspend(struct device *dev)
{
	struct spi_k64_config *info = dev->config->config_info;

	DBG("spi_k64_suspend: %p\n", dev);

	/* disable module */

	sys_set_bit((info->regs + SPI_K64_REG_MCR), SPI_K64_MCR_MDIS_BIT);

	irq_disable(info->irq);

	while (sys_read32(info->regs + SPI_K64_REG_SR) & SPI_K64_SR_TXRXS) {
		DBG("SPI Controller dev %p is running.  Waiting to stop.\n", dev);
	}

	return DEV_OK;
}
Esempio n. 10
0
File: mvic.c Progetto: 01org/zephyr
/**
 *
 * @brief modify interrupt line register.
 *
 * @param irq INTIN number
 * @param value value to be written
 * @param mask of bits to be modified
 *
 * @returns N/A
 */
static void _mvic_rte_update(unsigned int irq, u32_t value, u32_t mask)
{
	int key;
	u32_t regsel, old_value, updated_value;

	__ASSERT(!(value & ~MVIC_IOWIN_SUPPORTED_BITS_MASK),
		 "invalid IRQ flags %" PRIx32 " for irq %d", value, irq);

	regsel = compute_ioregsel(irq);

	key = irq_lock();

	sys_write32(regsel, MVIC_IOREGSEL);

	old_value = sys_read32(MVIC_IOWIN);
	updated_value = (old_value & ~mask) | (value & mask);
	sys_write32(updated_value, MVIC_IOWIN);

	irq_unlock(key);
}
Esempio n. 11
0
static int _loapic_init(struct device *unused)
{
	ARG_UNUSED(unused);
	s32_t loApicMaxLvt; /* local APIC Max LVT */

	/* enable the Local APIC */
	sys_write32(sys_read32(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_SVR)
		    | LOAPIC_ENABLE, CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_SVR);

	loApicMaxLvt = (*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_VER) &
			LOAPIC_MAXLVT_MASK) >> 16;

	/* reset the DFR, TPR, TIMER_CONFIG, and TIMER_ICR */

	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_DFR) =
		(int)0xffffffff;
	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_TPR) = (int)0x0;
	*(volatile int *) (CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_TIMER_CONFIG) =
		(int)0x0;
	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_TIMER_ICR) = (int)0x0;

	/* program Local Vector Table for the Virtual Wire Mode */

	/* set LINT0: extInt, high-polarity, edge-trigger, not-masked */

	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_LINT0) =
		(*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_LINT0) &
		 ~(LOAPIC_MODE | LOAPIC_LOW | LOAPIC_LEVEL | LOAPIC_LVT_MASKED)) |
		(LOAPIC_EXT | LOAPIC_HIGH | LOAPIC_EDGE);

	/* set LINT1: NMI, high-polarity, edge-trigger, not-masked */

	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_LINT1) =
		(*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_LINT1) &
		 ~(LOAPIC_MODE | LOAPIC_LOW | LOAPIC_LEVEL | LOAPIC_LVT_MASKED)) |
		(LOAPIC_NMI | LOAPIC_HIGH | LOAPIC_EDGE);

	/* lock the Local APIC interrupts */

	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_TIMER) =
		LOAPIC_LVT_MASKED;
	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_ERROR) =
		LOAPIC_LVT_MASKED;

	if (loApicMaxLvt >= LOAPIC_LVT_P6)
		*(volatile int *) (CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_PMC) =
			LOAPIC_LVT_MASKED;

	if (loApicMaxLvt >= LOAPIC_LVT_PENTIUM4)
		*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_THERMAL) =
			LOAPIC_LVT_MASKED;

#if CONFIG_LOAPIC_SPURIOUS_VECTOR
	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_SVR) =
		(*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_SVR)
		 & 0xFFFFFF00)
		| (LOAPIC_SPURIOUS_VECTOR_ID & 0xFF);
#endif

	/* discard a pending interrupt if any */
#if CONFIG_EOI_FORWARDING_BUG
	_lakemont_eoi();
#else
	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI) = 0;
#endif

	return 0;
}
Esempio n. 12
0
/**
 * @brief Read and/or write a defined amount of data through an SPI driver
 *
 * @param dev Pointer to the device structure for the driver instance
 * @param tx_buf Memory buffer that data should be transferred from
 * @param tx_buf_len Size of the memory buffer available for reading from
 * @param rx_buf Memory buffer that data should be transferred to
 * @param rx_buf_len Size of the memory buffer available for writing to
 *
 * @return DEV_OK if successful, another DEV_* code otherwise.
 */
static int spi_k64_transceive(struct device *dev,
				uint8_t *tx_buf, uint32_t tx_buf_len,
				uint8_t *rx_buf, uint32_t rx_buf_len)
{
	struct spi_k64_config *info = dev->config->config_info;
	struct spi_k64_data *spi_data = dev->driver_data;
	uint32_t int_config;	/* interrupt configuration */

	DBG("spi_k64_transceive: dev %p, Tx buf %p, ", dev, tx_buf);
	DBG("Tx len %u, Rx buf %p, Rx len %u\n", tx_buf_len, rx_buf, rx_buf_len);

	/* Check parameters */

	if ((tx_buf_len && (tx_buf == NULL)) || (rx_buf_len && (rx_buf == NULL))) {

		DBG("spi_k64_transceive: ERROR - NULL buffer\n");
		return DEV_INVALID_OP;
	}

	/* Check Tx FIFO status */

	if (tx_buf_len &&
		((sys_read32(info->regs + SPI_K64_REG_SR) & SPI_K64_SR_TFFF) == 0)) {

		DBG("spi_k64_transceive: Tx FIFO is full\n");
		return DEV_USED;
	}

	/* Set buffers info */
	spi_data->tx_buf = tx_buf;
	spi_data->tx_buf_len = tx_buf_len;
	spi_data->rx_buf = rx_buf;
	spi_data->rx_buf_len = rx_buf_len;

	/* enable transfer operations - must be done before enabling interrupts */

	spi_k64_start(dev);

	/*
	 * Enable interrupts:
	 * - Transmit FIFO Fill (Tx FIFO not full); and/or
	 * - Receive FIFO Drain (Rx FIFO not empty);
	 *
	 * Note: DMA requests are not supported.
	 */

	int_config = sys_read32(info->regs + SPI_K64_REG_RSER);

	if (tx_buf_len) {

		int_config |= SPI_K64_RSER_TFFF_RE;
	}

	if (rx_buf_len) {

		int_config |= SPI_K64_RSER_RFDF_RE;
	}

	sys_write32(int_config, (info->regs + SPI_K64_REG_RSER));

    /* wait for transfer to complete */

	device_sync_call_wait(&spi_data->sync_info);

    /* check completion status */

	if (spi_data->error) {
		spi_data->error = 0;
		return DEV_FAIL;
	}

	return DEV_OK;
}
Esempio n. 13
0
static uint32_t quark_se_ipm_sts_get(void)
{
    return sys_read32(QUARK_SE_IPM_CHALL_STS) & inbound_channels;
}
Esempio n. 14
0
File: soc.c Progetto: agatti/zephyr
int bit_is_set(u32_t reg, u8_t bit)
{
	return sys_read32(reg) & BIT(bit);
}
Esempio n. 15
0
/**
 * @brief SPI module data push (write) operation.
 * @param dev Pointer to the device structure for the driver instance
 * @return None.
 */
static void spi_k64_push_data(struct device *dev)
{
	struct spi_k64_config *info = dev->config->config_info;
	struct spi_k64_data *spi_data = dev->driver_data;
	uint32_t data;
#ifdef CONFIG_SPI_DEBUG
	uint32_t cnt = 0;		/* # of bytes pushed */
#endif

	DBG("spi_k64_push_data - ");

	do {	/* initial status already checked by spi_k64_isr() */

		if (spi_data->tx_buf && (spi_data->tx_buf_len > 0)) {

			if (spi_data->frame_sz > CHAR_BIT) {

				/* get 2nd byte with frame sizes larger than 8 bits  */

				data = (uint32_t)(*(uint16_t *)(spi_data->tx_buf));

				spi_data->tx_buf += 2;
				spi_data->tx_buf_len -= 2;

#ifdef CONFIG_SPI_DEBUG
				cnt+=2;
#endif
			} else {

				data = (uint32_t)(*(spi_data->tx_buf));

				spi_data->tx_buf++;
				spi_data->tx_buf_len--;

#ifdef CONFIG_SPI_DEBUG
				cnt++;
#endif
			}

			/* Write data to the selected slave */

			if (spi_data->cont_pcs_sel && (spi_data->tx_buf_len == 0)) {

				/* clear continuous PCS enabling in the last frame */

				sys_write32((data | SPI_K64_PUSHR_PCS_SET(spi_data->pcs)),
							(info->regs + SPI_K64_REG_PUSHR));

			} else {

				sys_write32((data | SPI_K64_PUSHR_PCS_SET(spi_data->pcs) |
								SPI_K64_PUSHR_CONT_SET(spi_data->cont_pcs_sel)),
							(info->regs + SPI_K64_REG_PUSHR));
			}

			/* Clear interrupt */

			sys_write32(SPI_K64_SR_TFFF, (info->regs + SPI_K64_REG_SR));

		} else {

			/* Nothing more to push */

			break;
		}

	} while (sys_read32(info->regs + SPI_K64_REG_SR) & SPI_K64_SR_TFFF);

	DBG("pushed: %d\n", cnt);

}
Esempio n. 16
0
static inline uint32_t eth_read(uint32_t base_addr, uint32_t offset)
{
	return sys_read32(base_addr + offset);
}
Esempio n. 17
0
static inline uint32_t _i2c_qse_ss_memory_read(uint32_t base_addr,
					       uint32_t offset)
{
	return sys_read32(base_addr + offset);
}
Esempio n. 18
0
static u32_t dma_stm32_read(struct dma_stm32_device *ddata, u32_t reg)
{
	return sys_read32(ddata->base + reg);
}
Esempio n. 19
0
static inline void gpio_dw_unmask_int(uint32_t mask_addr)
{
	sys_write32(sys_read32(mask_addr) & INT_ENABLE_ARC, mask_addr);
}
Esempio n. 20
0
static inline void gpio_dw_unmask_int(uint32_t mask_addr)
{
	sys_write32(sys_read32(mask_addr) & INT_UNMASK_IA, mask_addr);
}
Esempio n. 21
0
/**
 * @brief Complete SPI module data transfer operations.
 * @param dev Pointer to the device structure for the driver instance
 * @param error Error condition (0 = no error, otherwise an error occurred)
 * @return None.
 */
static void spi_k64_complete(struct device *dev, uint32_t error)
{
	struct spi_k64_data *spi_data = dev->driver_data;
	struct spi_k64_config *info = dev->config->config_info;
	uint32_t int_config;	/* interrupt configuration */

	if (error) {

		DBG("spi_k64_complete - ERROR condition\n");

		goto complete;
	}

	/* Check for a completed transfer */

	if (spi_data->tx_buf && (spi_data->tx_buf_len == 0) && !spi_data->rx_buf) {

		/* disable Tx interrupts */

		int_config = sys_read32(info->regs + SPI_K64_REG_RSER);

		int_config &= ~SPI_K64_RSER_TFFF_RE;

		sys_write32(int_config, (info->regs + SPI_K64_REG_RSER));

	} else if (spi_data->rx_buf && (spi_data->rx_buf_len == 0) &&
				!spi_data->tx_buf) {

		/* disable Rx interrupts */

		int_config = sys_read32(info->regs + SPI_K64_REG_RSER);

		int_config &= ~SPI_K64_RSER_RFDF_RE;

		sys_write32(int_config, (info->regs + SPI_K64_REG_RSER));

	} else if (spi_data->tx_buf && spi_data->tx_buf_len == 0 &&
			spi_data->rx_buf && spi_data->rx_buf_len == 0) {

		/* disable Tx, Rx interrupts */

		int_config = sys_read32(info->regs + SPI_K64_REG_RSER);

		int_config &= ~(SPI_K64_RSER_TFFF_RE | SPI_K64_RSER_RFDF_RE);

		sys_write32(int_config, (info->regs + SPI_K64_REG_RSER));

	} else {

		return;
	}

complete:

	spi_data->tx_buf = spi_data->rx_buf = NULL;
	spi_data->tx_buf_len = spi_data->rx_buf_len = 0;

	/* Disable transfer operations */

	spi_k64_halt(dev);

    /* Save status */

	spi_data->error = error;

    /* Signal completion */

	device_sync_call_complete(&spi_data->sync_info);
}
Esempio n. 22
0
int spi_k64_init(struct device *dev)
{
	struct spi_k64_config *info = dev->config->config_info;
	struct spi_k64_data *data = dev->driver_data;
	uint32_t mcr;

	dev->driver_api = &k64_spi_api;

	/* Enable module clocking */

	sys_set_bit(info->clk_gate_reg, info->clk_gate_bit);

	/*
	 * Ensure module operation is stopped and enabled before writing anything
	 * more to the registers.
	 * (Clear MCR[MDIS] and set MCR[HALT].)
	 */

	DBG("halt\n");
	mcr = SPI_K64_MCR_HALT;
	sys_write32(mcr, (info->regs + SPI_K64_REG_MCR));

	while (sys_read32(info->regs + SPI_K64_REG_SR) & SPI_K64_SR_TXRXS) {
		DBG("SPI Controller dev %p is running.  Waiting for Halt.\n", dev);
	}

	/* Clear Tx and Rx FIFOs */

	mcr |= (SPI_K64_MCR_CLR_RXF | SPI_K64_MCR_CLR_TXF);

	DBG("fifo clr\n");
 	sys_write32(mcr, (info->regs + SPI_K64_REG_MCR));

	/* Set master mode */

	mcr = SPI_K64_MCR_MSTR | SPI_K64_MCR_HALT;
	DBG("master mode\n");
 	sys_write32(mcr, (info->regs + SPI_K64_REG_MCR));

	/* Disable SPI module interrupt generation */

	DBG("irq disable\n");
	sys_write32(0, (info->regs + SPI_K64_REG_RSER));

	/* Clear status */

	DBG("status clr\n");
	sys_write32((SPI_K64_SR_RFDF | SPI_K64_SR_RFOF | SPI_K64_SR_TFUF |
				SPI_K64_SR_EOQF	| SPI_K64_SR_TCF),
				(info->regs + SPI_K64_REG_SR));

    /* Set up the synchronous call mechanism */

	device_sync_call_init(&data->sync_info);

	/* Configure and enable SPI module IRQs */

	info->config_func();

	irq_enable(info->irq);

	/* 
	 * Enable Rx overflow interrupt generation.
	 * Note that Tx underflow is only generated when in slave mode.
	 */

	DBG("rxfifo overflow enable\n");
	sys_write32(SPI_K64_RSER_RFOF_RE, (info->regs + SPI_K64_REG_RSER));

	DBG("K64 SPI Driver initialized on device: %p\n", dev);

	/* operation remains disabled (MCR[HALT] = 1)*/

	return DEV_OK;
}