/* ATmega128 I/O register definitions */
#include <mega128.h>
/* FAT on MMC/SD/SD HC card support */
#include <ff.h>
/* printf */
#include <stdio.h>
/* string functions */
#include <string.h>
/* Timer1 overflow interrupt frequency [Hz] */
#define T1_OVF_FREQ 100
/* Timer1 clock prescaler value */
#define T1_PRESC 1024L
/* Timer1 initialization value after overflow */
#define T1_INIT (0x10000L-(_MCU_CLOCK_FREQUENCY_/(T1_PRESC*T1_OVF_FREQ)))
/* USART Baud rate */
#define BAUD_RATE 19200
#define BAUD_INIT (_MCU_CLOCK_FREQUENCY_/(BAUD_RATE*16L)-1)
/* 100Hz timer interrupt generated by ATmega128 Timer1 overflow */
interrupt [TIM1_OVF] void timer_comp_isr(void)
{
/* re-initialize Timer1 */
TCNT1H=T1_INIT>>8;
TCNT1L=T1_INIT&0xFF;
/* MMC/SD/SD HC card access low level timing function */
disk_timerproc();
}
/* error message list */
flash char * flash error_msg[]=
{
"", /* not used */
"FR_DISK_ERR",
"FR_INT_ERR",
"FR_INT_ERR",
"FR_NOT_READY",
"FR_NO_FILE",
"FR_NO_PATH",
"FR_INVALID_NAME",
"FR_DENIED",
"FR_EXIST",
"FR_INVALID_OBJECT",
"FR_WRITE_PROTECTED",
"FR_INVALID_DRIVE",
"FR_NOT_ENABLED",
"FR_NO_FILESYSTEM",
"FR_MKFS_ABORTED",
"FR_TIMEOUT"
};
/* display error message and stop */
void error(FRESULT res)
{
if ((res>=FR_DISK_ERR) && (res<=FR_TIMEOUT))
printf("ERROR: %p\r\n",error_msg[res]);
/* stop here */
while(1);
}
/* will hold file/directory information returned by f_readdir*/
FILINFO file_info;
/* recursively scan directory entries and display them */
FRESULT directory_scan(char *path)
{
/* will hold the directory information */
DIR directory;
/* FAT function result */
FRESULT res;
int i;
if ((res=f_opendir(&directory,path))==FR_OK)
{
while (((res=f_readdir(&directory,&file_info))==FR_OK) &&
file_info.fname[0])
{
/* display file/directory name and associated information */
printf("%c%c%c%c%c %02u/%02u/%u %02u:%02u:%02u %9lu" " %s/%s\r\n",
(file_info.fattrib & AM_DIR) ? 'D' : '-',
(file_info.fattrib & AM_RDO) ? 'R' : '-',
(file_info.fattrib & AM_HID) ? 'H' : '-',
(file_info.fattrib & AM_SYS) ? 'S' : '-',
(file_info.fattrib & AM_ARC) ? 'A' : '-',
file_info.fdate & 0x1F,(file_info.fdate >> 5) & 0xF,
(file_info.fdate >> 9)+1980,
file_info.ftime >> 11,(file_info.ftime >> 5) & 0x3F,
(file_info.ftime & 0xF) << 1,
file_info.fsize,path,file_info.fname);
if (file_info.fattrib & AM_DIR)
{
/* its a subdirectory */
/* make sure to skip past "." and ".." when recursing */
if (file_info.fname[0]!='.')
{
i=strlen(path);
/* append the subdirectory name to the path */
if (path[i-1]!='/') strcatf(path,"/");
strcat(path,file_info.fname);
/* scan subdirectory */
res=directory_scan(path);
/* restore the old path name */
path[i]=0;
/* remove any eventual '/' from the end of the path */
--i;
if (path[i]=='/') path[i]=0;
/* stop if an error occured */
if (res!=FR_OK) break;
}
}
}
}
return res;
}
void main(void)
{
/* FAT function result */
FRESULT res;
/* will hold the information for logical drive 0: */
FATFS drive;
/* root directory path */
char path[256]="0:/";
/* initialize Timer1 overflow interrupts in Mode 0 (Normal) */
TCCR1A=0x00;
/* clkio/1024 */
TCCR1B=(1<<CS12)|(1<<CS10);
/* timer overflow interrupts will occur with 100Hz frequency */
TCNT1H=T1_INIT>>8;
TCNT1L=T1_INIT&0xFF;
/* enable Timer1 overflow interrupt */
TIMSK=1<<TOIE1;
/* initialize the USART0 TX, 8N1, Baud rate: 19200 */
UCSR0A=0;
UCSR0B=1<<TXEN0;
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);
UBRR0H=BAUD_INIT>>8;
UBRR0L=BAUD_INIT&0xFF;
/* globally enable interrupts */
#asm("sei")
printf("Directory listing for root of logical drive 0:\r\n");
/* mount logical drive 0: */
if ((res=f_mount(0,&drive))==FR_OK)
printf("Logical drive 0: mounted OK\r\n");
else
/* an error occured, display it and stop */
error(res);
/* repeateadly read directory entries and display them */
if ((res=directory_scan(path))!=FR_OK)
/* if an error occured, display it and stop */
error(res);
/* stop here */
while(1);
}