|
|
View previous topic :: View next topic |
Author |
Message |
tomay3000
Joined: 11 Jul 2010 Posts: 3
|
PIC16F628A : Just take a look |
Posted: Sun Jul 11, 2010 7:24 pm |
|
|
I made an RS232 Serial External SPI FLASH Programmer for Winbond EEPROMs series. & the only function that works great is just reading
So can anyone help me to solve my problems
This is my PIC16F628A driver code for Winbond W25Xxx W25Xxx.C:
Code: | ///////////////////////////////////////////////////////////////////////////
//// Library for a Winbond W25Xxx (128 KB --> 16 MB) ////
//// ////
//// init_ext_eeprom(); Call before the other functions are used ////
//// ////
//// write_ext_eeprom(a, d); Write the byte d to the address a ////
//// ////
//// d = read_ext_eeprom(a); Read the byte d from the address a ////
//// ////
//// b = ext_eeprom_ready(); Returns TRUE if the eeprom is ready ////
//// to receive opcodes ////
//// ////
//// The main program may define EEPROM_SELECT, EEPROM_DI, EEPROM_DO ////
//// and EEPROM_CLK to override the defaults below. ////
//// ////
//// ////
//// Pin Layout ////
//// ----------------------------------------------- ////
//// | __ | ////
//// | 1: CS EEPROM_SELECT | 8: VCC +5V | ////
//// | | ____ | ////
//// | 2: DO EEPROM_DO | 7: HOLD +5V | ////
//// | __ | | ////
//// | 3: WP +5V | 6: CLK EEPROM_CLK | ////
//// | | | ////
//// | 4: GND Ground | 5: DIO EEPROM_DI | ////
//// ----------------------------------------------- ////
//// ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996, 2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
#ifndef EEPROM_SELECT
#define EEPROM_SELECT PIN_A0
#define EEPROM_CLK PIN_A1
#define EEPROM_DI PIN_A2
#define EEPROM_DO PIN_A2
#endif
#define EEPROM_ADDRESS int32
void init_ext_eeprom()
{
output_high(EEPROM_SELECT);
output_low(EEPROM_DI);
output_low(EEPROM_CLK);
}
BOOLEAN ext_eeprom_ready()
{
BYTE rdsr, i, data;
rdsr = 0x05; // rdsr opcode
output_low(EEPROM_SELECT);
for(i=0; i<8; ++i)
{
output_bit(EEPROM_DI, shift_left(&rdsr, 1, 0));
output_high(EEPROM_CLK); // data latches
output_low(EEPROM_CLK); // back to idle
}
for(i=0; i<8; ++i)
{
output_high(EEPROM_CLK);
shift_left(&data, 1, input(EEPROM_DO));
output_low(EEPROM_CLK); // data latches & back to idle
}
output_high(EEPROM_SELECT);
return !bit_test(data, 0);
}
void erase_ext_eeprom()
{
BYTE i, wren, erase;
wren = 0x06; // wren opcode
erase = 0xc7; // chip erase
// Wait until the eeprom is done with a previous write
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
for(i=0; i<8; ++i)
{
output_bit(EEPROM_DI, shift_left(&wren, 1, 0));
output_high(EEPROM_CLK); // data latches
output_low(EEPROM_CLK); // back to idle
}
output_high(EEPROM_SELECT);
output_low(EEPROM_SELECT);
for(i=0; i<8; ++i)
{
output_bit(EEPROM_DI, shift_left(&erase, 1, 0));
output_high(EEPROM_CLK); // data latches
output_low(EEPROM_CLK); // back to idle
}
output_high(EEPROM_SELECT);
delay_ms(40000); // tCE
}
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data)
{
BYTE cmd[5], i, wren;
wren = 0x06; // wren opcode
cmd[0] = data;
cmd[1] = (BYTE) address;
cmd[2] = (BYTE) (address >> 8);
cmd[3] = (BYTE) (address >> 16);
cmd[4] = 0x02;
// Wait until the eeprom is done with a previous write
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
for(i=0; i<8; ++i)
{
output_bit(EEPROM_DI, shift_left(&wren, 1, 0));
output_high(EEPROM_CLK); // data latches
output_low(EEPROM_CLK); // back to idle
}
output_high(EEPROM_SELECT);
output_low(EEPROM_SELECT);
for(i=0; i<40; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd, 5, 0));
output_high(EEPROM_CLK); // data latches
output_low(EEPROM_CLK); // back to idle
}
output_high(EEPROM_SELECT);
delay_ms(3); // tPP
}
BYTE read_ext_eeprom(EEPROM_ADDRESS address)
{
BYTE cmd[4], i, data;
cmd[0] = (BYTE) address;
cmd[1] = (BYTE) (address >> 8);
cmd[2] = (BYTE) (address >> 16);
cmd[3] = 0x03;
// Wait until the eeprom is done with a previous write
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
for(i=0; i<32; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd, 4, 0));
output_high(EEPROM_CLK); // data latches
output_low(EEPROM_CLK); // back to idle
}
for(i=0; i<8; ++i)
{
output_high(EEPROM_CLK);
shift_left(&data, 1, input(EEPROM_DO));
output_low(EEPROM_CLK); // data latches & back to idle
}
output_high(EEPROM_SELECT);
return(data);
} |
and Winbond W25Xxx SPI Flash Programmer.h file:
Code: | #include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=20000000)
#use rs232(baud=115200,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8) |
and the main program is Winbond W25Xxx SPI Flash Programmer.c:
Code: | #include "Winbond W25Xxx SPI Flash Programmer.h"
#include "W25Xxx.C"
#include <stdio.h>
BYTE cmd[5], co = 0, data = 'X';
int32 address;
#int_TBE
void TBE_isr(void)
{
disable_interrupts(INT_TBE);
switch(cmd[0])
{
case 'E':
putc('S');
break;
case 'W':
putc('S');
break;
case 'R':
putc(data);
break;
}
enable_interrupts(INT_RDA);
}
#int_RDA
void RDA_isr(void)
{
cmd[co ++] = getc();
if(co == 5)
{
disable_interrupts(INT_RDA);
co = 0;
address = ((int32) cmd[1]) << 16;
address |= ((int32) cmd[2]) << 8;
address |= (int32) cmd[3];
switch(cmd[0])
{
case 'E':
erase_ext_eeprom();
break;
case 'W':
write_ext_eeprom(address, cmd[4]);
break;
case 'R':
data = read_ext_eeprom(address);
break;
}
enable_interrupts(INT_TBE);
}
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
init_ext_eeprom();
disable_interrupts(INT_TBE);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
//TODO: User Code
while(TRUE);
} |
So where could the problem be
Thank you any way ;) _________________ PIC16F628A |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 11, 2010 11:43 pm |
|
|
Post the full part number of the eeprom that you're testing, and post a
link to the eeprom data sheet, and post your compiler version.
I suggest simplifying the program. Get rid of the #int_rda and #int_tbe
routines until you get the eeprom working reliably.
Also, your posted code looks like it's a CCS driver, but I don't find any
such driver in the CCS directories. I don't find it if I search the net with
Google. So I could be wrong, but I think you've created an invention
and tacked the CCS copyright message on it. |
|
|
tomay3000
Joined: 11 Jul 2010 Posts: 3
|
|
Posted: Mon Jul 12, 2010 8:26 am |
|
|
PCM programmer wrote: | Post the full part number of the eeprom that you're testing, and post a
link to the eeprom data sheet, and post your compiler version.
I suggest simplifying the program. Get rid of the #int_rda and #int_tbe
routines until you get the eeprom working reliably.
Also, your posted code looks like it's a CCS driver, but I don't find any
such driver in the CCS directories. I don't find it if I search the net with
Google. So I could be wrong, but I think you've created an invention
and tacked the CCS copyright message on it. |
Sorry for my previous post
& for the full part number of my SPI EEPROM is : W25X40A
& a link to its datasheet is : http://www.winbond.com.tw/NR/rdonlyres/93A5FE5A-EEF2-417B-87A8-CB8144F6120D/0/W25X10A_W25X20A_W25X40A_W25X80A.pdf
& my compiler version is : 4.106
& for the W25Xxx.C driver, I crated it using the athor drivers samples.
& I did this test program test.h:
Code: | #include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=20000000)
#use rs232(baud=115200,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8) |
& the test.c main program is :
Code: | #include "test.h"
#include <stdio.h>
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
//TODO: User Code
while(TRUE)
putc(getc());
} |
& I always receive what I sent to the PIC. So it is working
This is an image of my EEPROM Programmer :
http://www.wuala.com/tomay3000/Documents/Electronics/EEPROM%20Programmer.JPG
& the JDM Programmer for the PIC :
http://www.wuala.com/tomay3000/Documents/Electronics/JDM%20Programmer.JPG _________________ PIC16F628A
Last edited by tomay3000 on Sat Jul 17, 2010 10:23 am; edited 1 time in total |
|
|
tomay3000
Joined: 11 Jul 2010 Posts: 3
|
|
Posted: Wed Jul 14, 2010 11:09 am |
|
|
Finally, I found the solution. The problem was in the VCC voltage, so the Winbond SpiFlash supports a range of (2.7 --> 3.6) volts, not 5 volts, so I found that my Winbond W25Xxx SpiFlash is gone with a 5 volts & my PIC16F628A is working great. _________________ PIC16F628A |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|