Code: Select all
{
*****************************************************************************
* Name () UNTITLED.BAS
* Author () [select VIEW...EDITOR OPTIONS]
* Notice () Copyright (c) 2009 [select VIEW...EDITOR OPTIONS]
* () All Rights Reserved
* Date () 1/9/2009
* Version () 1.0
* Notes ()
* ()
*****************************************************************************
}
Module M25P128
// OPTIONS
#option SHIFT_MAX = 8
// IMPORT MODULES
Include "SHIFT.BAS"
// DEFAULT MODULE OPTIONS - USER OPTIONS CAN OVERRIDE THESE VALUES...
#option M25P_CS = PORTC.2 // use 5k to 10k ohms pull-up resistor
#option M25P_CLK = PORTC.3 // use 5k to 10k ohms pull-down resistor
#option M25P_DI = PORTC.5 //
#option M25P_DO = PORTC.4 //
// Validate CS pin...
#if IsOption(M25P_CS) And Not IsValidPortPin(M25P_CS)
#error M25P_CS, "Invalid option. CS must be a valid port pin."
#endif
// Validate DI pin...
#if IsOption(M25P_DI) And Not IsValidPortPin(M25P_DI)
#error M25P_DI, "Invalid option. DI must be a valid port pin."
#endif
// Validate CLK pin...
#if IsOption(M25P_CLK) And Not IsValidPortPin(M25P_CLK)
#error M25P_CLK, "Invalid option. CLK must be a valid port pin."
#endif
// Validate DO pin...
#if IsOption(M25P_DO) And Not IsValidPortPin(M25P_DO)
#error M25P_DO, "Invalid option. DO must be a valid port pin."
#endif
// ======= M25P128 Instructions ==================================
Const
M25P_WREN = $06, ' Write M25PEnable
M25P_WRDI = $04, ' Write M25PDisable
M25P_RDID = $9F, ' Read Identification
M25P_RDSR = $05, ' Read STATUS Register
M25P_WRSR = $01, ' Write STATUS Register
M25P_Read = $03, ' Read Data Bytes
M25P_Read_Fast = $0B, ' Read Data Bytes At Higher Speed
M25P_PP = $02, ' PAGE Program
M25P_SE = $D8, ' Sector Erase
M25P_BE = $C7, ' Bulk Erase
M25P_Dummy = $FF ' Dummy Byte for Fast Read
// Variables used with commands to the M25P128
Dim M25PStatus As Byte
Dim M25PIndex As Byte ' Index Counter
Dim SRWD As M25PStatus.7 ' Status Register Write M25PDisable
Dim BP2 As M25PStatus.4 ' The Block Protect (BP2, BP1, BP0) bits
Dim BP1 As M25PStatus.3
Dim BP0 As M25PStatus.2
Dim WEL As M25PStatus.1 ' The Write M25PEnable Latch
Dim WIP As M25PStatus.0 ' The Write In Progress
{
****************************************************************************
* Name : Disable(PRIVATE)
* Purpose : Disable the M25P128
****************************************************************************
}
Sub M25PDisable()
High(M25P_CS) ' M25PDisable the chip again
End Sub
{
****************************************************************************
* Name : Enable(PRIVATE)
* Purpose : Enable the M25P128
****************************************************************************
}
Sub M25PEnable()
Low(M25P_CS) ' M25PEnable the chip
End Sub
{
****************************************************************************
* Name : Write(PRIVATE)
* Purpose : Write M25PEnable the M25P128
****************************************************************************
}
Sub WriteEnable()
M25PEnable() ' M25PEnable the chip
Shift.Out(MSB_FIRST,M25P_WREN,8) ' Send the WREN command
M25PDisable() ' M25PDisable the chip again
End Sub ' All done return
{
****************************************************************************
* Name : WriteDisble(PRIVATE)
* Purpose : Write M25PDisable the M25P128
****************************************************************************
}
Sub WriteM25PDisable()
M25PEnable() ' M25PEnable the chip
Shift.Out(MSB_FIRST,M25P_WRDI,8) ' Send the WRDI command
M25PDisable() ' M25PDisable the chip again
End Sub
{
****************************************************************************
* Name : ReadID
* Purpose : Read the 24 Bit Id of the M25P128
****************************************************************************
}
Public Function ReadId() As LongWord
M25PEnable() ' M25PEnable the chip
Shift.Out(MSB_FIRST,M25P_RDID,8) ' Send the RDID command
ReadId.BYTE0 = Shift.In(MSB_POST,8) ' readin the 24 bit ID data
ReadId.BYTE1 = Shift.In(MSB_POST,8)
ReadId.BYTE2 = Shift.In(MSB_POST,8) ' M25PDisable the chip again
M25PDisable()
End Function
{
****************************************************************************
* Name : ReadStatus(PRIVATE)
* Purpose : Read the Read Status Register of the the M25P128
****************************************************************************
}
Sub ReadStatus()
M25PEnable() ' M25PEnable the chip
Shift.Out(MSB_FIRST,M25P_RDSR,8) ' Send the RDSR command
M25PStatus = Shift.In(MSB_POST,8)
End Sub
{
****************************************************************************
* Name : ReReadStatus(PRIVATE)
* Purpose : ReRead the Read Status Register of the the M25P128
****************************************************************************
}
Sub ReReadStatus()
M25PStatus = Shift.In(MSB_POST,8)
End Sub
{
****************************************************************************
* Name : BulkErase
* Purpose : Erase the Entire M25P128 DATA - TAKES AWHILE TO OPERATE
****************************************************************************
}
Public Sub BulkErase()
ReadStatus() ' Check its Not in the middle of a current Write
While WIP = 1
ReReadStatus()
Wend
M25PDisable() ' M25PDisable To ensure the Read STATUS is stopped
DelayUS(4)
M25PEnable() ' M25PEnable the chip again
WriteEnable()
M25PEnable() ' M25PEnable the chip
Shift.Out(MSB_FIRST,M25P_BE,8) ' Sent the Bulk erase instruction
M25PDisable() ' M25PDisable the chip To start the erase
End Sub
{
****************************************************************************
* Name : SectorErase
* Purpose : Erase the One Sector of the M25P128 DATA
****************************************************************************
}
Public Sub SectorErase(pM25PDataAddress As LongWord)
ReadStatus() ' Check its not in the middle of a current write
While WIP = 1
ReReadStatus()
Wend
M25PDisable() ' M25PDisable to ensure the read status is stopped
DelayUS(4)
M25PEnable() ' M25PEnable the chip again
WriteEnable()
M25PEnable() ' M25PEnable the chip
Shift.Out(MSB_FIRST,M25P_SE,8) ' Sent the Sector erase instruction
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE2,8) ' Send the address
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE1,8) ' The whole sector that the address is in will be
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE0,8) ' Erased
M25PDisable() ' M25PDisable the chip to start the erase
End Sub
{
****************************************************************************
* Name : WriteStatus
* Purpose : Make areas of the M25P128 Data read only
****************************************************************************
}
Sub WriteStatus(pM25PWriteByte As Byte)
WriteEnable()
M25PEnable() ' M25PEnable the chip
Shift.Out(MSB_FIRST,pM25PWriteByte,8)
M25PDisable() ' M25PDisable the chip again
End Sub
{
****************************************************************************
* Name : WriteByte
* Purpose : Write a single byte and the specified address
****************************************************************************
}
Sub WriteByte(pM25PDataAddress As LongWord,pM25PWriteByte As Byte)
ReadStatus() ' Check its not in the middle of a current write
While WIP = 1
ReReadStatus()
Wend
M25PDisable() ' M25PDisable to ensure the read status is stopped
DelayUS(4)
M25PEnable() ' M25PEnable the chip again
WriteEnable() ' Write M25PEnable the device
M25PEnable() ' M25PEnable the device
Shift.Out(MSB_FIRST,M25P_PP,8) ' Sent the Page Write instruction
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE2,8) ' Send the address
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE1,8)
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE0,8)
Shift.Out(MSB_FIRST,pM25PWriteByte,8) ' Finaly the data
M25PDisable() ' Finish the write by bringing the CS line high
End Sub
{
****************************************************************************
* Name : WriteBytes
* Purpose : Write up to 255 bytes from the specified address
* CAUTION : OVERLAPPING A PAGE BOUNDARY CAN CAUSE SERIOUS ERRORS
****************************************************************************
}
Sub WriteBytes(pM25PDataAddress As LongWord,ByRef pM25PDataOut() As Byte)
ReadStatus() ' Check its not in the middle of a current write
While WIP = 1
ReReadStatus()
Wend
M25PDisable() ' M25PDisable to ensure the read status is stopped
DelayUS(4)
M25PEnable() ' M25PEnable the chip again
WriteEnable() ' Write M25PEnable the device
M25PEnable() ' M25PEnable the device
Shift.Out(MSB_FIRST,M25P_PP,8) ' Sent the Page Write instruction
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE2,8) ' Send the address
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE1,8)
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE0,8)
For M25PIndex = 0 To Bound(pM25PDataOut) ' Via FRS0 send all the data requested
Shift.Out(MSB_FIRST,pM25PDataOut(M25PIndex),8)
Next
M25PDisable() ' Finish the write by bringing the CS line high
End Sub
{
****************************************************************************
* Name : ReadByte
* Purpose : Read a single byte at the specified address
****************************************************************************
}
Function ReadByte(pM25PDataAddress As LongWord) As Byte
ReadStatus() ' Check its not in the middle of a current write
While WIP = 1
ReReadStatus()
Wend
M25PDisable() ' M25PDisable to ensure the read status is stopped
DelayUS(4)
M25PEnable() ' M25PEnable the chip again
Shift.Out(MSB_FIRST,M25P_Read,8) ' Sent the data read instruction
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE2,8) ' Send the address
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE1,8)
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE0,8)
ReadByte = Shift.In(MSB_POST,8) ' Read the byte in
M25PDisable()
End Function
{
****************************************************************************
* Name : ReadBytes
* Purpose : Read a multiple bytes byte at the specified address
****************************************************************************
}
Function ReadBytes(pM25PDataAddress As LongWord,ByRef pM25PDataIn() As Byte,pBytesToRead As LongWord) As Byte
If pBytesToRead > Bound(pM25PDataIn()) Then 'Check to make sure you do not overfill the array
pBytesToRead = Bound(pM25PDataIn())
EndIf
ReadStatus() ' Check its not in the middle of a current write
While WIP = 1
ReReadStatus()
Wend
M25PDisable() ' M25PDisable to ensure the read status is stopped
DelayUS(4)
M25PEnable() ' M25PEnable the chip again
Shift.Out(MSB_FIRST,M25P_Read_Fast,8) ' Sent the data read instruction
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE2,8) ' Send the address
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE1,8)
Shift.Out(MSB_FIRST,pM25PDataAddress.BYTE0,8)
Shift.Out(MSB_FIRST,M25P_Dummy,8)
For M25PIndex = 0 To pBytesToRead - 1
pM25PDataIn(M25PIndex) = Shift.In(MSB_POST,8)
Next
M25PDisable()
End Function
{
****************************************************************************
* Name : Init
* Purpose : Setup the Port Pins
****************************************************************************
}
Sub M25PInit()
Output(M25P_CS)
Shift.SetClock(M25P_CLK,TRUE) //initialise shiftOUT clock pin, IDLE HIGH
Shift.SetInput(M25P_SDI)
Shift.SetOutput(M25P_SDO) //initialise shiftOUT pin
End Sub