|
|
View previous topic :: View next topic |
Author |
Message |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
at45db021.c problem |
Posted: Tue Jun 03, 2014 1:05 pm |
|
|
Hello
I am using 18F67j60 and AT45DB011D.
with a few modifications I made driver work. The problem appears at reading page function: Quote: | ext_flash_readPage() | which contains Quote: | ext_flash_waitUntilReady() | in which the uC waits high level state on MISO representing device ready signal. So my program hangs out waiting for never coming high level bit.
This way doesn't work:
Code: | while(True){
ext_flash_writePageThroughBuffer(0, def_buff,0 ,data, sizeof(data));
ext_flash_readPage(0, 0, rec_arr, 264); //Hangs out here
print_array(rec_arr, sizeof(rec_arr));
wait_butt();
} |
When I put delay between the two functions then I got what I want.
This way it works:
Code: | while(True){
ext_flash_writePageThroughBuffer(0, def_buff,0 ,data, sizeof(data));
delay_ms(10); //This fixes the problem
ext_flash_readPage(0, 0, rec_arr, 264); //Hangs out here
print_array(rec_arr, sizeof(rec_arr));
wait_butt();
} |
What eats me inside is why bit7 of Status Register doesn't go high, while this Code: | while(!input(FLASH_DO))
; | is awaiting? _________________ A person who never made a mistake never tried anything new. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Tue Jun 03, 2014 2:51 pm |
|
|
hmmm...
while(!input(FLASH_DO))
Looks like _DO is letter 'D', letter 'O'....
...should it really be number '0' ????
Sometimes zeros and ohs look very,very similar to me.
I don't have the driver handy to confirm/deny what it should be.
but if wrong that would cause it to hang.
just thinking out loud....
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 03, 2014 4:40 pm |
|
|
What if you modify the ext_flash_waitUntilReady() routine to read the
status in a more formal way ? i.e., call a routine to read the whole status
byte, test the busy bit, and wait in a loop until the device is ready.
Try this and see if it helps:
Code: |
#define DEVICE_READY_MASK 0x80
void ext_flash_waitUntilReady()
{
// Add the following new code:
int8 status;
while(1)
{
status = ext_flash_readStatus(); // Read status byte
if(status & DEVICE_READY_MASK) // Is Ready bit == 1 ?
break; // Exit loop if so
}
// Comment out the existing CCS driver code for this routine:
// output_low(FLASH_SELECT); // Enable select line
// ext_flash_sendData(0xD7, 8); // Send status command
// while(!input(FLASH_DO)); // Wait until ready
// output_high(FLASH_SELECT); // Disable select line
} |
I don't have any busy timeout code in there. Ideally, the routine should
return TRUE if the device goes ready within a timeout period, and if not,
it should return FALSE. But that would require modifying more of the
driver code and it's not necessary for this test. |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Wed Jun 04, 2014 1:47 am |
|
|
Thank you both guys and, Sorry, I should have thought about that.
temtronic here is the driver:
https://drive.google.com/file/d/0B_EYtdS7J5eKaWhuTkZhLTJHdEU/edit?usp=sharing
FLASH_DO is a Macros to SDI of the uC.
This is my pin definition before I call the driver.
Code: | #define FLASH_SELECT PIN_F7
#define FLASH_CLOCK PIN_C3
#define FLASH_DI PIN_C5
#define FLASH_DO PIN_C4 |
It actually specifies the hardware SPI.
PCM programmer
Quote: | call a routine to read the whole status
byte, test the busy bit, and wait in a loop until the device is ready |
I think that is a good idea, and I am going to try it. BUT, this is from the datasheet:
Quote: | The user can continuously poll bit 7 of the status register by stopping SCK at a low level
once bit 7 has been output. The status of bit 7 will continue to be output on the SO pin, and
once the device is no longer busy, the state of SO will change from 0 to 1 |
Thats why I think it might be my/driver's fault.
If I comment out whats inside the ext_flash_waitUntilReady() I get only 0xFF for the entire page, since the device is not ready, but once the device is ready I can read the actual data again. So the device i indeed busy about 10ms after the user writes inside the main memory. _________________ A person who never made a mistake never tried anything new. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Jun 04, 2014 4:15 am |
|
|
This driver uses bit-banging in firmware - it has to to implement this clock-hold-while-waiting-for-ready thing. It cannot use the hardware SPI. Even if you have specified the hardware SPI pins, this driver will not use the hardware SPI. The datasheet shows there are different ways of doing it - the status byte is apparently re-sent if you just keep on clocking, allowing hardware SPI to be used to re-read the ready bit, and you can explicity re-send the whole command and response.
The clock hold thing is great if you want to squeeze the absolute best speed out of the thing, which implies running at the full 66MHz SPI clock rate which no PIC is going to get close to. but if you don't then its a complication you don't need.
Anyway, if you want to use this driver you must make sure nothing else is using the SPI hardware, otherwise things are going to get confused. It should be possible, fairly simple really, to write a modified driver that uses the hardware (or software) SPI routines supplied by CCS and therefore make it compatible with code that uses other SPI devices. |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Wed Jun 04, 2014 5:01 am |
|
|
Quote: | It cannot use the hardware SPI |
Who says I am using hardware SPI?
The reason I specified these pins is that my dev board is made up that way.
I will not re-rout the PCB simply because this driver isnt working.
So for better clarity I will post my entire code.
RF_Developer Thank you for the reply.
And yet why is this bit-banging not working. I'm staring at the code and driver and I cant still figure out why it isnt go out of this Code: | while(!input(FLASH_DO)); |
The thing is that I can make this code work. I have already done it before I wrote to you.
I know my English is not good, and yet I think you understand my question.
My question (again) is not how to work around it, but why this part of the driver (waiting for high level bit7 of status register) isnt working.
The Worst is I do think that there is no reason for this driver to not work along with my hardware. Obviously I miss something. I still think it should work the way it is.
Here is the code:
https://drive.google.com/file/d/0B_EYtdS7J5eKR0szc3JhSnZvOHc/edit?usp=sharing
Thank you again for help! _________________ A person who never made a mistake never tried anything new. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Jun 04, 2014 5:16 am |
|
|
when stuck like this ....try a simpler program !
Delete 99% of your code, and just have main() test that pin and set/rst an LED based on the input.Code will be 10-12 lines long.Dump the listing to confirm the machine code is correct! Might even be a compiler version bug?
You could have a PCB problem(whiskers, bad etch,open trace) and no amount of staring at good code will see that. Ring out the traces, confirm the button does work.
It's back to troubleshooting101. Start with the basics,confirm the hardware is correct, test and retest.
Also, are there ANY other peripherals 'attached' to that pin? Is it an output only pin? I don't use that PIC but sometimes Compiler 'defaults' aren't what YOU want!
hth
jay |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Jun 04, 2014 5:45 am |
|
|
rikotech8 wrote: | Quote: | It cannot use the hardware SPI |
Who says I am using hardware SPI? |
I didn't say you were, but you could be trying to because of this:
Quote: |
It actually specifies the hardware SPI.
|
and because you haven't posted complete compilable code, so we cannot be sure of what other stuff might be causing problems.
Quote: | So for better clarity I will post my entire code. |
Yes, that's a good idea, and may help. But we cant do much with ALL of your code. We need the simplest, yet still complete and compilable, code that shows the problem. Back in the day, you had to include a complete, as simple as possible but complete code, or complete code fragment, such as a subroutine, with any bug report to compiler suppliers otherwise they didn't take any notice of the report at all. If they could not take the code and quickly replicate your (faulty) results, they would do nothing. Things have moved on, but we are still guessing when all we get is a few lines out of context with often no clear statement of what's wrong.
It might turn out that as you simplify your code, suddenly it starts working. That will help you, and us to understand where the problem is.
Quote: | The Worst is I do think that there is no reason for this driver to not work along with my hardware. Obviously I miss something. I still think it should work the way it is. |
Yes, it should work as it is. Its simple, and doesn't rely on much hardware - it doesn't need the hardware SPI on the PIC for example. So maybe something else is messing it up. Something not in the code you've shown us so far maybe. |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Wed Jun 04, 2014 8:57 am |
|
|
This is the entire code. If simpler wont be complete.
Code: | #include <18F67J60.h>
#use delay(clock=41666667)
#fuses NOWDT, H4_SW, NOIESO, NOFCMEN, PRIMARY, ETHLED
#use rs232(baud=9600, uart1, errors)
#USE FAST_IO (C)
#define FLASH_SELECT PIN_F7
#define FLASH_CLOCK PIN_C3
#define FLASH_DI PIN_C5
#define FLASH_DO PIN_C4
#define LED PIN_B4
#define BUTT_PRESSED !INPUT(PIN_B3)
#define LED_ON OUTPUT_LOW(LED)
#define LED_OFF OUTPUT_HIGH(LED)
#define LED_TOGG OUTPUT_TOGGLE(LED)
#define DEF_BUFF 0
#define TRIS_C_SET 0x90 //4,7 as inputs and 0,1,2,3,5,6 as outputs
#include "at45db021.c"
void user_init(void);
void wait_butt(void);
void print_array(int8 *arr, int16 arr_lenght);
void main(void)
{
int8 data[10] = {1,2,3,4,5,6,7,8,9,69};
int8 rec_arr[264];
user_init();
wait_butt();
led_on;
while(True){
ext_flash_writePageThroughBuffer(0, def_buff,0 ,data, sizeof(data));
ext_flash_readPage(0, 0, rec_arr, 264); //Hangs out here
print_array(rec_arr, sizeof(rec_arr));
wait_butt();
}
}
void wait_butt(void){
while(!butt_pressed);
while(butt_pressed);
}
void user_init(void){
setup_oscillator(OSC_PLL_5_DIV_3|OSC_NORMAL);
delay_ms(20); //Power up time
SETUP_SPI(SPI_DISABLED);
led_off;
output_low(pin_c0);
output_low(pin_c1);
set_tris_c(TRIS_C_SET);
init_ext_flash();
}
void print_array(int8 *arr, int16 arr_lenght){
int16 i;
for(i=0;i<arr_lenght; i++)
printf("%u ",arr[i]);
}
|
And this is the my dev board:
https://www.olimex.com/Products/PIC/Proto/PIC-P67J60/
PCM programmer I modified the wait_until_ready to this:
Code: | void ext_flash_waitUntilReady()
{
int busy = 0;
while (!(busy & 0x80)){
output_low(FLASH_SELECT);
ext_flash_sendData(0xD7,8);
busy = ext_flash_readStatus();
}
}
|
Now it works well. _________________ A person who never made a mistake never tried anything new. |
|
|
|
|
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
|