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

📄 main.c

📁 MMC driver for LPC21
💻 C
字号:

//
// this is being tested on an LPC2138 with 14.7456MHz xtal, full pll clock rate, full pclk rate.
//
// it doesn't include the normal pll etc initialization code so you'll have to add that yourself
// (depending on which compiler you use).
//
// the compiled size of the test program maybe a LOT bigger than you expected - 2 possible reasons for this ..
//
// 1) you have compiled with the mmc 'mmc_debug1' option enabled (see top of mmc.h file) -
//    large compiled size difference! .. not to mention a very large speed penalty (>= 10 fold slow down)
//    when debug enabled!!!
//
// 2) this file (main.c) uses a bit of floating point maths and a floating point sprintf call in the
//    main() section - comment this out if you want! .. it's only for a speed test. see near the start
//    of the exec loop.
//

#include <string.h>
#include <stdio.h>
//#include <math.h>

#include "common.h"
#include "mmc.h"

char	s[128];
_u8	buffer[512];		// big enough for one MMC/SD sector

// *****************************************************
// uart interrupt service routines

void uart0_ISR(void)
{
	ctl_global_interrupts_re_enable_from_isr();					// allow nested ints

	register _u8 i;

	while ((i = U0IIR) & U0IIR_Interrupt_Identification_MASK)
	{
		switch (i & U0IIR_Interrupt_Identification_MASK)
		{
			case 0x02	:	// THRE interrupt .. tx buffer empty - feed more bytes to the tx if that's wot we want
//								U0THR = NextByteToSend;
								break;
			case 0x04	:	// Receive Data Available (RDA) interrupt
			case 0x0c	:	// Character Time-out Indicator (CTI) interrupt
								while ((i = U0LSR) & U0LSR_RDR)
								{	// save the incoming bytes into an FIFO buffer
									if (i & (U0LSR_PE | U0LSR_FE | U0LSR_BI))
									{	// parity, frame or break error
										i = U0RBR;	// drop byte & clear error
									}
									else
									{
										uart0_rxBuf[uart0_rxWr] = U0RBR;
										if (++uart0_rxWr >= sizeof(uart0_rxBuf)) uart0_rxWr = 0;
									}
								}
								break;
			case 0x06	:	// Receive Line Status (RLS) interrupt
								i = U0LSR;
								break;
			default		:	// clear any/all interrupt flags we can find - we don't know the cause of this interrupt :(
								i = U0LSR;
								i = U0RBR;
								break;
		}
	}

//	VICVectAddr = 0;

	ctl_global_interrupts_un_re_enable_from_isr();
}

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

void ShowError(int err)
{
	switch (err)
	{
		case mmc_ok									:	break;
		case mmc_err_not_inserted				:	WriteStr_uart0("mmc_err_not_inserted\r\n");
															break;
		case mmc_err_timeout						:	WriteStr_uart0("mmc_err_timeout\r\n");
															break;
		case mmc_err_busy							:	WriteStr_uart0("mmc_err_busy\r\n");
															break;
		case mmc_err_invalid_address			:	WriteStr_uart0("mmc_err_invalid_address\r\n");
															break;
		case mmc_err_invalid_data_size		:	WriteStr_uart0("mmc_err_invalid_data_size\r\n");
															break;
		case mmc_err_write						:	WriteStr_uart0("mmc_err_write\r\n");
															break;
		case mmc_err_read							:	WriteStr_uart0("mmc_err_read\r\n");
															break;
		case mmc_err_invalid_state				:	WriteStr_uart0("mmc_err_invalid_state\r\n");
															break;
		case mmc_err_crc							:	WriteStr_uart0("mmc_err_crc\r\n");
															break;
		case mmc_err_invalid_sector_count	:	WriteStr_uart0("mmc_err_invalid_sector_count\r\n");
															break;
		case mmc_err_data							:	WriteStr_uart0("mmc_err_data\r\n");
															break;
		case mmc_err_fail							:	WriteStr_uart0("mmc_err_fail\r\n");
															break;
	}
}

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

int main(void)
{
	int	i, j;
	_u32	dw;

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









	// if need be, insert your usual PLL etc initialization code here










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

	ctl_global_interrupts_disable();

	// *******************
	// initialize pin states ..
	// regardless of the 'normal' reset pin states for this chip we are gona do it ourselves anyway - just incase!

	PINSEL0 = 0;						// all pins as GPIO
	PINSEL1 = 0;						// all pins as GPIO
	PINSEL2 = 0;						// all pins as GPIO

	IO0DIR = 0;							// all pins as input
	IO1DIR = 0;							// all pins as input
	IO0SET = 0xffffffff;				// all pins high
	IO1SET = 0xffffffff;				// all pins high

	PCONP = 0;							// turn off all peripherals

	// *******************
	// initialize a few variables

	uart0_rxWr = uart0_rxRd = 0;



	// *******************
	// try to discover all the reasons for the latest reboot

	if (WDMOD & WDMOD_WDTOF)
	{	// reset was caused by the watchdog timing out - for one
		WDMOD &= ~WDMOD_WDTOF;									// clear the WDT oveflow flag
//		Flags |= Flags_WatchDogReset;							// reeeememmmmberrrrr!
	}

	// *******************
	// work out the cclk & pclk frequencies

	if ((PLLSTAT & PLLSTAT_PLLE) && (PLLSTAT & PLLSTAT_PLLC) && (PLLSTAT & PLLSTAT_PLOCK))
	{	// pll is in use & locked
		cclk = liblpc2000_get_cclk(fosc);	// our cpu clock frequency
		pclk = liblpc2000_get_pclk(cclk);	// our peripheral clock frequency
	}
	else
	{	// we are not using/connected to the pll (or it's become unlocked!) .. disable it
		PLLCON = 0;									// make sure the pll is disconnected & disabled
		PLLFEED = 0xAA;							//
		PLLFEED = 0x55;							//
		APBDIV = 0x01;								// pclk = fosc

		cclk = fosc;								// our cpu clock frequency
		pclk = fosc;								// our peripheral clock frequency
	}

	// *******************
	// wait a bit ..
	// this helps stop the i/o pins from flapping about (as we start to set their functions/state in follwing code)
	// if multiple reboots happen within a short time span

//	if (Flags & Flags_WatchDogReset) delay_ms(300);	// wait 300ms .. we were reset by the watchdog
	delay_ms(50);												// wait 50ms

	// *******************
	// set io pins up

	MMC_SWITCH_DIR &= ~MMC_SWITCH_BIT;				// pin as input

	MMC_CS_SET = MMC_CS_BIT;							// MMC CS line high
	MMC_CS_DIR |= MMC_CS_BIT;							// pin as output
	MMC_CS_SET = MMC_CS_BIT;							// MMC CS line high
	
	// *******************
	// setup peripherals

	SPI0_Initialize(100000, true, false, false, false, false, true, NULL);

	UART0_Initialize(115200, 1, uart0_ISR);		// init uart with fifo 1-byte trigger level & rx int

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

	mmc_deselect();	// just incase we rebooted without getting the MMC to let go of the SPI bus.
							// though this may not be enough - sometimes the only way to fix it is to power cycle the MMC/SD card :(

	ctl_global_interrupts_enable();			// allow interrupts to do their thing

	// ******************************************************************************
	// ******************************************************************************
	// ******************************************************************************
	// executive loop

	WriteStr_uart0("\r\n********************\r\n");






	
	
	// ***********
	// MMC/SD card example usage







	// do a sector test

	start_test_timer();																// start time - to test the speed of the routines

	i = mmc_test_sector(296);														// test sector 296
//	for (i = 0; i < 20; i++) mmc_test_sector(i);								// test first 20 sectors
//	for (i = 100; i < 200; i++) mmc_test_sector(i);							// test sectors 100 to 199
//	for (i = 0; i < MMC_Info.size_sectors; i++) mmc_test_sector(i);	// test all MMC sectors - this could take a looong time !!!!!

	dw = stop_test_timer();															// stop the timer and get timer count
	if (i >= 0)
	{
		float us = (1000000.0f * dw) / pclk;										// calc time taken (micro-seconds)
		sprintf(s, "\r\n cclk: %0.3fMHz   pclk: %0.3fMHz   sector_test_time: %0.1fuS   byte_errors:%d\r\n", (float)cclk / 1000000.0f, (float)pclk / 1000000.0f, us, i);
		WriteStr_uart0(s);																// push the string out!
	}







	i = mmc_init();																	// chip-select and init the MMC/SD
	if (i >= 0)
	{	// no error

		// test the speed of a sector read

		start_test_timer();															// start time - to test the speed of the routines

		i = mmc_read_sector(&buffer, 0, MMC_Info.size_sector);			// read a single sector

		dw = stop_test_timer();														// stop the timer and get timer count

		if (i >= 0)
		{
			float us = (1000000.0f * dw) / pclk;									// calc time taken (micro-seconds)
			sprintf(s, "\r\n cclk: %0.3fMHz   pclk: %0.3fMHz   sector_read_time: %0.1fuS\r\n", (float)cclk / 1000000.0f, (float)pclk / 1000000.0f, us);
			WriteStr_uart0(s);															// push the string out!

			// test the speed of a sector erase

			start_test_timer();															// start time - to test the speed of the routines

			i = mmc_erase_sectors(0, 1);												// erase a single sector

			dw = stop_test_timer();														// stop the timer and get timer count

			if (i >= 0)
			{
				us = (1000000.0f * dw) / pclk;									// calc time taken (micro-seconds)
				sprintf(s, " cclk: %0.3fMHz   pclk: %0.3fMHz   sector_erase_time: %0.1fuS\r\n", (float)cclk / 1000000.0f, (float)pclk / 1000000.0f, us);
				WriteStr_uart0(s);															// push the string out!

				// test the speed of a sector write

				start_test_timer();															// start time - to test the speed of the routines

				i = mmc_write_sector(&buffer, 0, MMC_Info.size_sector);			// read a single sector

				dw = stop_test_timer();														// stop the timer and get timer count

				if (i >= 0)
				{
					us = (1000000.0f * dw) / pclk;									// calc time taken (micro-seconds)
					sprintf(s, " cclk: %0.3fMHz   pclk: %0.3fMHz   sector_write_time: %0.1fuS\r\n", (float)cclk / 1000000.0f, (float)pclk / 1000000.0f, us);
					WriteStr_uart0(s);															// push the string out!
				}
				else
					ShowError(i);
			}
			else
				ShowError(i);
		}
		else
			ShowError(i);

		mmc_deselect();																// de-chip-select the MMC/SD
	}
	else
		ShowError(i);









	// simple read/write sector-0 data to a buffer from the MMC/SD
	i = mmc_read_sectors(&buffer, 0, 1);										// read data from 1 sector in the MMC
	if (i >= 0)
	{	// no error
		i = mmc_write_sectors(&buffer, 0, 1);									// write the data back to the sector(s) in the MMC
		if (i < 0) ShowError(i);
	}
	else
		ShowError(i);








	// read several sectors (one at a time)
	i = mmc_init();																		// chip-select and init the MMC/SD
	if (i >= 0)
	{	// no error
		start_test_timer();															// start time - to test the speed of the routines

		for (j = 0; j < 40; j++)													// sectors 0 to 39
		{
			i = mmc_read_sector(&buffer, j, MMC_Info.size_sector);		// read a single sector

			if (i >= 0)
			{	// no error



				// do wot you wanna do with the sector data here



			}
			else
				ShowError(i);
		}

		dw = stop_test_timer();															// stop the timer and get timer count
		float us = (1000000.0f * dw) / pclk;										// calc time taken (micro-seconds)
		sprintf(s, "\r\n cclk: %0.3fMHz   pclk: %0.3fMHz   40_sector_read_time: %0.1fuS\r\n", (float)cclk / 1000000.0f, (float)pclk / 1000000.0f, us);
		WriteStr_uart0(s);																// push the string out!

		mmc_deselect();																	// de-chip-select the MMC/SD
	}
	else
		ShowError(i);










	// read/erase/write-back several sectors (one at a time)
	i = mmc_init();																		// chip-select and init the MMC/SD
	if (i >= 0)
	{
		for (j = 0; j < 5; j++)
		{
			i = mmc_read_sector(&buffer, j, MMC_Info.size_sector);			// read a sector
			if (i >= 0)
			{
				i = mmc_erase_sectors(j, 1);											// erase the sector
				if (i < 0) ShowError(i);

				i = mmc_write_sector(&buffer, j, MMC_Info.size_sector);		// write it back
				if (i < 0) ShowError(i);
			}
			else
				ShowError(i);
		}
		mmc_deselect();																	// de-chip-select the MMC/SD
	}
	else
		ShowError(i);










	// main exec loop

	for (i = 0; ; i++)
	{ 
		// ***********************
		// process any incoming RS232 bytes

		while (uart0_rxRd != uart0_rxWr)
		{
			_u8 c = uart0_rxBuf[uart0_rxRd];
			if (++uart0_rxRd >= sizeof(uart0_rxBuf)) uart0_rxRd = 0;

//			WriteByte_uart0(c, 1000000);	// echo it back down the RS232 port
		}










	}

	// ******************************************************************************
	// ******************************************************************************
	// ******************************************************************************
	// we should never end up here!

	return 0;
}

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

⌨️ 快捷键说明

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