Tronixlabs Support Forum
Sign up Latest Topics
 
 
 


Reply
  Author   Comment  
Bill Legge

Junior Member
Registered:
Posts: 1
Reply with quote  #1 
I got these chips from Tronixlabs a few weeks ago and have some working C code to
possibly help you get started.  My code uses the Mikroeletronika C32 compiler and the
Microchip MCU PIC32Mx795F512L. Same code also works on the M25P80 flash memory
Code is tested and works:

////////////////////////////////////////////////////////////////////////////////
// Project:         WVL_Flash_Memory                                          
// File:            WVL_Flash_Memory.c                                        
// MCU:             32MX795F512L Microchip                                    
// Flash Memory:    25P80 8Mbit or W25Q64FV 64Mbit memory                     
// Power:           3.3V for MCU                                              
// Xtal:            Running at 80MHz                                          
// Compiler:        mikroC PRO for PIC32 version 4.0.0                        
// Programmer:      ICD3                                                      
// Author:          WVL                                                       
// Date:            March 2018                                                
////////////////////////////////////////////////////////////////////////////////
#include <built_in.h>                           // to extract address in 3 bytes from 4 byte long variable
////////////////////////////////////////////////////////////////////////////////
// SerialFlash Commands for 25P80 8Mbit and W25Q64FV 64Mbit                   
static const unsigned short _SERIAL_FLASH_CMD_RDID  = 0x9F;   // decimal 159   
static const unsigned short _SERIAL_FLASH_CMD_READ  = 0x03;   // decimal 3     
static const unsigned short _SERIAL_FLASH_CMD_WRITE = 0x02;  // decimal 2     
static const unsigned short _SERIAL_FLASH_CMD_WREN  = 0x06;  // decimal 6     
static const unsigned short _SERIAL_FLASH_CMD_RDSR  = 0x05;  // decimal 5     
static const unsigned short _SERIAL_FLASH_CMD_ERASE = 0xC7;  // decimal 199   
static const unsigned short _SERIAL_FLASH_CMD_EWSR  = 0x06;  // decimal 6     
static const unsigned short _SERIAL_FLASH_CMD_WRSR  = 0x01;  // decimal 1     
static const unsigned short _SERIAL_FLASH_CMD_SER   = 0xD8;   // decimal 216   
////////////////////////////////////////////////////////////////////////////////
// Serial flash chip select                                                   
sbit CS_Serial_Flash_bit_C3 at LATC3_bit;                                     
sbit CS_Serial_Flash_Direction_bit_C3 at TRISC3_bit;                          
////////////////////////////////////////////////////////////////////////////////
// Prototypes for serial flash copied from Mikro Fusion examples                                         
void SerialFlash_init_C3();                                                                              
void SerialFlash_WriteEnable_C3();                                                                       
unsigned char SerialFlash_IsWriteBusy_C3();                                                              
void SerialFlash_WriteByte_C3(unsigned char _data, unsigned long address);                               
void SerialFlash_WriteWord_C3(unsigned int _data, unsigned long address);                                
unsigned char SerialFlash_ReadID_C3(void);                                                               
unsigned char SerialFlash_ReadByte_C3(unsigned long address);                                            
unsigned int SerialFlash_ReadWord_C3(unsigned long address);                                             
unsigned char SerialFlash_WriteArray_C3(unsigned long address,unsigned char*pData, unsigned int nCount); 
void SerialFlash_ReadArray_C3(unsigned long address, unsigned char* pData, unsigned int nCount);         
void SerialFlash_ChipErase_C3(void);                                                                     
void SerialFlash_ResetWriteProtection_C3();                                                              
void SerialFlash_SectorErase_C3(unsigned long address);                                                  
void SerialFlash_Start_C3();                                                                             
///////////////////////////////////////////////////////////////////////////////
void main() {
    unsigned short          x = 0;
    unsigned short       read = 0;
    unsigned short    write = 123;       // test byte 0x7B
    unsigned long    test_address;       // test address 4 bytes or 32 bit
          test_address = 0x123456;      // initialise after declaration essential
    // Init MCU
    AD1PCFG = 0xFFC7;           // RB3, RB4, RB5 analog remainder digital
    JTAGEN_bit = 0;                // disable JTAG
    // Init ports and pins
    TRISA = 0xFF;
    TRISB = 0xFF;
    TRISC = 0;
    TRISD = 0;
    TRISE = 0;
    TRISF = 0;
    TRISG = 0;
    // Init serial flash using SPI2 and RC3 as chip select W25Q64FV
    // Uses SPI2 on SDO2/RG8 SDI2/RG7 SCK2/RG6 CS/RG9
    // Maximim clock is 13.3MHz = 80/6
    SerialFlash_Start_C3();
    SerialFlash_WriteEnable_C3();
    SerialFlash_ChipErase_C3();    // 15 seconds, all bytes set to 0xFF
    delay_ms(2000);
    while(1){
        // Read and write to W25Q64FV or 25P80
        SerialFlash_WriteByte_C3(write,test_address);
        read =  SerialFlash_ReadByte_C3(test_address);
        //
        // Insert your code here to display result of read and write
        //
        test_address++;
        write++;
        // Housekeeping
        delay_ms(1000);
     }
}
////////////////////////////////////////////////////////////////////////////////
// Function - SerialFlash_init()
void SerialFlash_init_C3(){
    CS_Serial_Flash_bit_C3 = 1;
    CS_Serial_Flash_Direction_bit_C3 = 0;
}
////////////////////////////////////////////////////////////////////////////////
// Function - SerialFlash_WriteEnable()
void SerialFlash_WriteEnable_C3(){
    CS_Serial_Flash_bit_C3 = 0;
    SPI2_Write(_SERIAL_FLASH_CMD_WREN);
    CS_Serial_Flash_bit_C3 = 1;
}
////////////////////////////////////////////////////////////////////////////////
// Initialize SPI bus and serial flash on SPI2                                
// Max speed is 80/6 = 13.3MHz                                                
// M25P80 memory only accepts two SPI formats:                                
//      _SPI_CLK_IDLE_HIGH,_SPI_ACTIVE_2_IDLE)                                
//      _SPI_CLK_IDLE_LOW, _SPI_IDLE_2_ACTIVE)                                
// However, RGB needs _SPI_CLK_IDLE_LOW, _SPI_IDLE_2_ACTIVE only              
// Uses SPI2 on SDO2/RG8 SDI2/RG7 SCK2/RG6 CS/RG9                             
void SerialFlash_Start_C3() {                                                 
    SPI2_Init_Advanced(_SPI_MASTER,_SPI_8_BIT,1024,_SPI_SS_DISABLE,\
    _SPI_DATA_SAMPLE_MIDDLE,_SPI_CLK_IDLE_LOW,_SPI_IDLE_2_ACTIVE);            
    Delay_ms(100);                                                            
    SerialFlash_init_C3();              // CS bit set as output and disabled       
    SerialFlash_WriteEnable_C3();  // CS cycled and WREN sent to chip         
    Delay_ms(10);                                                             
}                                                                             
////////////////////////////////////////////////////////////////////////////////
// Function - SerialFlash_IsWriteBusy()
unsigned char SerialFlash_IsWriteBusy_C3(){
    unsigned char temp;
    CS_Serial_Flash_bit_C3 = 0;
    SPI2_Write(_SERIAL_FLASH_CMD_RDSR);
    temp = SPI2_Read(0);
    CS_Serial_Flash_bit_C3 = 1;
    return (temp&0x01);
}
////////////////////////////////////////////////////////////////////////////////
// Function - SerialFlash_WriteByte() Function that writes a single byte
// Input: Data to be written and the address to which to store the data
void SerialFlash_WriteByte_C3(unsigned char _data, unsigned long address){
    SerialFlash_WriteEnable_C3();
    CS_Serial_Flash_bit_C3 = 0;
    SPI2_Write(_SERIAL_FLASH_CMD_WRITE);
    SPI2_Write(Higher(address));
    SPI2_Write(Hi(address));
    SPI2_Write(Lo(address));
    SPI2_Write(_data);
    CS_Serial_Flash_bit_C3 = 1;
    // Wait for write end
    while(SerialFlash_isWriteBusy_C3());
}
////////////////////////////////////////////////////////////////////////////////
// Function -SerialFlash_WriteWord()writes 2 succesive bytes of word variable
// Input: Word data to be written and the address to which to store the data
void SerialFlash_WriteWord_C3(unsigned int _data, unsigned long address){
  SerialFlash_WriteByte_C3(Hi(_data),address);
  SerialFlash_WriteByte_C3(Lo(_data),address+1);
}
////////////////////////////////////////////////////////////////////////////////
// Function SerialFlash_ReadID() reads the CHIP ID
// Input: none Output: ID byte value
unsigned char SerialFlash_ReadID_C3(void){
  unsigned char temp;
  CS_Serial_Flash_bit_C3 = 0;
  SPI2_Write(_SERIAL_FLASH_CMD_RDID);
  temp = SPI2_Read(0);
  CS_Serial_Flash_bit_C3 = 1;
  return temp;
}
////////////////////////////////////////////////////////////////////////////////
// Function - SerialFlash_ReadByte() reads the byte from the address
// Input: address to be read. Output: byte data from the address
unsigned char SerialFlash_ReadByte_C3(unsigned long address){
  unsigned char temp;
  CS_Serial_Flash_bit_C3 = 0;
  SPI2_Write(_SERIAL_FLASH_CMD_READ);
  SPI2_Write(Higher(address));
  SPI2_Write(Hi(address));
  SPI2_Write(Lo(address));
  temp = SPI2_Read(0);
  CS_Serial_Flash_bit_C3 = 1;
  return temp;
}
////////////////////////////////////////////////////////////////////////////////
// Function - SerialFlash_ReadWord()reads the word from the address
// Input: read address. Output: word data stored in two successive addresses
unsigned int SerialFlash_ReadWord_C3(unsigned long address){
  unsigned int temp;
  Hi(temp) = SerialFlash_ReadByte_C3(address);
  Lo(temp) = SerialFlash_ReadByte_C3(address+1);
  return temp;
}
////////////////////////////////////////////////////////////////////////////////
// Function - SerialFlash_WriteArray() writes data to successive addresses
// Input: address of the begining, pointer to buffer containing data
// and number of bytes to be written
// Output: 1 - if write succeeded, 0 - if write failed
unsigned char SerialFlash_WriteArray_C3(unsigned long address, unsigned char* pData, unsigned int nCount){
  unsigned long addr;
  unsigned char* pD;
  unsigned int counter;
  addr = address;
  pD   = pData;
  // WRITE
  for(counter = 0; counter < nCount; counter++){
      SerialFlash_WriteByte_C3(*pD++, addr++);
  }
  // VERIFY
  for (counter=0; counter < nCount; counter++){
    if (*pData != SerialFlash_ReadByte_C3(address))
        return 0;
    pData++;
    address++;
  }
  return 1;
}
////////////////////////////////////////////////////////////////////////////////
// Function SerialFlash_ReadArray() reads data from successive addresses
// Input: address of the begining, pointer to buffer where to store read data,
// and number of bytes to be read. Output: none
void SerialFlash_ReadArray_C3(unsigned long address, unsigned char* pData, unsigned int nCount){
  CS_Serial_Flash_bit_C3 = 0;
  SPI2_Write(_SERIAL_FLASH_CMD_READ);
  SPI2_Write(Higher(address));
  SPI2_Write(Hi(address));
  SPI2_Write(Lo(address));
  while(nCount--){
    *pData++ = SPI2_Read(0);
  }
  CS_Serial_Flash_bit_C3 = 1;
}
////////////////////////////////////////////////////////////////////////////////
// Function - SerialFlash_ChipErase() sends Chip Erase command
void SerialFlash_ChipErase_C3(void){
  SerialFlash_WriteEnable_C3();
  CS_Serial_Flash_bit_C3 = 0;
  SPI2_Write(_SERIAL_FLASH_CMD_ERASE);
  CS_Serial_Flash_bit_C3 = 1;
  // Wait for write end
  while(SerialFlash_IsWriteBusy_C3());
}
////////////////////////////////////////////////////////////////////////////////
// Function - SerialFlash_ResetWriteProtection()sends Reset Write Protection command
void SerialFlash_ResetWriteProtection_C3(){
  CS_Serial_Flash_bit_C3 = 0;
  SPI2_Write(_SERIAL_FLASH_CMD_EWSR);
  CS_Serial_Flash_bit_C3 = 1;
  CS_Serial_Flash_bit_C3 = 0;
  SPI2_Write(_SERIAL_FLASH_CMD_EWSR);
  SPI2_Write(0);
  CS_Serial_Flash_bit_C3 = 1;
}
////////////////////////////////////////////////////////////////////////////////
// Function SerialFlash_SectorErase() sends Sector Erase command
// Input: address of the sector to be erased. Output: none
void SerialFlash_SectorErase_C3(unsigned long address){
  SerialFlash_WriteEnable_C3();
  CS_Serial_Flash_bit_C3 = 0;
  SPI2_Write(_SERIAL_FLASH_CMD_SER);
  SPI2_Write(Higher(address));
  SPI2_Write(Hi(address));
  SPI2_Write(Lo(address));
  CS_Serial_Flash_bit_C3 = 1;
  // Wait for write end
  while(SerialFlash_IsWriteBusy_C3());
}

Good luck - Regards Bill Legge
Previous Topic | Next Topic
Print
Reply

Quick Navigation:

Easily create a Forum Website with Website Toolbox.