Commit af1e498d authored by Daniel Kampert's avatar Daniel Kampert

Finalize SD card example

parent b43e8434
......@@ -98,44 +98,44 @@
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings>
<AvrGcc>
<avrgcc.common.Device>-mmcu=atxmega384c3 -B "%24(PackRepoDir)\atmel\XMEGAC_DFP\1.1.50\gcc\dev\atxmega384c3"</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>DEBUG</Value>
<Value>MCU_NAME=MCU_NAME_ATXMEGA384C3</Value>
<Value>MCU_ARCH=MCU_ARCH_XMEGA</Value>
</ListValues>
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\XMEGAC_DFP\1.1.50\include</Value>
<Value>../../../../../include</Value>
<Value>../include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcc.linker.libraries.Libraries>
<avrgcc.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\XMEGAC_DFP\1.1.50\include</Value>
</ListValues>
</avrgcc.assembler.general.IncludePaths>
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
</AvrGcc>
<avrgcc.common.Device>-mmcu=atxmega384c3 -B "%24(PackRepoDir)\atmel\XMEGAC_DFP\1.1.50\gcc\dev\atxmega384c3"</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>DEBUG</Value>
<Value>MCU_NAME=MCU_NAME_ATXMEGA384C3</Value>
<Value>MCU_ARCH=MCU_ARCH_XMEGA</Value>
</ListValues>
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\XMEGAC_DFP\1.1.50\include</Value>
<Value>../../../../../include</Value>
<Value>../include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcc.linker.libraries.Libraries>
<avrgcc.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\XMEGAC_DFP\1.1.50\include</Value>
</ListValues>
</avrgcc.assembler.general.IncludePaths>
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
</AvrGcc>
</ToolchainSettings>
</PropertyGroup>
<ItemGroup>
......@@ -160,6 +160,24 @@
<Compile Include="source\Peripheral\SD\SD.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="source\Services\FatFs\diskio.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="source\Services\FatFs\fatfs-r0.13c\source\diskio.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="source\Services\FatFs\fatfs-r0.13c\source\ff.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="source\Services\FatFs\fatfs-r0.13c\source\ff.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="source\Services\FatFs\fatfs-r0.13c\source\ffsystem.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="source\Services\FatFs\fatfs-r0.13c\source\ffunicode.c">
<SubType>compile</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="include" />
......@@ -171,6 +189,8 @@
<Folder Include="source\Peripheral" />
<Folder Include="source\Peripheral\SD" />
<Folder Include="source\Services\FatFs" />
<Folder Include="source\Services\FatFs\fatfs-r0.13c" />
<Folder Include="source\Services\FatFs\fatfs-r0.13c\source" />
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project>
\ No newline at end of file
......@@ -239,7 +239,7 @@
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
#define FF_FS_NORTC 0
#define FF_FS_NORTC 1
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2018
......
......@@ -33,6 +33,7 @@
*/
#include "Peripheral/SD/SD.h"
#include "source/Services/FatFs/fatfs-r0.13c/source/ff.h"
SPIM_Config_t SDConfig = {
.SPIClock = 1000000,
......@@ -43,6 +44,13 @@ SPIM_Config_t SDConfig = {
SD_Error_t Error;
FATFS MicroSD_FS;
FRESULT FileStatus;
FIL LogFile;
UINT Return;
char FilePath[] = "0:File.txt";
char ReadData[13];
int main(void)
{
SysClock_Init();
......@@ -73,6 +81,18 @@ int main(void)
uint8_t Sectors[1024];
Error = SD_ReadDataBlocks(0x00, 2, Sectors);
FileStatus = f_mount(&MicroSD_FS, "0:", 1);
if(FileStatus == FR_OK)
{
FileStatus = f_open(&LogFile, FilePath, FA_WRITE | FA_CREATE_ALWAYS);
FileStatus = f_puts("Hello, World!", &LogFile);
FileStatus = f_close(&LogFile);
FileStatus = f_open(&LogFile, FilePath, FA_READ | FA_OPEN_EXISTING);
FileStatus = f_read(&LogFile, ReadData, 13, &Return);
FileStatus = f_close(&LogFile);
}
while(1)
{
}
......
......@@ -617,7 +617,7 @@ const SD_Error_t SD_GetSectors(uint32_t* Sectors)
/*
Version 2 or later SD card
*/
if((CSD[0] >> 0x06))
if((__CardType == SD_VER_2_STD) || (__CardType == SD_VER_2_HI))
{
Size = CSD[9] + (CSD[8] << 8) + 0x01;
*Sectors = Size << 0x0A;
......
/*
* diskio.c
*
* Copyright (C) Daniel Kampert, 2018
* Website: www.kampis-elektroecke.de
* File info: Low level disk operations for FatFs driver.
GNU GENERAL PUBLIC LICENSE:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Errors and commissions should be reported to DanielKampert@kampis-elektroecke.de
*/
/** @file Common/Services/FatFs/diskio.h
* @brief Low level disk operations for FatFs driver.
*
* @author Daniel Kampert
*/
#include "fatfs-r0.13c/source/ff.h"
#include "fatfs-r0.13c/source/diskio.h"
#include "Peripheral/SD/SD.h"
#define DEV_MMC 0 /**< Map MMC/SD card to physical drive 0 */
SPIM_Config_t __InterfaceConfig = {
.SPIClock = 1000000,
.DataOrder = SPI_DATAORDER_MSB_FIRST,
.Mode = SPI_MODE_0,
.Device = SD_INTERFACE
};
// Disk status
static volatile DSTATUS __MMCStatus = STA_NOINIT;
DSTATUS disk_initialize(
BYTE pdrv /* Physical drive number to identify the drive */
)
{
switch(pdrv)
{
case DEV_MMC:
{
if(SD_Init(&__InterfaceConfig) == SD_SUCCESSFULL)
{
__MMCStatus &= ~STA_NOINIT;
return __MMCStatus;
}
}
default:
{
return STA_NOINIT;
}
}
}
DSTATUS disk_status(
BYTE pdrv /* Physical drive number to identify the drive */
)
{
switch(pdrv)
{
case DEV_MMC:
{
return __MMCStatus;
}
default:
{
return STA_NOINIT;
}
}
}
DRESULT disk_read (
BYTE pdrv, /* Physical drive number to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
switch(pdrv)
{
case DEV_MMC:
{
if(__MMCStatus & STA_NOINIT)
{
return RES_NOTRDY;
}
// Read a single block
if(count == 1)
{
if(SD_ReadDataBlock(sector, buff) == SD_SUCCESSFULL)
{
return RES_OK;
}
}
// Read multiple blocks
else
{
if(SD_ReadDataBlocks(sector, count, buff) == SD_SUCCESSFULL)
{
return RES_OK;
}
}
return RES_ERROR;
}
default:
{
return RES_NOTRDY;
}
}
return RES_PARERR;
}
DRESULT disk_write(
BYTE pdrv, /* Physical drive number to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
switch(pdrv)
{
case DEV_MMC:
{
if(__MMCStatus & STA_NOINIT)
{
return RES_NOTRDY;
}
// Write a single block
if(count == 1)
{
if(SD_WriteDataBlock(sector, buff) == SD_SUCCESSFULL)
{
return RES_OK;
}
}
// Write multiple blocks
else
{
if(SD_WriteDataBlocks(sector, count, buff) == SD_SUCCESSFULL)
{
return RES_OK;
}
}
return RES_ERROR;
}
default:
{
return RES_NOTRDY;
}
}
return RES_PARERR;
}
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive number (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
BYTE *ptr = (BYTE*)buff;
switch(pdrv)
{
case DEV_MMC:
{
switch(cmd)
{
case GET_BLOCK_SIZE:
{
if(SD_GetEraseBlockSize((uint16_t*)ptr) == SD_SUCCESSFULL)
{
return RES_OK;
}
return RES_OK;
}
case GET_SECTOR_COUNT:
{
if(SD_GetSectors((DWORD*)ptr) == SD_SUCCESSFULL)
{
return RES_OK;
}
return RES_ERROR;
}
case GET_SECTOR_SIZE:
{
*(WORD*)buff = SD_BLOCK_SIZE;
// ToDo: Support for older SD cards with smaller sectors than 512 Byte
return RES_OK;
}
case CTRL_SYNC:
{
SD_Sync();
return RES_OK;
}
default:
{
return RES_PARERR;
}
}
}
default:
{
return RES_PARERR;
}
}
}
\ No newline at end of file
FatFs License
FatFs has being developped as a personal project of the author, ChaN. It is free from the code anyone else wrote at current release. Following code block shows a copy of the FatFs license document that heading the source files.
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem Module Rx.xx /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 20xx, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
/
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/----------------------------------------------------------------------------*/
Therefore FatFs license is one of the BSD-style licenses but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, does not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses including GNU GPL. When you redistribute the FatFs source code with any changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="cache-control" content="no-cache">
<meta name="description" content="Open source FAT filesystem for embedded projects">
<link rel="stylesheet" href="css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - Generic FAT Filesystem Module</title>
</head>
<body>
<h1>FatFs - Generic FAT Filesystem Module</h1>
<hr>
<div class="abst">
<img src="res/layers.png" class="rset" width="245" height="255" alt="layer">
<p>FatFs is a generic FAT/exFAT filesystem module for small embedded systems. The FatFs module is written in compliance with ANSI C (C89) and completely separated from the disk I/O layer. Therefore it is independent of the platform. It can be incorporated into small microcontrollers with limited resource, such as 8051, PIC, AVR, ARM, Z80, RX and etc. Also Petit FatFs module for tiny microcontrollers is available <a href="http://elm-chan.org/fsw/ff/00index_p.html">here</a>.</p>
<h4>Features</h4>
<ul>
<li>DOS/Windows compatible FAT/exFAT filesystem.</li>
<li>Platform independent. Easy to port.</li>
<li>Very small footprint for program code and work area.</li>
<li>Various <a href="doc/config.html">configuration options</a> to support for:
<ul>
<li>Long file name in ANSI/OEM or Unicode.</li>
<li>exFAT filesystem.</li>
<li>Thread safe for RTOS.</li>
<li>Multiple volumes (physical drives and partitions).</li>
<li>Variable sector size.</li>
<li>Multiple code pages including DBCS.</li>
<li>Read-only, optional API, I/O buffer and etc...</li>
</ul>
</li>
</ul>
</div>
<div class="para">
<h3>Application Interface</h3>
<img src="res/layers1.png" class="rset" width="245" height="220" alt="layer">
<p>FatFs provides various filesystem functions for the applications as shown below.</p>
<ul>
<li>File Access
<ul>
<li><a href="doc/open.html">f_open</a> - Open/Create a file</li>
<li><a href="doc/close.html">f_close</a> - Close an open file</li>
<li><a href="doc/read.html">f_read</a> - Read data from the file</li>
<li><a href="doc/write.html">f_write</a> - Write data to the file</li>
<li><a href="doc/lseek.html">f_lseek</a> - Move read/write pointer, Expand size</li>
<li><a href="doc/truncate.html">f_truncate</a> - Truncate file size</li>
<li><a href="doc/sync.html">f_sync</a> - Flush cached data</li>
<li><a href="doc/forward.html">f_forward</a> - Forward data to the stream</li>
<li><a href="doc/expand.html">f_expand</a> - Allocate a contiguous block to the file</li>
<li><a href="doc/gets.html">f_gets</a> - Read a string</li>
<li><a href="doc/putc.html">f_putc</a> - Write a character</li>
<li><a href="doc/puts.html">f_puts</a> - Write a string</li>
<li><a href="doc/printf.html">f_printf</a> - Write a formatted string</li>
<li><a href="doc/tell.html">f_tell</a> - Get current read/write pointer</li>
<li><a href="doc/eof.html">f_eof</a> - Test for end-of-file</li>
<li><a href="doc/size.html">f_size</a> - Get size</li>
<li><a href="doc/error.html">f_error</a> - Test for an error</li>
</ul>
</li>
<li>Directory Access
<ul>
<li><a href="doc/opendir.html">f_opendir</a> - Open a directory</li>
<li><a href="doc/closedir.html">f_closedir</a> - Close an open directory</li>
<li><a href="doc/readdir.html">f_readdir</a> - Read an directory item</li>
<li><a href="doc/findfirst.html">f_findfirst</a> - Open a directory and read the first item matched</li>
<li><a href="doc/findnext.html">f_findnext</a> - Read a next item matched</li>
</ul>
</li>
<li>File and Directory Management
<ul>
<li><a href="doc/stat.html">f_stat</a> - Check existance of a file or sub-directory</li>
<li><a href="doc/unlink.html">f_unlink</a> - Remove a file or sub-directory</li>
<li><a href="doc/rename.html">f_rename</a> - Rename/Move a file or sub-directory</li>
<li><a href="doc/chmod.html">f_chmod</a> - Change attribute of a file or sub-directory</li>
<li><a href="doc/utime.html">f_utime</a> - Change timestamp of a file or sub-directory</li>
<li><a href="doc/mkdir.html">f_mkdir</a> - Create a sub-directory</li>
<li><a href="doc/chdir.html">f_chdir</a> - Change current directory</li>
<li><a href="doc/chdrive.html">f_chdrive</a> - Change current drive</li>
<li><a href="doc/getcwd.html">f_getcwd</a> - Retrieve the current directory and drive</li>
</ul>
</li>
<li>Volume Management and System Configuration
<ul>
<li><a href="doc/mount.html">f_mount</a> - Register/Unregister the work area of the volume</li>
<li><a href="doc/mkfs.html">f_mkfs</a> - Create an FAT volume on the logical drive</li>
<li><a href="doc/fdisk.html">f_fdisk</a> - Create logical drives on the physical drive</li>
<li><a href="doc/getfree.html">f_getfree</a> - Get total size and free size on the volume</li>
<li><a href="doc/getlabel.html">f_getlabel</a> - Get volume label</li>
<li><a href="doc/setlabel.html">f_setlabel</a> - Set volume label</li>
<li><a href="doc/setcp.html">f_setcp</a> - Set active code page</li>
</ul>
</li>
</ul>
</div>
<div class="para">
<h3>Media Access Interface</h3>
<img src="res/layers2.png" class="rset" width="245" height="220" alt="layer">
<p>Since the FatFs module is the <em>filesystem layer</em> independent of platforms and storage media, it is completely separated from the physical devices, such as memory card, harddisk and any type of storage device. The low level device control module is <em>not a part of FatFs module</em> and it needs to be provided by implementer. FatFs accesses the storage devices via a simple media access interface shown below. Also sample implementations for some platforms are available in the downloads. A function checker for low level disk I/O module is available <a href="res/app4.c">here</a>.</p>
<ul>
<li><a href="doc/dstat.html">disk_status</a> - Get device status</li>
<li><a href="doc/dinit.html">disk_initialize</a> - Initialize device</li>
<li><a href="doc/dread.html">disk_read</a> - Read sector(s)</li>
<li><a href="doc/dwrite.html">disk_write</a> - Write sector(s)</li>
<li><a href="doc/dioctl.html">disk_ioctl</a> - Control device dependent functions</li>
<li><a href="doc/fattime.html">get_fattime</a> - Get current time</li>
</ul>
</div>
<div class="para">
<h3>Resources</h3>
<p>The FatFs module is a free software opened for education, research and development. You can use, modify and/or redistribute it for personal projects or commercial products without any restriction under your responsibility. For further information, refer to the application note.</p>
<ul>
<li>Read first: <a href="doc/appnote.html">FatFs module application note</a></li>
<li>Download: <a href="http://elm-chan.org/fsw/ff/archives.html">Archives of FatFs and Petit-FatFs</a></li>
<li>Community: <a href="http://elm-chan.org/fsw/ff/bd/">FatFs User Forum</a></li>
<li><a href="https://msdn.microsoft.com/en-us/windows/hardware/gg463080.aspx">FAT32 Specification by Microsoft</a>↗ (The authorized document on FAT filesystem)</li>
<li><a href="http://elm-chan.org/docs/fat_e.html">The basics of FAT filesystem</a></li>
<li><a href="http://elm-chan.org/docs/exfat_e.html">The basics of exFAT filesystem</a></li>
<li><a href="http://elm-chan.org/docs/mmc/mmc_e.html">How to use MMC/SDC</a></li>
<li><a href="http://elm-chan.org/junk/fa/faff.html">Playing with FlashAir and FatFs</a></li>
<li><a href="http://nemuisan.blog.bai.ne.jp/">Nemuisan's Blog</a>↗ (Well written implementations for STM32F/SPI &amp; SDIO and LPC4088/SDMMC)</li>
<li><a href="http://stm32f4-discovery.net/2014/07/library-21-read-sd-card-fatfs-stm32f4xx-devices/">Read SD card with FatFs on STM32F4xx devices by Tilen Majerle</a>↗ (Quick and easy implementation for STM32F4-Discovery)</li>
<li><a href="res/rwtest1.png">Benchmark 1</a> (ATmega1284/20MHz with MMC via USART in SPI, CFC via GPIO)</li>
<li><a href="res/rwtest2.png">Benchmark 2</a> (LPC2368/72MHz with MMC via MCI)</li>
<li><a href="res/fd.mp4">Demo movie of an application</a> (this project is in ffsample.zip/lpc23xx)</li></ul>
</div>
<hr>
<p class="foot"><a href="http://elm-chan.org/fsw/ff/00index_e.html">FatFs Home Page</a></p>
</body>
</html>
* {margin: 0; padding: 0; border-width: 0;}
body {margin: 8px; background-color: #e0ffff; font-color: black; font-family: serif; line-height: 133%; max-width: 1024px;}
a:link {color: blue;}
a:visited {color: darkmagenta;}
a:hover {background-color: #a0ffff;}
a:active {color: darkmagenta; overflow: hidden; outline:none; position: relative; top: 1px; left: 1px;}
abbr {border-width: 1px;}
p {margin: 0 0 0.3em 1em;}
i {margin: 0 0.3em 0 0;}
b {margin: 0 0.1em;}
em {font-style: normal; font-weight: bold; margin: 0 0.1em;}
strong {}
pre {border: 1px dashed gray; margin: 0.5em 1em; padding: 0.5em; line-height: 1.2em; font-size: 85%; font-family: "Consolas", "Courier New", monospace; background-color: white;}
pre span.c {color: green;}
pre span.k {color: blue;}
pre span.b {font-weight: bold;}
pre span.arg {font-style: italic;}
tt {margin: 0 0.2em; font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; }
tt.arg {font-style: italic;}
ol {margin: 0.5em 2.5em;}
ul {margin: 0.5em 2em;}
ul ul {margin: 0 2em 0.5em 1em;}
dl {margin: 0.5em 1em;}
dd {margin: 0 2em;}
dt {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace;}
dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; }
dl.ret dt {margin: 0.5em 0 0 0 ; font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; font-weight: bold; }
hr {border-width: 1px; margin: 1em;}
div.abst {font-family: sans-serif;}
div.para {clear: both; font-family: serif;}
div.ret a {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; }
.equ {text-indent: 0; margin: 1em 2em 1em;}
.indent {margin-left: 2em;}
.rset {float: right; margin: 0.3em 0 0.5em 0.5em;}
.lset {float: left; margin: 0.3em 0.5em 0.5em 0.5em;}
ul.flat li {list-style-type: none; margin: 0;}
a.imglnk img {border: 1px solid;}
.iequ {white-space: nowrap; font-weight: bold;}
.clr {clear: both;}
.it {font-style: italic;}
.mfd {font-size: 0.7em; padding: 0 1px; border: 1px solid; white-space : nowrap}
.ral {text-align: right; }
.lal {text-align: left; }
.cal {text-align: center; }
h1 {line-height: 1em; font-size: 2em; font-family: sans-serif; padding: 0.3em 0 0.3em;}
h2 {font-size: 2em; font-family: sans-serif; background-color: #d8d8FF; padding: 0.5em 0.5em; margin: 0 0 0.5em;}
h3 {font-size: 1.5em; font-family: sans-serif; margin: 1.5em 0 0.5em;}
div.doc h3 {border-color: #b0d8d8; border-style: solid; border-width: 0px 0px 4px 12px; padding: 4px; margin-top: 3em;}
h4 {font-size: 1.2em; font-family: sans-serif; margin: 2em 0 0.2em;}
h5 {font-size: 1em; font-family: sans-serif; margin: 1em 0 0em;}
p.hdd {float: right; text-align: right; margin-top: 0.5em;}
hr.hds {clear: both; margin-bottom: 1em;}
kbd {letter-spacing: 0;}
small {font-size: 80%;}