EugenOS Опубликовано 17 июля, 2014 Поделиться Опубликовано 17 июля, 2014 Знатоки NEC подскажите в чем проблема. Имею такую проблему. Портировал в ИАР нековский пример эмулятора еепром на uPD78F9234. Если загружаю программу в контроллер из под ИАРа(тогда загружается код дебагера), все работает. Если же беру HEX (.a26) и заливаю его в контррллер, то блок данных записывает, но функция записи возвращает false (0) как будто запись не удалась. Просматриваю память - данные на месте (записаны без ошибок). Вот здесь в tst без кода отладчика появляется 0. eeBuffer.ee_data.id = rxBuffer.sub_cmd; eeBuffer.ee_data.delimiter = 0; cpy64( eeBuffer.ee_data.data, rxBuffer.data ); tst = eeprom_write( &eeBuffer.ee_data ); то же самое (дизасм): ; eeBuffer.ee_data.id = rxBuffer.sub_cmd; 1335 255E MOV A, S:rxBuffer+1 ; (0xFE5E) 1337 E568 MOV S:eeBuffer, A ; (0xFE68) ; eeBuffer.ee_data.delimiter = 0; 1339 F05FFE MOVW AX, #rxBuffer+2 ; (0xFE5F) 133C F57100 MOV S:0xFE71, #0x00 ; cpy64( eeBuffer.ee_data.data, rxBuffer.data ); 133F E4 MOVW BC, AX 1340 F069FE MOVW AX, #eeBuffer+1 ; (0xFE69) 1343 225116 CALL cpy64 ; (0x1651) ; tst = eeprom_write( &eeBuffer.ee_data ); 1346 F068FE MOVW AX, #eeBuffer ; (0xFE68) 1349 220202 CALL eeprom_write ; (0x0202) 134C 0AE5 MOV C, A ; в других вариантах вместо tst (оптимизировало в регистр С)был сразу if, но результат был тот же. работает так, будто там false вот исходный код eeprom_write (слегка модифицированный код из примеров NEC, просто там они использовали тип bit, которого нет в IAR): ;------------------------------------------------------------------- ; Function name: __eeprom_write (user access function) ; Input: AX = Structure pointer ; Return value: CY = 0(Normal completion) or CY = 1 (abnormal completion) ; Summary: Writes data with specified number from the storage address to EEPROM. ; 1. Searches for blocks being used as EEPROM. ; 2. If there are no valid blocks, the first specified block is set as valid. ; 3. Searches for addresses to enable writing to valid block. ; 4. If the valid blocks are full and cannot be written to, the operation moves to the next block. ; 5. Creates write data. ; 6. Writes to valid blocks. ;------------------------------------------------------------------- ;bit _eeprom_write(struct_eeprom_data *) eeprom_write: PUSH HL PUSH DE PUSH BC CALL getpara ; Decomposes parameter from argument CALL SelfFlashModeOn ; Sets flash mode CALL EEPROMUseBlockSearch ; Searches block currently used as EEPROM BNC EP_WRITE_WTS ; Branches if currently used blocks are found ; ; Starts using new block because no currently used blocks are found ; CALL EEPROMBlockInit ; If no currently used blocks are found, sets block with ; smallest number specified as EEPROM as valid block BC EP_WRITE_FL ; Branches and completes if securing has failed EP_WRITE_2: MOVW AX,#EEPROM_BLOCK*100H+DATATOP MOV CurentB_No,A ; Determines block number to be used ; ; Data write processing ; EP_WRITE_SELF: MOVW DE,AX ; Sets current write address to DE MOVW AX,RWPointer ; Reads structure address XCHW AX,DE ; Sets structure address to DE MOV C,#LENG CALL FlashEEPROMWrite ; Writes data to EEPROM BZ EP_WRITE_TR EP_WRITE_FL: CALL SelfFlashModeOff ; Releases flash mode MOV A,0 ; Return value = Abnormal completion (FALSE) BR EP_WRITE_E ; ; If current block is valid ; EP_WRITE_WTS: CALL EEPROMWriteTopSearch ; Searches writable area BNC EP_WRITE_SELF ; Goes to data writing because area was found ; ; Moves to next block because there is no free space in area ; CALL EEPROMUseBlockChange ; Changes used block BC EP_WRITE_FL ; Exits with abnormal completion EP_WRITE_TR: CALL SelfFlashModeOff ; Releases flash mode MOV A,1 ; Return value = Normal completion (TRUE) EP_WRITE_E: POP BC POP DE POP HL RET ;------------------------------------------------------------------- getpara: MOVW HL,AX ; Sets Structure pointer to HL MOVW RWPointer,AX ; Copies to work area MOV A,[HL] ; Reads data number MOV RQDATA_No,A ; Copies to work area INCW HL ; Sets data address to HL RET ;------------------------------------------------------------------- ; Function name: FlashEEPROMWrite ; Input: DE = Write start address ; C = Number of data blocks to be written ; AX = Write data storage address ; Output: Z(ZeroFlag) = Normal completion (1) or abnormal completion (0) ; Registers used: D, E ; Summary: Writes data to EEPROM and internally verifies the data. ;------------------------------------------------------------------- FlashEEPROMWrite: PUSH HL PUSH AX PUSH BC MOVW HL,AX ; AX = Write data storage address MOV FLCMD,#CMD_BYTE_WRITE ; Sets flash control command (byte write) FL_WR_W1: MOVW AX,HL MOV FLAPH,A XCH A,X MOV FLAPL,A ; Sets write/verify address MOV A,[DE] MOV FLW,A ; Sets write data CALL SubFlashSelfPrg BZ FL_WR_W2 ; Exits if normal completion POP BC BR FL_WR_E FL_WR_W2: INCW DE ; Read address + 1 INCW HL ; Write address + 1 DBNZ C,FL_WR_W1 ; Loops for specified number of bytes POP BC ; C = Number of data blocks to be written POP AX ; Loads write data storage address ; AX = Write data storage address PUSH AX ; Saves write data storage address MOV FLCMD,#CMD_INTERNAL_VERIFY2 ; Sets flash control command (internal verify) MOV FLAPH,A XCH A,X MOV FLAPL,A ; Sets verify start address DEC C ADD A,C XCH A,X ADDC A,#0 MOV FLAPHC,A XCH A,X MOV FLAPLC,A ; Sets verify end address CALL SubFlashSelfPrg FL_WR_E: POP AX POP HL RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Код не весь, смысла весь приводить не вижу. раз данные записываются, значит попадаем в функцию FlashEEPROMWrite. Пробовал из нее убрать ту часть где производится верификация данных. Результат неизменен. вот все различия в данных записываемых в контроллер (ну плюс еще 300 байт отладчика в конце памяти). Как видим это вектор ресета, вектор INTP3 которым порльзуется дебагер и одна ячейка таблицы CALLT которой так же пользуется дебагер. По-видимому отличия в инициализации сказываются на работе с флешь памятью. Вот моя процедура инициализации (вызываю в main в самом начале): void hwinit(void) { asm("DI"); unsigned char ucCnt200us; PCC = 0; // fxp (= fx/4 = 2 MHz) LSRCM = 1; /* Stop the oscillation of the low-speed internal oscillator */ if (!(RESF & 0x01)) { /* Omit subsequent LVI-related processing during LVI reset */ LVIS = 0x0; /* Set the low-voltage detection level (VLVI) to 4.3 V +-0.2 V */ LVION = 1; /* Enable the low-voltage detector operation */ for (ucCnt200us = 0; ucCnt200us < 9; ucCnt200us++) { /* Wait of about 200 us */ asm("NOP"); } while (LVIF){ /* Wait for VDD >= VLVI */ asm("NOP"); } LVIMD = 1; /* Set so that an internal reset signal is generated when VDD < VLVI */ } PPCC = 0x0; // The clock supplied to the peripheral hardware (fxp) = fx (= 8 MHz) P0 = 0x0; PM0 = 0xF0; P2 = 0x00; PM2 = 0xF0; P3 = 0x00; PM3 = 0xF0; P4 = 0x38; PM4 = 0x10; P12 = 0x0F; PM12 = 0xF1; P13 = 0x00; MK0 = 0xFF; // all Intr disabled MK1 = 0xFF; // all Intr disabled setupTimerT80( tcl80_DIV64, 126 ); enableT80Interrupt(); uartSetup( fXPdiv2, 208, noParity | use8DataBits ); ASICL6_bit.no0 = 1; // inverted TxD; uartEnableRxInt(); uartEnableErrInt(); //initWdt( wcsIntOsc | wtv262144 ); initWdt( wcsStop );// пока отключил WDT clrWdt(); IF0 = 0x00; asm("EI"); } Сижу читаю (до дыр) даташиты... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.