M25P128 module almost done

Coding and general discussion relating to user created compiler modules

Moderators: David Barker, Jerry Messina

Post Reply
User avatar
ohararp
Posts: 194
Joined: Tue Oct 03, 2006 11:29 pm
Location: Dayton, OH USA
Contact:

M25P128 module almost done

Post by ohararp » Fri Jan 16, 2009 9:08 pm

Hey all, I have my module nearly complete. However, I want to have the user declare the pin lines (CS,CLK,SDO,SDI) in a fashion similar to how Steven allows the #option to be used for his SD library. These pin values get passed to the "Shift.bas" command for later use when talking to the chip. Does anybody think they can take a look at the code and see how I can better pass these values?

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  
Thanks Ryan
$25 SMT Stencils!!!
www.ohararp.com/Stencils.html

Post Reply