/******************************************************************************
Microchip Memory Disk Drive File System
*****************************************************************************
FileName: FS Phys Interface Template.c
Dependencies: TEMPLATEFILE.h
string.h
FSIO.h
FSDefs.h
Processor: None
Compiler: None
Company: Microchip Technology, Inc.
Software License Agreement
The software supplied herewith by Microchip Technology Incorporated
(the Company) for its PICmicro® Microcontroller is intended and
supplied to you, the Companys customer, for use solely and
exclusively on Microchip PICmicro Microcontroller products. The
software is owned by the Company and/or its supplier, and is
protected under applicable copyright laws. All rights are reserved.
Any use in violation of the foregoing restrictions may subject the
user to criminal sanctions under applicable laws, as well as to
civil liability for the breach of the terms and conditions of this
license.
THIS SOFTWARE IS PROVIDED IN AN AS IS CONDITION. NO WARRANTIES,
WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*****************************************************************************/
//DOM-IGNORE-BEGIN
/********************************************************************
Change History:
Rev Description
----- -----------
1.2.5 Fixed bug where sector address was calculated incorrectly
1.2.6 No change
********************************************************************/
//DOM-IGNORE-END
#include "Compiler.h"
#include "MDD File System\FSIO.h"
#include "MDD File System\FSDefs.h"
#include "string.h"
#include "MDD File System\Internal Flash.h"
#include "HardwareProfile.h"
#include "FSConfig.h"
/*************************************************************************/
/* Note: This file is included as a template of a C file for */
/* a new physical layer. It is designed to go with */
/* "TEMPLATEFILE.h" */
/*************************************************************************/
/******************************************************************************
* Global Variables
*****************************************************************************/
#ifdef USE_PIC18
#pragma udata
#pragma code
#endif
static MEDIA_INFORMATION mediaInformation;
/******************************************************************************
* Prototypes
*****************************************************************************/
void EraseBlock(ROM BYTE* dest);
void WriteRow(void);
void WriteByte(unsigned char);
BYTE DISKmount( DISK *dsk);
BYTE LoadMBR(DISK *dsk);
BYTE LoadBootSector(DISK *dsk);
extern void Delayms(BYTE milliseconds);
MEDIA_INFORMATION * MediaInitialize(void);
/******************************************************************************
* Function: BYTE MediaDetect(void)
*
* PreCondition: InitIO() function has been executed.
*
* Input: void
*
* Output: TRUE - Card detected
* FALSE - No card detected
*
* Side Effects: None
*
* Overview: None
*
* Note: None
*****************************************************************************/
BYTE MDD_IntFlash_MediaDetect()
{
return TRUE;
}//end MediaDetect
/******************************************************************************
* Function: WORD ReadSectorSize(void)
*
* PreCondition: MediaInitialize() is complete
*
* Input: void
*
* Output: WORD - size of the sectors for this physical media.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
*****************************************************************************/
WORD MDD_IntFlash_ReadSectorSize(void)
{
return MEDIA_SECTOR_SIZE;
}
/******************************************************************************
* Function: DWORD ReadCapacity(void)
*
* PreCondition: MediaInitialize() is complete
*
* Input: void
*
* Output: DWORD - size of the "disk"
*
* Side Effects: None
*
* Overview: None
*
* Note: None
*****************************************************************************/
DWORD MDD_IntFlash_ReadCapacity(void)
{
return MDD_INTERNAL_FLASH_TOTAL_DISK_SIZE;
}
/******************************************************************************
* Function: BYTE InitIO(void)
*
* PreCondition: None
*
* Input: void
*
* Output: TRUE - Card initialized
* FALSE - Card not initialized
*
* Side Effects: None
*
* Overview: None
*
* Note: None
*****************************************************************************/
BYTE MDD_IntFlash_InitIO (void)
{
return TRUE;
}
/******************************************************************************
* Function: BYTE MediaInitialize(void)
*
* PreCondition: None
*
* Input: None
*
* Output: Returns a pointer to a MEDIA_INFORMATION structure
*
* Overview: MediaInitialize initializes the media card and supporting variables.
*
* Note: None
*****************************************************************************/
MEDIA_INFORMATION * MDD_IntFlash_MediaInitialize(void)
{
mediaInformation.errorCode = MEDIA_NO_ERROR;
return &mediaInformation;
}//end MediaInitialize
/******************************************************************************
* Function: BYTE SectorRead(DWORD sector_addr, BYTE *buffer)
*
* PreCondition: None
*
* Input: sector_addr - Sector address, each sector contains 512-byte
* buffer - Buffer where data will be stored, see
* 'ram_acs.h' for 'block' definition.
* 'Block' is dependent on whether internal or
* external memory is used
*
* Output: Returns TRUE if read successful, false otherwise
*
* Side Effects: None
*
* Overview: SectorRead reads 512 bytes of data from the card starting
* at the sector address specified by sector_addr and stores
* them in the location pointed to by 'buffer'.
*
* Note: The device expects the address field in the command packet
* to be byte address. Therefore the sector_addr must first
* be converted to byte address. This is accomplished by
* shifting the address left 9 times.
*****************************************************************************/
BYTE MDD_IntFlash_SectorRead(DWORD sector_addr, BYTE* buffer)
{
#if defined(__C30__)
#if defined(__PIC24FJ256DA210__) \
|| defined(__PIC24FJ128DA210__) \
|| defined(__PIC24FJ256DA206__) \
|| defined(__PIC24FJ128DA206__) \
|| defined(__PIC24FJ256DA110__) \
|| defined(__PIC24FJ128DA110__) \
|| defined(__PIC24FJ256DA106__) \
|| defined(__PIC24FJ128DA106__) \
|| defined(__PIC24FJ256GB210__)
WORD DSRPageSave;
DSRPageSave = DSRPAG;
DSRPAG = (FILES_ADDRESS + sector_addr * MEDIA_SECTOR_SIZE)/0x8000 + 0x0200;
#else
WORD PSVPageSave;
PSVPageSave = PSVPAG;
PSVPAG = (FILES_ADDRESS + sector_addr * MEDIA_SECTOR_SIZE)/0x8000;
#endif
#endif
memcpypgm2ram
(
(void*)buffer,
(ROM void*)(MASTER_BOOT_RECORD_ADDRESS + (sector_addr * MEDIA_SECTOR_SIZE)),
MEDIA_SECTOR_SIZE
);
#if defined(__C30__)
#if defined(__PIC24FJ256DA210__) \
|| defined(__PIC24FJ128DA210__) \
|| defined(__PIC24FJ256DA206__) \
|| defined(__PIC24FJ128DA206__) \
|| defined(__PIC24FJ256DA110__) \
|| defined(__PIC24FJ128DA110__) \
|| defined(__PIC24FJ256DA106__) \
|| defined(__PIC24FJ128DA106__) \
|| defined(__PIC24FJ256GB210__)
DSRPAG = DSRPageSave;
#else
PSVPAG = PSVPageSave;
#endif
#endif
return TRUE;
}//end SectorRead
/******************************************************************************
* Function: BYTE SectorWrite(DWORD sector_addr, BYTE *buffer, BYTE allowWriteToZero)
*
* PreCondition: None
*
* Input: sector_addr - Sector address, each sector contains 512-byte
* buffer - Buffer where data will be read
* allowWriteToZero - If true, writes to the MBR will be valid
*
* Output: Returns TRUE if write successful, FALSE otherwise
*
* Side Effects: None
*
* Overview: SectorWrite sends 512 bytes of data from the location
* pointed to by 'buffer' to the card starting
* at the sector address specified by sector_addr.
*
* Note: The sample device expects the address field in the command packet
* to be byte address. Therefore the sector_addr must first
* be converted to byte address. This is accomplished by
* shifting the address left 9 times.
*****************************************************************************/
#if defined(__18CXX)
#pragma udata myFileBuffer
#endif
volatile unsigned char file_buffer[ERASE_BLOCK_SIZE] __attribute__((far));
#if defined(__18CXX)
#pragma udata
#endif
#define INTERNAL_FLASH_PROGRAM_WORD 0x4003
#define INTERNAL_FLASH_ERASE 0x4042
#define INTERNAL_FLASH_PROGRAM_PAGE 0x4001
#if defined(__C32__)
#define PTR_SIZE DWORD
#else
#define PTR_SIZE WORD
#endif
ROM BYTE *FileAddress = 0;
BYTE MDD_IntFlash_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero)
{
#if !defined(INTERNAL_FLASH_WRITE_PROTECT)
ROM BYTE* dest;
BOOL foundDifference;
WORD blockCounter;
WORD sectorCounter;
#if defined(__18CXX)
BYTE *p;
#endif
#if defined(__C30__)
#if defined(__PIC24FJ256DA210__) \
|| defined(__PIC24FJ128DA210__) \
|| defined(__PIC24FJ256DA206__) \
|| defined(__PIC24FJ128DA206__) \
|| defined(__PIC24FJ256DA110__) \
|| defined(__PIC24FJ128DA110__) \
|| defined(__PIC24FJ256DA106__) \
|| defined(__PIC24FJ128DA106__) \
|| defined(__PIC24FJ256GB210__)
WORD DSRPageSave;
DSRPageSave = DSRPAG;
DSRPAG = (FILES_ADDRESS + sector_addr * MEDIA_SECTOR_SIZE)/0x8000 + 0x0200;
#else
WORD PSVPageSave;
PSVPageSave = PSVPAG;
PSVPAG = (FILES_ADDRESS + sector_addr * MEDIA_SECTOR_SIZE)/0x8000;
#endif
#endif
dest = (ROM BYTE*)(MASTER_BOOT_RECORD_ADDRESS + (sector_addr * MEDIA_SECTOR_SIZE));
sectorCounter = 0;
while(sectorCounter < MEDIA_SECTOR_SIZE)
{
foundDifference = FALSE;
for(blockCounter = 0; blockCounter < ERASE_BLOCK_SIZE; blockCounter++)
{
if(dest[sectorCounter] != buffer[sectorCounter])
{
foundDifference = TRUE;
sectorCounter -= blockCounter;
break;
}
sectorCounter++;
}
if(foundDifference == TRUE)
{
BYTE i,j;
PTR_SIZE address;
#if (ERASE_BLOCK_SIZE >= MEDIA_SECTOR_SIZE)
address = ((PTR_SIZE)(dest + sectorCounter) & ~(ERASE_BLOCK_SIZE - 1));
memcpypgm2ram
(
(void*)file_buffer,
(ROM void*)address,
ERASE_BLOCK_SIZE
);
EraseBlock((ROM BYTE*)address);
address = ((PTR_SIZE)(dest + sectorCounter) & (ERASE_BLOCK_SIZE - 1));
memcpy
(
(void*)(&file_buffer[address]),
(void*)buffer,
MEDIA_SECTOR_SIZE
);
#else
address = ((WORD)(&dest[sectorCounter]) & ~(ERASE_BLOCK_SIZE - 1));
EraseBlock((ROM BYTE*)address);
sectorCounter = sectorCounter & ~(ERASE_BLOCK_SIZE - 1);
memcpy
(
(void*)file_buffer,
(void*)buffer+sectorCounter,
ERASE_BLOCK_SIZE
);
#endif
//sectorCounter = sectorCounter & ~(ERASE_BLOCK_SIZE - 1);
i=ERASE_BLOCK_SIZE/WRITE_BLOCK_SIZE;
j=0;
#if defined(__18CXX)
p = file_buffer;
#endif
while(i-->0)
{
//Write the new data
for(blockCounter = 0; blockCounter < WRITE_BLOCK_SIZE; blockCounter++)
{
//Write the data
#if defined(__18CXX)
TABLAT = *p++;
_asm tblwtpostinc _endasm
sectorCounter++;
#endif
#if defined(__C30__)
__builtin_tblwtl((int)FileAddress, *((WORD*)&file_buffer[sectorCounter]));
__builtin_tblwth((int)FileAddress, 0);
FileAddress += 2;
sectorCounter += 2;
blockCounter++;
#endif
#if defined(__C32__)
NVMWriteWord((DWORD*)KVA_TO_PA(FileAddress), *((DWORD*)&file_buffer[sectorCounter]));
FileAddress += 4;
sectorCounter += 4;
#endif
}
j++;
//write the row
#if defined(__18CXX)
// Start the write process: reposition tblptr back into memory block that we want to write to.
_asm tblrdpostdec _endasm
// Write flash memory, enable write control.
EECON1 = 0x84;
EECON2 = 0x55;
EECON2 = 0xaa;
EECON1bits.WR = 1;
Nop();
EECON1bits.WREN = 0;
TBLPTR++;
#endif
#if defined(__C30__)
NVMCON = INTERNAL_FLASH_PROGRAM_PAGE;
asm("DISI #16"); //Disable interrupts for next few instructions for unlock sequence
__builtin_write_NVM();
#endif
Nop();
Nop();
}
}
}
#if defined(__C30__)
#if defined(__PIC24FJ256DA210__) \
|| defined(__PIC24FJ128DA210__) \
|| defined(__PIC24FJ256DA206__) \
|| defined(__PIC24FJ128DA206__) \
|| defined(__PIC24FJ256DA110__) \
|| defined(__PIC24FJ128DA110__) \
|| defined(__PIC24FJ256DA106__) \
|| defined(__PIC24FJ128DA106__) \
|| defined(__PIC24FJ256GB210__)
DSRPAG = DSRPageSave;
#else
PSVPAG = PSVPageSave;
#endif
#endif
return TRUE;
#else
return TRUE;
#endif
} //end SectorWrite
#if !defined(INTERNAL_FLASH_WRITE_PROTECT)
void EraseBlock(ROM BYTE* dest)
{
#if defined(__18CXX)
TBLPTR = (unsigned short long)dest;
//Erase the current block
EECON1 = 0x94;
EECON2 = 0x55;
EECON2 = 0xaa;
EECON1bits.WR = 1;
EECON1bits.WREN = 0;
#endif
#if defined(__C30__)
NVMCON = INTERNAL_FLASH_ERASE; //Erase page on next WR
__builtin_tblwtl((int)dest, 0xFFFF);
asm("DISI #16"); //Disable interrupts for next few instructions for unlock sequence
__builtin_write_NVM();
FileAddress = dest;
NVMCON = INTERNAL_FLASH_PROGRAM_PAGE;
#endif
#if defined(__C32__)
FileAddress = dest;
NVMErasePage((BYTE *)KVA_TO_PA(dest));
#endif
}
#endif
/******************************************************************************
* Function: BYTE WriteProtectState(void)
*
* PreCondition: None
*
* Input: None
*
* Output: BYTE - Returns the status of the "write enabled" pin
*
* Side Effects: None
*
* Overview: Determines if the card is write-protected
*
* Note: None
*****************************************************************************/
BYTE MDD_IntFlash_WriteProtectState(void)
{
#if defined(INTERNAL_FLASH_WRITE_PROTECT)
return TRUE;
#else
return FALSE;
#endif
}
|