⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.c

📁 MMC driver for LPC21
💻 C
字号:

#include "common.h"

// *****************************************************
// variables

_u32 cclk = 0;
_u32 pclk = 0;

volatile _u8 uart0_rxBuf[128];
volatile _u16 uart0_rxWr = 0;
volatile _u16 uart0_rxRd = 0;

// *****************************************************
// misc

void delay_us(_u32 us)
{
	volatile _u32 clk = (_s32)(((_u64)cclk * us) / 10000000);
	while (clk-- > 0);
}

bool delay_ms(_u16 ms)
{	// sit n wait for a number of milliseconds
	if (ms < 1) return false;								// safe guard + wots the point?
	if (PCONP & PCONP_PCTIM1) return false;			// the timer is already in use
//	if (T1TCR & T1TCR_Counter_Enable) return false;	// the timer is already in use
																	//
	PCONP |= PCONP_PCTIM1;									// power up timer 1
																	//
	T1TCR = T1TCR_Counter_Reset;							// stop & reset the timer counter
	T1TCR = 0;													//
	T1TC = 0;													//
	T1PC = 0;													//
	T1EMR = 0;													//
	T1CCR = 0;													//
	T1PR = 0;													//
	T1MR0 = (_u32)(((_u64)pclk * ms) / 1000) - 1;	// Set timer match register value
	T1IR = 0xFF;												// Clear the timer interrupt flags
	T1MCR = T1MCR_MR0S;										// stop timer on match
	T1TCR = T1TCR_Counter_Enable;							// Start timer
	while (T1TCR & T1TCR_Counter_Enable);				// wait until delay time has elapsed
																	//
	PCONP &= ~PCONP_PCTIM1;									// power down timer 1
																	//
	return true;												//
}

// *****************************************************

bool start_test_timer(void)
{	// start timer 1 so we can do sum speed testing or such like
	if (PCONP & PCONP_PCTIM1) return false;			// the timer is already in use
																	//
	PCONP |= PCONP_PCTIM1;									// power up timer 1
																	//
	T1TCR = T1TCR_Counter_Reset;							// stop & reset the timer counter
	T1TCR = 0;													//
	T1TC = 0;													//
	T1PC = 0;													//
	T1EMR = 0;													//
	T1CCR = 0;													//
	T1PR = 0;													//
	T1MR0 = 0xffffffff;										// Set timer match register value
	T1IR = 0xFF;												// Clear the timer interrupt flags
	T1MCR = T1MCR_MR0S;										// stop timer on match
	T1TCR = T1TCR_Counter_Enable;							// Start timer
																	//
	return true;												//
}

_u32 stop_test_timer(void)
{
	_u32 result;
	if (!(PCONP & PCONP_PCTIM1)) return 0;				// the timer isunt running :(
	if (!(T1TCR & T1TCR_Counter_Enable)) return 0;	// the timer isunt enabled :(
	T1TCR &= ~T1TCR_Counter_Enable;						// Stop timer
	result = T1TC;												// get the counter value
	T1TCR = 0;													// Stop timer
	PCONP &= ~PCONP_PCTIM1;									// power down timer 1
	return result;												// return the counter value
}

// *****************************************************
// spi routines

_u32 SPI0_Initialize(_u32 freq, bool master, bool clk_edge_2, bool sclk_active_low, bool lsb_1st, bool use_SSEL, bool set_pins, CTL_ISR_FN_t isr)
{
	_u8 b;

	PCONP |= PCONP_PCSPI0;						// power up SPI0

	S0SPCR = 0;									// start a fresh

	_u32 div = pclk / freq;						// spi sclk freq
	if (div < 8) div = 8;						// the internal hardware has speed limits
	else
	if (div > 254) div = 254;					// yes it does!
	div &= ~Bit0;								// clear bit-0 - divider value must always be even

	S0SPCCR = (_u8)div;							// set the spi clock rate

	if (clk_edge_2) S0SPCR |= S0SPCR_CPHA;		// Data sampled on the second clock edge of the SCK

	if (sclk_active_low) S0SPCR |= S0SPCR_CPOL;	// SCK is active low

	if (master) S0SPCR |= S0SPCR_MSTR;			// master

	if (lsb_1st) S0SPCR |= S0SPCR_LSBF;			// lsb 1st

	b = S0SPDR;									// clear the Rx FIFO
	b = S0SPSR;									// clear status flags

	S0SPINT = Bit0;								// clear interrupt flag

	if (set_pins)
	{
		// set the SCLK, MOSI & MISO pins as an SCLK, MOSI & MISO
		PINSEL0 &= ~(Bit13 | Bit11 | Bit9);
		PINSEL0 |= Bit12 | Bit10 | Bit8;

		if (use_SSEL)
		{	// set the SSEL pin as a SSEL
			PINSEL0 &= ~Bit15;
			PINSEL0 |= Bit14;
		}
	}

	if (isr)
	{	// add int vector & enable int
		ctl_set_isr(SPI0_INT, SPI0_Int_Priority, CTL_ISR_TRIGGER_FIXED, isr, 0);
		ctl_unmask_isr(SPI0_INT);

		S0SPCR |= Bit7;							// enable spi interrupt
	}
	else
	{	// remove any int vector there might be
		ctl_mask_isr(SPI0_INT);
		ctl_set_isr(SPI0_INT, SPI0_Int_Priority, 0, 0, 0);
	}

	return (pclk / S0SPCCR);					// return the actual speed we managed to set the sclk freq too
}

void SPI0_Deinitialize(void)
{
	S0SPCR = 0;				// Disable spi interrupt

	ctl_mask_isr(SPI0_INT);
	ctl_set_isr(SPI0_INT, SPI0_Int_Priority, 0, 0, 0);

	// set the SCLK, MOSI & MISO pins back to normal IO mode
	PINSEL0 &= ~(Bit13|Bit12 | Bit11|Bit10 | Bit9|Bit8);

	// set the SSEL pin back to normal IO mode
	PINSEL0 &= ~(Bit15|Bit14);

	PCONP &= ~PCONP_PCSPI0;					// power down SPI0
}

void SPI0_SendByte(_u8 b)
{
	S0SPDR = b;											// send byte
}

_u8 SPI0_GetByte(_u8 b)
{
	return S0SPDR;										// return rx'ed byte
}

int SPI0_WaitForTx(void)
{	// wait for tx byte to be sent
	register _u8	stat;
	volatile _u32	i = cclk >> 13;						// timeout value
	while (!((stat = S0SPSR) & S0SPSR_SPIF))			// wait for byte to be sent
	{
		if (i-- == 0) return -1;						// time-out
	}
	return 0;											// byte sent
}

_u8 SPI0_WaitForTxGetRx(void)
{	// wait for tx byte to be sent & return rx'ed byte
	register _u8	stat;
	volatile _u32	i = cclk >> 13;						// timeout value
	while (!((stat = S0SPSR) & S0SPSR_SPIF))			// wait for byte to be sent
	{
		if (i-- == 0) return 0xff;						// time-out
	}
	return S0SPDR;										// return the byte rx'ed
}

_u8 SPI0_8(_u8 b)
{	// tx a byte & rx one back over the SPI-0 line
	SPI0_SendByte(b);									// send byte
	return SPI0_WaitForTxGetRx();						// wait for byte to finish being sent
}

_u16 SPI0_16(_u16 w)
{	// tx a word & rx one back over the SPI-0 line
	register _u16 r;

	SPI0_SendByte(w >> 8);								// send MS-Byte
	r = (_u16)SPI0_WaitForTxGetRx() << 8;				// wait for byte to finish being sent and get rx'ed byte

	SPI0_SendByte(w);									// send LS-Byte
	r |= (_u16)SPI0_WaitForTxGetRx();					// wait for byte to finish being sent and get rx'ed byte

	return r;											// return the rx'ed word
}

// *****************************************************
// uart routines

_u32 UART0_Initialize(unsigned int baud, _u8 fifo_size, CTL_ISR_FN_t isr)
{	// Configure UART

	PCONP |= PCONP_PCUART0;								// power up uart-0

	_u32 br_div = pclk / ((_u32)baud << 4);		// work out the baud rate divider value

	U0IER = 0;												// disable all interrupts
	U0IIR = 0;												// clear interrupt ID register
	U0LSR = 0;												// clear line status register
	U0FCR = 0;												// no fifo

	U0LCR |= U0LCR_Divisor_Latch_Access_Bit;		// Enable DLAB access
	U0DLL = br_div & 0xFF;								//
	U0DLM = (br_div >> 8) & 0xFF;						//
	U0LCR &= ~U0LCR_Divisor_Latch_Access_Bit;		// Disable DLAB access

	U0LCR = 0;												// default to 5-bit, 1-stop bit, odd-parity, no break tx, no DLAB access
//	U0LCR |= Bit0;											// change to 6 bit
//	U0LCR |= Bit1;											// change to 7 bit
	U0LCR |= Bit1 | Bit0;								// change to 8 bit
//	U0LCR |= Bit2;											// change to 2-stop bits
//	U0LCR |= Bit3;											// change to even-parity generation & checking
//	U0LCR |= Bit4;											// change to even-parity
//	U0LCR |= Bit5;											// change to force '1' sticky parity
//	U0LCR |= Bit5 | Bit4;								// change to force '0' sticky parity
//	U0LCR |= Bit6;											// change to enable break tx

	// set the TxD pin as TxD
	PINSEL0 &= ~Bit1;										//
	PINSEL0 |= Bit0;										//

	// set the RxD pin as RxD
	PINSEL0 &= ~Bit3;										//
	PINSEL0 |= Bit2;										//

	if (fifo_size > 0)
	{	// enable the chips uart Tx & Rx FIFO buffers
		if (fifo_size <= 1) U0FCR = 0;								// FIFO trigger = 1 byte
		else
		if (fifo_size <= 4) U0FCR = Bit6;							// FIFO trigger = 4 bytes
		else
		if (fifo_size <= 8) U0FCR = Bit7;							// FIFO trigger = 8 bytes
		else
		if (fifo_size <= 14) U0FCR = Bit7 | Bit6;					// FIFO trigger = 14 bytes
		else
			U0FCR = Bit7;													// FIFO trigger = 8 bytes
		U0FCR |= U0FCR_FIFO_Enable;									// enable the fifo's
		U0FCR |= U0FCR_Tx_FIFO_Reset | U0FCR_Rx_FIFO_Reset;	// clear the TX & RX fifo's
	}

	// Setup UART RX interrupt
	if (isr)
	{
		ctl_set_isr(UART0_INT, UART0_Int_Priority, CTL_ISR_TRIGGER_FIXED, isr, 0);		// add a vector int entry
		ctl_unmask_isr(UART0_INT);																		// enable the interrupt

		// enable desired interrupt triggers
		U0IER = U0IER_RBR_Interrupt_Enable;						// Rx byte interrupt
//		U0IER |= U0IER_THRE_Interrupt_Enable;					// THRE interrupt (tx holding register)
		U0IER |= U0IER_Rx_Line_Status_Interrupt_Enable;		// Rx line status interrupt
	}

	return ((pclk / br_div) << 4);								// return the actual speed we managed to set the baud rate too
}

void UART0_Deinitialize(void)
{
	if (PCONP & PCONP_PCUART0)
	{
		U0IER = 0;														// disable ints
		U0IIR = 0;														// clear interrupt ID register
	}

	ctl_mask_isr(UART0_INT);										// stop ints
	ctl_set_isr(UART0_INT, UART0_Int_Priority, 0, 0, 0);	// clear int vector

	PCONP &= ~PCONP_PCUART0;										// power down uart-0
}

void ClearRxUartFIFO(int uart)
{
	switch (uart)
	{
		case 0	:	if (PCONP & PCONP_PCUART0) U0FCR |= U0FCR_Rx_FIFO_Reset;		// clear the RX fifo
						break;
		case 1	:	if (PCONP & PCONP_PCUART1) U1FCR |= U1FCR_Rx_FIFO_Reset;		// clear the RX fifo
						break;
	}
}

void ClearTxUartFIFO(int uart)
{
	switch (uart)
	{
		case 0	:	if (PCONP & PCONP_PCUART0) U0FCR |= U0FCR_Tx_FIFO_Reset;		// clear the TX fifo
						break;
		case 1	:	if (PCONP & PCONP_PCUART1) U1FCR |= U1FCR_Tx_FIFO_Reset;		// clear the TX fifo
						break;
	}
}

bool WriteByte_uart0(_u8 ch, _s32 timeout)
{
	register _s32 i = timeout;

	if (!(PCONP & PCONP_PCUART0)) return false;		// the uart is not powered up

	while (!(U0LSR & U0LSR_THRE))							// wait for tx to be ready for new byte
	{
		if (--i <= 0) return false;						// time-out
	}
	U0THR = ch;													// tx byte

	return true;
}

void WriteStr_uart0(char *s)
{
	if (!(PCONP & PCONP_PCUART0)) return;				// the uart is not powered up

	while (*s != 0) WriteByte_uart0(*s++, 1000000);	// send each byte of the string
}

// ****************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -