📄 main.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 + -