From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25916 invoked by alias); 1 Jul 2005 22:54:53 -0000 Mailing-List: contact ecos-discuss-help@ecos.sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: ecos-discuss-owner@ecos.sourceware.org Received: (qmail 25881 invoked by uid 22791); 1 Jul 2005 22:54:48 -0000 Received: from norbert.ecoscentric.com (HELO smtp.ecoscentric.com) (194.153.168.165) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Fri, 01 Jul 2005 22:54:48 +0000 Received: by smtp.ecoscentric.com (Postfix, from userid 99) id 444C565C082; Fri, 1 Jul 2005 23:54:46 +0100 (BST) Received: from delenn.bartv.net (localhost [127.0.0.1]) by smtp.ecoscentric.com (Postfix) with ESMTP id 8502565C057; Fri, 1 Jul 2005 23:54:42 +0100 (BST) To: gruber.m@utanet.at Cc: ecos-discuss@sources.redhat.com In-reply-to: <200507011523.14520.gruber.m@utanet.at> (message from Manfred Gruber on Fri, 1 Jul 2005 15:23:14 +0200) From: Bart Veer References: <200507011523.14520.gruber.m@utanet.at> Message-Id: <20050701225442.8502565C057@smtp.ecoscentric.com> Date: Fri, 01 Jul 2005 22:54:00 -0000 Subject: Re: [ECOS] flash v2 program problem X-SW-Source: 2005-07/txt/msg00021.txt.bz2 >>>>> "Manfred" == Manfred Gruber writes: Manfred> I use flash_v2 branch and have a problem on program my Manfred> device. I use a AM29LV256, 2 x 16 bit devices on a 32 bit Manfred> bus . On testing I found out that Toggle Bit DQ6 Manfred> functionality fails sometimes on my hardware. I had done Manfred> a quick dirty hack, with that it works. can someone tell Manfred> me why? Manfred> // Quick dirty hack Manfred> do { Manfred> current = addr[i]; Manfred> if ((current & AM29_STATUS_DQ7) == masked_datum) { Manfred> break; Manfred> } Manfred> if (0 != (current & AM29_STATUS_DQ5)) { Manfred> continue; Manfred> } Manfred> } while (retries-- > 0); This code looks wrong. While a program operation is in progress DQ7 will be inverted relative to the value being programmed, DQ6 will toggle, and DQ5 will remain clear unless there is a serious error. On completion the value read back will be the same as the value programmed, so DQ7 will now match and DQ6 will cease toggling. Things get somewhat complicated when there are parallel devices which may complete at different times. The test if ((current & AM29_STATUS_DQ7) == masked_datum) checks for completion: the DQ7 bits of all the chips match the values being programmed. If one of the chips has finished but the other is still busy then the test will fail. The next test, if (0 != (current & AM29_STATUS_DQ5)) { continue; } does not achieve anything useful. Usually DQ5 will be clear so the test will fail and we just go around the loop again. If there is ever a serious error and DQ5 gets set, we just continue around the loop again. You are no longer testing for errors, only for completion. Now for the original: Manfred> do { Manfred> current = addr[i]; Manfred> if ((current & AM29_STATUS_DQ7) == masked_datum) { Manfred> break; Manfred> } Manfred> if (0 != (current & AM29_STATUS_DQ5)) { Manfred> current2 = addr[i]; --> Sometimes my devices fail here .... Manfred> if ((((current ^ current2) & AM29_STATUS_DQ6) >> 1) & current) { Manfred> block_start[AM29_OFFSET_COMMAND] = AM29_COMMAND_RESET; Manfred> return; Manfred> } Manfred> } Manfred> } while (retries-- > 0); Manfred> #endif The DQ7 test again checks for completion. The DQ5 test can trigger in two situations: either there is a real error, or one of the chips has completed before the other and the value being written happens to have bit 5 set. If a chip is still busy programming then DQ6 will be toggling, so bit 6 of current and current2 will be different. The expression "(current ^ current2)" detects changing bits, masking with DQ6 means we are only interested in that bit toggling, the ">> 1" moves to DQ5, and finally "& current" gives us the error condition. There are actually three cases: 1) both current and current2 were read while the chip was busy programming. DQ6 will have toggled. If DQ5 is set then we have an error. 2) current was read while the chip was busy toggling but current2 was read after completion. DQ6 may or may not have toggled depending on the value being written. But if DQ5 was set in current then there was an error. 3) both current and current2 were read after completion so DQ6 will have stopped toggling and (current ^ current2) always evaluates to 0. Hence the "if" test fails and we go around the loop again. Manfred> for example it fails with this values: Manfred> am29xxxxx_hw_programm: Manfred> current 0xff847abf Manfred> current2 0xffc45a5a Manfred> AM_STATUS 400040 Manfred> ((((current ^ current2) & AM29_STATUS_DQ6) >> 1) & current) --> 200020 Looking at the top 16 bits first we have (with ? == don't care): current ???????? 10000100 current2 ???????? 11000100 so DQ6 is toggling, i.e. the chip is still busy, DQ5 is clear indicating no error, and presumably the value being written has bit 7 clear so it is currently being read inverted as 1. This is all as expected. Now for the bottom 16 bits: current ???????? 10111111 current2 ???????? 01011010 This does not make a whole lot of sense. DQ7 has changed, so programming cannot have completed before current was read. Instead it looks like programming was still in progress when current was read but had completed for current2. The value being written to these 16 bits must have been 0x5a5a. Current has DQ5 set indicating an error. In theory this can happen when trying to program a 0 back to a 1, but at the start of the am29_hw_program() loop there is a mask operation to prevent this. The only other circumstance I know of under which DQ5 can be set is if the chip has an internal timeout, which is pretty much a fatal error condition. If so then DQ5 should continue reading back as 1 until there is a reset command. However current2 has DQ5 clear, yet there has not been a reset command. Manfred> I tried to use the toggle bit algorithm from my am29lv256 Manfred> documentation, but without sucess. maybe some flash_v2 Manfred> developer has a mor information for me what goes wrong? AFAIK the driver code is correct. I do not see how a standard am29 chip can give these results. Bart -- Bart Veer eCos Configuration Architect http://www.ecoscentric.com/ The eCos and RedBoot experts -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss