Example #1
0
static BT_ERROR canRead(BT_HANDLE hCan, BT_CAN_MESSAGE *pCanMessage) {
	volatile LPC17xx_CAN_REGS *pRegs = hCan->pRegs;

	BT_ERROR Error = BT_ERR_NONE;

	switch(hCan->eMode) {
	case BT_CAN_MODE_POLLED:
	{
		while(!(pRegs->CANGSR & LPC17xx_CAN_GSR_RBS)) {
			BT_ThreadYield();
		}
		CanReceive(hCan, pCanMessage);
		break;
	}

	case BT_CAN_MODE_BUFFERED:
	{
		// Get bytes from RX buffer very quickly.
		BT_FifoRead(hCan->hRxFifo, 1, pCanMessage, &Error);
		break;
	}

	default:
		// ERR, invalid handle configuration.
		break;
	}
	return Error;
}
Example #2
0
static BT_u32 i2c_master_transfer(BT_HANDLE hI2C, BT_I2C_MESSAGE *msgs, BT_u32 num, BT_ERROR *pError) {

	while(hI2C->pRegs->STATUS & STATUS_BA) {
		BT_ThreadYield();
	}

	if(num > 1) {
		hI2C->bHold = 1;
		hI2C->pRegs->CONTROL |= CONTROL_HOLD;
	} else {
		hI2C->bHold = BT_FALSE;
	}

	BT_u32 count;
	for(count = 0; count < num; count++, msgs++) {
		if(count == (num - 1)) {
			hI2C->bHold = BT_FALSE;
		}

retry:
		hI2C->err_status = 0;
		hI2C->p_msg = msgs;

		if(msgs->flags & BT_I2C_M_TEN) {
			hI2C->pRegs->CONTROL &= ~CONTROL_NEA;
		} else {
			hI2C->pRegs->CONTROL |= CONTROL_NEA;
		}

		if(msgs->flags & BT_I2C_M_RD) {
			mrecv(hI2C);
		} else {
			msend(hI2C);
		}

		// Wait on transfer complete signal.
		BT_kMutexPend(hI2C->pMutex, 0);
		hI2C->pRegs->INT_DISABLE = 0x000002FF;

		if(hI2C->err_status & INT_MASK_ARB_LOST) {
			BT_kPrint("ZYNQ I2C: Lost ownership on bus, trying again...");
			BT_ThreadSleep(2);
			goto retry;
		}
	}

	hI2C->p_msg = NULL;
	hI2C->err_status = 0;

	return num;
}
Example #3
0
/**
 *	Make the UART inactive (Clear the Enable bit).
 **/
static BT_ERROR uartDisable(BT_HANDLE hUart) {
	volatile LM3Sxx_UART_REGS *pRegs = hUart->pRegs;

    // Wait for end of TX.
    while(pRegs->FR & LM3Sxx_UART_FR_BUSY) {
    	BT_ThreadYield();
    }

    // Disable the FIFO.
    pRegs->LCRH &= ~(LM3Sxx_UART_LCRH_FEN);

    // Disable the UART.
    pRegs->CTL &= ~(LM3Sxx_UART_CTL_UARTEN | LM3Sxx_UART_CTL_TXE | LM3Sxx_UART_CTL_RXE);

    return BT_ERR_NONE;
}
Example #4
0
static BT_ERROR devcfg_cleanup(BT_HANDLE h) {
	g_bInUse = BT_FALSE;

	while(!(h->pRegs->INT_STS & INT_STS_PCFG_DONE)) {
		BT_ThreadYield();
	}
	
	zynq_slcr_unlock(h->pSLCR);
	zynq_slcr_postload_fpga(h->pSLCR);
	zynq_slcr_lock(h->pSLCR);

	bt_iounmap(h->pRegs);
	bt_iounmap(h->pSLCR);

	return BT_ERR_NONE;
}
Example #5
0
/**
 *	Implementing the CHAR dev write API.
 *
 *	Note, this doesn't implement ulFlags specific options yet!
 **/
static BT_s32 uartWrite(BT_HANDLE hUart, BT_u32 ulFlags, BT_u32 ulSize, const BT_u8 *pucSource) {
	volatile LM3Sxx_UART_REGS *pRegs = hUart->pRegs;

	BT_ERROR Error = BT_ERR_NONE;
	BT_u8 ucData;
	BT_u8 *pSrc = (BT_u8*)pucSource;
	BT_u32 slWritten = 0;

	switch(hUart->eMode) {
	case BT_UART_MODE_POLLED:
	{
		while(ulSize) {
			while((pRegs->FR & LM3Sxx_UART_FR_TXFF)) {
				BT_ThreadYield();
			}
			pRegs->DR = *pucSource++;
			ulSize--;
			slWritten++;
		}
		break;
	}

	case BT_UART_MODE_BUFFERED:
	{
		slWritten = BT_FifoWrite(hUart->hTxFifo, ulSize, pSrc, 0);

		pRegs->IM &= ~LM3Sxx_UART_INT_TX;	// Disable the interrupt

		while (!BT_FifoIsEmpty(hUart->hTxFifo, &Error) && (!(pRegs->FR & LM3Sxx_UART_FR_TXFF))) {
			BT_FifoRead(hUart->hTxFifo, 1, &ucData, 0);
			pRegs->DR = ucData;
		}
		pRegs->IM |= LM3Sxx_UART_INT_TX;	// Enable the interrupt
		break;
	}

	default:
		break;
	}
	return slWritten;
}
Example #6
0
static BT_s32 uartRead(BT_HANDLE hUart, BT_u32 ulFlags, BT_u32 ulSize, BT_u8 *pucDest) {
	volatile LM3Sxx_UART_REGS *pRegs = hUart->pRegs;

	BT_ERROR Error = BT_ERR_NONE;
	BT_s32 slRead = 0;

	switch(hUart->eMode) {
	case BT_UART_MODE_POLLED:
	{
		while(ulSize) {
			while((pRegs->FR & LM3Sxx_UART_FR_RXFE)) {
				if (slRead)
					return slRead;
				else
					BT_ThreadYield();
			}

			*pucDest++ = pRegs->DR & 0x000000FF;
			ulSize--;
			slRead++;
		}
		break;
	}

	case BT_UART_MODE_BUFFERED:
	{
		// Get bytes from RX buffer very quickly.
		slRead = BT_FifoRead(hUart->hRxFifo, ulSize, pucDest, 0);
		break;
	}

	default:
		// ERR, invalid handle configuration.
		break;
	}
	return slRead;
}
Example #7
0
/**
 *	Note, this doesn't implement ulFlags specific options yet!
 **/
static BT_ERROR canWrite(BT_HANDLE hCan, BT_CAN_MESSAGE *pCanMessage) {
	volatile LPC17xx_CAN_REGS *pRegs = hCan->pRegs;
	BT_CAN_MESSAGE oMessage;

	BT_ERROR Error = BT_ERR_NONE;

	switch(hCan->eMode) {
	case BT_CAN_MODE_POLLED:
	{
		BT_u32 ulIndex;
		while ((ulIndex = canFindFreeBuffer(hCan)) == LPC17xx_CAN_NO_FREE_BUFFER) {
			BT_ThreadYield();
		}
		CanTransmit(hCan, pCanMessage);
		break;
	}

	case BT_CAN_MODE_BUFFERED:
	{
		BT_FifoWrite(hCan->hTxFifo, 1, pCanMessage, &Error);

		while (!BT_FifoIsEmpty(hCan->hTxFifo, &Error) && (canFindFreeBuffer(hCan) != LPC17xx_CAN_NO_FREE_BUFFER)) {
			BT_FifoRead(hCan->hTxFifo, 1, &oMessage, &Error);
			CanTransmit(hCan, &oMessage);
		}

		pRegs->CANIER |= LPC17xx_CAN_IER_TIE;	// Enable the interrupt

		break;
	}

	default:
		break;
	}
	return Error;
}
Example #8
0
/**
 *	This assumes a single write request will be generated.
 **/
static BT_s32 devcfg_write(BT_HANDLE hDevcfg, BT_u32 ulFlags, BT_u32 ulSize, const void *pBuffer) {

	BT_u32 user_count = ulSize;

	BT_u32 kmem_size = ulSize + hDevcfg->residue_len;
	bt_paddr_t kmem = bt_page_alloc_coherent(kmem_size);
	if(!kmem) {
		BT_kPrint("xdevcfg: Cannot allocate memory.");
		return BT_ERR_NO_MEMORY;
	}

	BT_u8 *buf = (BT_u8 *) bt_phys_to_virt(kmem);

	// Collect stragglers from last time (0 to 3 bytes).
	memcpy(buf, hDevcfg->residue_buf, hDevcfg->residue_len);

	// Copy the user data.
	memcpy(buf + hDevcfg->residue_len, pBuffer, ulSize);

	// Include straggles in total to be counted.
	ulSize += hDevcfg->residue_len;

	// Check if header?
	if(hDevcfg->offset == 0 && ulSize > 4) {
		BT_u32 i;
		for(i = 0; i < ulSize - 4; i++) {
			if(!memcmp(buf + i, "\x66\x55\x99\xAA", 4)) {
				BT_kPrint("xdevcfg: found normal sync word.");
				hDevcfg->bEndianSwap = 0;
				break;
			}

			if(!memcmp(buf + i, "\xAA\x99\x55\x66", 4)) {
				BT_kPrint("xdevcfg: found byte-swapped sync word.");
				hDevcfg->bEndianSwap = 1;
				break;
			}
		}

		if(i != ulSize - 4) {
			ulSize -= i;
			memmove(buf, buf + i, ulSize);	// ulSize - i ??
		}
	}

	// Save stragglers for next time.
	hDevcfg->residue_len = ulSize % 4;
	ulSize -= hDevcfg->residue_len;
	memcpy(hDevcfg->residue_buf, buf + ulSize, hDevcfg->residue_len);

	// Fixup the endianness
	if(hDevcfg->bEndianSwap) {
		BT_u32 i;
		for (i = 0; i < ulSize; i += 4) {
			BT_u32 *p = (BT_u32 *) &buf[i];
			p[0] = __builtin_bswap32(p[0]);
		}
	}

	// Transfer the data.

	hDevcfg->pRegs->DMA_SRC_ADDR = (BT_u32 ) kmem | 1;
	hDevcfg->pRegs->DMA_DST_ADDR = 0xFFFFFFFF;

	BT_u32 transfer_len = 0;
	if(ulSize % 4) {
		transfer_len = (ulSize / 4) + 1;
	} else {
		transfer_len = (ulSize / 4);
	}

	hDevcfg->pRegs->DMA_SRC_LEN = transfer_len;
	hDevcfg->pRegs->DMA_DST_LEN = 0;

	while(!(hDevcfg->pRegs->INT_STS & INT_STS_DMA_DONE_INT)) {
		BT_ThreadYield();
	}

	hDevcfg->pRegs->INT_STS = INT_STS_DMA_DONE_INT;	// Clear DMA_DONE status

	hDevcfg->offset += user_count;

	bt_page_free_coherent(kmem, kmem_size);

	return user_count;
}
Example #9
0
long bt_sys_yield(void) {
	BT_ThreadYield();
	return 0;
}