|
|
  |
замена AT45DB161B-RI на AT45DB161D-SU, проблема с отсутствием ноги RDY/~BUSY |
|
|
|
Mar 28 2007, 22:30
|
Местный
  
Группа: Свой
Сообщений: 443
Регистрация: 22-07-06
Из: Украина, г. Харьков
Пользователь №: 19 006

|
Цитата do { DF_ChipSelect_Start(); SPI_WriteByte( DF_CMD_STATUS_READ_SPI03 ); bLastStatus = SPI_ReadByte(); DF_ChipSelect_Stop(); } while( (bLastStatus & 0x80) == 0 ); Здесь при неготовности микросхемы после деселекта микросхемы сразу идет опять выбор. Достаточно ли времени ChipSelect находится в неактивном состоянии, чтобы DataFlash его заметила? Ато проц нереально шустрый, может она не успевает? У меня с другими микрухами из-за этого както раз были проблемы, пришлось вставлять задержку. Так у меня AVR-ка была, а тут проц побыстрее.
|
|
|
|
|
Mar 30 2007, 10:17
|
Частый гость
 
Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287

|
Вот они: Код #define SPI_MODE 0x38 // MSTR CPOL CPHA = 111 #define SPI_RATE 0x08
// SPI Initialization void SPI_Init( void ) { S0SPSR; S0SPINT = 0x01; S0SPCCR = SPI_RATE; S0SPCR = SPI_MODE; S0SPDR; S0SPSR; }
// SPI Read byte unsigned char SPI_ReadByte( void ) { unsigned char bTmp;
S0SPSR; S0SPCCR = SPI_RATE; S0SPCR = SPI_MODE; S0SPDR = 0; do { bTmp = S0SPSR; if( (bTmp & 0x10) != 0 ) // if MODF = 1 S0SPCR = SPI_MODE; if( (bTmp & 0x40) != 0 ) // if WCOL = 1 S0SPDR; } while( (bTmp & 0x80) == 0 );
return( S0SPDR ); }
// SPI Write byte void SPI_WriteByte( unsigned char bData ) { unsigned char bTmp;
S0SPSR; S0SPCCR = SPI_RATE; S0SPCR = SPI_MODE; S0SPDR = bData; do { bTmp = S0SPSR; if( (bTmp & 0x10) != 0 ) // if MODF = 1 S0SPCR = SPI_MODE; if( (bTmp & 0x40) != 0 ) // if WCOL = 1 S0SPDR; } while( (bTmp & 0x80) == 0 ); } Раньше на чтение/запись по SPI была одна функция, но когда начались непонятные пляски, пришлось разделить на всякий случай.
Сообщение отредактировал Ykidia - Mar 30 2007, 10:24
|
|
|
|
|
Mar 30 2007, 12:53
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Ykidia @ Mar 30 2007, 09:17)  Вот они: Ха! Батенька! #define SPI_MODE 0x38 Цитата 6 LSBF LSB First controls which direction each byte is shifted when transferred. When 1, SPI data is transferred LSB (bit 0) first. When 0, SPI data is transferred MSB (bit 7) first. Вы же данные не тем концом суете. Цитата All instructions, addresses, and data are transferred with the most significant bit (MSB) first. Код { __spcr_bits Tmp; Tmp.CPHA = 1; Tmp.CPOL = 1; Tmp.MSTR = 1; Tmp.LSBF = 0; Tmp.SPIE = 0; S0SPCR_bit = Tmp; } В остальном не вижу криминала. Единственное, у меня IAR строчки вида S0SPSR; просто выкидывает. Хотя это явная ошибка, по стандарту должно быть чтение. Поэтому я делаю { volatile uint8_t tmp = S0SPSR; }. Не смотрели листинг, может то же самое?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 31 2007, 10:00
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата Единственное, у меня IAR строчки вида S0SPSR; просто выкидывает. Хотя это явная ошибка Вспоминается, что если S0SPSR объявлен как volatile, то не должон. Если объявлен не так, то компилер имеет полное право. В iomacro.h написано, что SFR_B разворачивается в __io union, а в мануале пишут The __io memory attribute implies that objects are __no_init and volatile. Если правда игнорит, то действительно невесело.
--------------------
aka Vit
|
|
|
|
|
Mar 31 2007, 13:24
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(sensor_ua @ Mar 31 2007, 09:00)  Вспоминается, что если S0SPSR объявлен как volatile, то не должон. Если правда игнорит, то действительно невесело. В том то и дело: Код #define __IO_REG32_BIT(NAME, ADDRESS, ATTRIBUTE, BIT_STRUCT)\ volatile __no_init ATTRIBUTE union \ { \ unsigned long NAME; \ BIT_STRUCT NAME ## _bit; \ } @ ADDRESS __IO_REG32_BIT(S0SPSR, 0xE0020004,__READ,__spsr_bits); //----------------------------------- S0SPSR = 0; S0SPSR; // Warning[Pe174]: expression has no effect S0SPSR = 0; //----------------------------------- 379 S0SPSR = 0; \ 000001BC 041082E5 STR R1,[R2, #+0x4] 380 S0SPSR; 381 S0SPSR = 0; \ 000001C0 041082E5 STR R1,[R2, #+0x4] Я помню, ReAl когда-то писал, что подобные выражения оформляет как (void)S0SPSR; чтобы самому себе напомнить, что это не описка а чтение. Но, увы, IAR тут делает большой промах. Хотя по доке вроде все нормально: Цитата Descriptions of implementation-defined behavior Access to volatile objects (6.5.3) Any reference to an object with volatile qualified type is an access. Смущает только упоминание implementation-defined behavior. Надо будет на работе в стандарт глянуть - что там об этом случае сказано. P.S. Ветка как-то плавно уползла от AVR к ARM, но описанная проблема относится ко всем IAR, с которыми работал.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 31 2007, 16:32
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Mar 31 2007, 12:24)  P.S. Ветка как-то плавно уползла от AVR к ARM, но описанная проблема относится ко всем IAR, с которыми работал. Да нету проблемы. Использую постоянно. Ниже первый попавшийся кусок, где дважды используется пустышка. Командная строка и листинг прилагаются. Код ////////////////////////////////////////////////////////////////////////////// // / // IAR ARM ANSI C/C++ Compiler V4.41A/W32 27/Mar/2007 19:41:57 / // Copyright 1999-2005 IAR Systems. All rights reserved. / // / // Cpu mode = arm / // Endian = little / // Stack alignment = 4 / // Source file = D:\ARM_WORK\pcmu\MAIN\SPI.C / // Command line = D:\ARM_WORK\pcmu\MAIN\SPI.C -D LPC2000_IAR -lC / // D:\ARM_WORK\pcmu\Works\List\ -lA / // D:\ARM_WORK\pcmu\Works\List\ --remarks -o / // D:\ARM_WORK\pcmu\Works\Obj\ -s9 --debug --cpu_mode / // arm --endian little --cpu ARM7TDMI-S --stack_align / // 4 --warnings_affect_exit_code / // --no_path_in_file_macros -e --require_prototypes / // --fpu None --dlib_config "D:\IAR\Embedded / // Workbench\arm\LIB\dl4tpannl8n.h" -I / // D:\ARM_WORK\pcmu\..\COMMON\RTOS\portable\IAR\LPC200 / // 0\ -I D:\ARM_WORK\pcmu\..\COMMON\RTOS\include\ -I / // D:\ARM_WORK\pcmu\..\COMMON\include\ -I / // D:\ARM_WORK\pcmu\MAIN\include\ -I "D:\IAR\Embedded / // Workbench\arm\INC\" --inline_threshold=2 / // List file = D:\ARM_WORK\pcmu\Works\List\SPI.s79 / // / // / //////////////////////////////////////////////////////////////////////////////
....
RSEG CODE:CODE:NOROOT(2) CFI Block cfiBlock7 Using cfiCommon0 CFI Function fpga_switch ARM // int fpga_switch( WORD data, WORD addr ) // { // ulong value = ( 0x9C0000>>(8+2) ); // int ret_data; // value |= (addr>>8)|((addr&0x1F)<<3); // value <<= 8; // value |= (data>>8)|((data&0x1F)<<3); // value <<= 2; fpga_switch: LSR R2,R1,#+8 AND R1,R1,#0x1F ORR R1,R2,R1, LSL #+3 ORR R1,R1,#0x2700 LSR R2,R0,#+8 AND R0,R0,#0x1F ORR R0,R2,R0, LSL #+3 ORR R0,R0,R1, LSL #+8 LSL R1,R0,#+2 // IO0CLR = P0B_SEL_FPGA; // Select(soft) MOV R0,#-536870908 ORR R0,R0,#0x28000 MOV R2,#+268435456 ORR R2,R2,#0x1000 STR R2,[R0, #+8] // SSPDR = value>>16; MOV R3,#-536870904 ORR R3,R3,#0x68000 LSR R12,R1,#+16 STR R12,[R3, #+0] // IO0SET = P0B_SEL_FPGA; // Unselect STR R2,[R0, #+0] // while( !(SSPSR & SSPSR_RNE) ); ??fpga_switch_0: LDR R0,[R3, #+4] TST R0,#0x4 BEQ ??fpga_switch_0 // ret_data = SSPDR; LDR R0,[R3, #+0] // SSPDR = value>>8; LSR R2,R1,#+8 STR R2,[R3, #+0] // while( !(SSPSR & SSPSR_RNE) ); ??fpga_switch_1: LDR R2,[R3, #+4] TST R2,#0x4 BEQ ??fpga_switch_1 // SSPDR; LDR R2,[R3, #+0] // SSPDR = value; STR R1,[R3, #+0] // while( !(SSPSR & SSPSR_RNE) ); ??fpga_switch_2: LDR R1,[R3, #+4] TST R1,#0x4 BEQ ??fpga_switch_2 // SSPDR; LDR R1,[R3, #+0] // return( ret_data ); MOV PC,LR ;; return CFI EndBlock cfiBlock7 // }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 31 2007, 17:03
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Mar 31 2007, 15:45)  Конечно! А я, значит, листинг и варнинг компилятора сам сочинил? А я  ? Только я еще и командную строку, и версию компилятора привел, однако. Могу еще добавить, для другого регистра и других условий: Код // __fiq __arm void FIQ_ISR_handler(void) // { FIQ_ISR_handler: SUB LR,LR,#+4 CFI ?RET R14 PUSH {R0-R4,LR} CFI ?RET Frame(CFA, -4) CFI R4 Frame(CFA, -8) CFI R3 Frame(CFA, -12) CFI R2 Frame(CFA, -16) CFI R1 Frame(CFA, -20) CFI R0 Frame(CFA, -24) CFI CFA R13+24 SUB SP,SP,#+16 CFI CFA R13+40 // ulong data; // // Need for Request clear:( // S0SPSR; MOV R8,#-536870908 ORR R8,R8,#0x20000 LDR R0,[R8, #+0] // // Clear Interrupt // S0SPINT = SPINT_SPIIF; MOV R0,#+1 STR R0,[R8, #+24] // Read Data // data = S0SPDR; LDR R9,[R8, #+4] ......
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 31 2007, 20:59
|
Частый гость
 
Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287

|
Цитата Вы же данные не тем концом суете. Вообще-то 2 варианта. Если вдруг Вы правы, тогда у меня бы все читалось наоборот, и в статусе было бы что-то вроде 0x35 вместо 0xAC или 0x37 вместо 0xEC. Но такого нет и рядом, читается 0x00 (либо 0xFF, который я раньше выдавал в линию для старта передачи), а в большинстве "рабочих" экземпляров читается что надо. Ну а второй вариант - просто посмотрите внимательно на мой дефайн: Цитата #define SPI_MODE 0x38 Бит 6 = 0, отсюда Цитата When 0, SPI data is transferred MSB (bit 7) first. что вполне совпадает с требованиями: Цитата All instructions, addresses, and data are transferred with the most significant bit (MSB) first. Цитата Единственное, у меня IAR строчки вида S0SPSR; просто выкидывает. Хотя это явная ошибка, по стандарту должно быть чтение. Поэтому я делаю { volatile uint8_t tmp = S0SPSR; }. Не смотрели листинг, может то же самое? У меня не выкидывает. Смотрел по листингу для 2214 - чтение на месте. Для 2138 при компиляции почему-то сообщает, что выражение не имеет эффекта, но по листингу все равно чтение остается.
Сообщение отредактировал Ykidia - Mar 31 2007, 20:59
|
|
|
|
|
Mar 31 2007, 22:57
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Ykidia @ Mar 31 2007, 19:59)  Ну а второй вариант - просто посмотрите внимательно на мой дефайн: Бит 6 = 0 Мда, сглупил. Извиняюсь. Сообщите, если найдете причину. Альтернатив-то команде чтения статуса нет, а на нее все остальные завязаны. Маловероятно, чтобы такую плюху пропустили. Еще меня несколько смущает, что вы каждый раз делаете переинициализацию SPI. Может в результате этого происходит какое-то лишнее шевеление ногой CLK? Я бы попробовал с таким максимально простым кодом: Код unsigned char SPI_ReadByte( void ) { S0SPDR = 0; while( !(S0SPSR & 0x80) ); return( S0SPDR ); }
void SPI_WriteByte( unsigned char bData ) { S0SPDR = bData; while( !(S0SPSR & 0x80) ); }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 1 2007, 04:56
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Ykidia @ Mar 31 2007, 19:59)  Вообще-то 2 варианта. Если вдруг Вы правы, тогда у меня бы все читалось наоборот... Вообще-то был бы только 1 вариант - писалось бы наоборот тоже. Тобиш вместо опкода 0x57 посылался бы 0xEA.. На такой опкод вполне реально получить в ответ 0x0 или 0xFF. Но это к проблеме не относится.. а так просто чтобы обратить внимание на причинно следственную связь. А по проблеме, думаю банально накосячили с сигналами либо заняли чем-то SSEL.. Если программно клокать, работает? Цитата S0SPSR; Я бы так ни в жизнь не написал. Код V32 dummy = S0SPSR; // dummy read of SPIF куда понятнее смотрится и безопастнее.
|
|
|
|
|
Apr 1 2007, 09:18
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(defunct @ Apr 1 2007, 03:56)  Я бы так ни в жизнь не написал. Жизнь она такая штука  - меняется  . Чем, например, такое написание хуже и непонятнее вызова функции без аргументов с игнорированием возвращаемого ей значения? Это нормально? status(); Или так надо  ? V32 dummy = status();
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 1 2007, 23:48
|
Частый гость
 
Группа: Свой
Сообщений: 80
Регистрация: 3-08-06
Пользователь №: 19 287

|
Цитата Я бы попробовал с таким максимально простым кодом Да у меня и было максимально просто, а как пошли глюки, так я постарался сделать точно так, как написано в даташите на LPC2214 в разделе SPI: The following sequence describes how one should process a data transfer with the SPI block when it is set up to be the master. This process assumes that any prior data transfer has already completed. 1. Set the SPI clock counter register to the desired clock rate. 2. Set the SPI control register to the desired settings. 3. Write the data to transmitted to the SPI data register. This write starts the SPI data transfer. 4. Wait for the SPIF bit in the SPI status register to be set to 1. The SPIF bit will be set after the last cycle of the SPI data transfer. 5. Read the SPI status register. 6. Read the received data from the SPI data register (optional). 7. Go to step 3 if more data is required to transmit. Ну и т.д.  Цитата просто чтобы обратить внимание на причинно следственную связь. Это да, но про варианты я сказал не особо серьезно, так как внимание уже было обращено на тот факт, что почти везде работает как надо, т.е. пишет, читает то, что писалось, читается статус - занятость, результат сравнения и т.д. Цитата Я бы так ни в жизнь не написал. Никогда не говорите никогда. Плохо кончится, родной © Кин-дза-дза  Однако я так пишу потому что Цитата А меня задолбали варнинги на неиспользуемые dummy и стал писать только так полностью согласен  . Более того - Вы смотрели листинг с использованием этих dummy? Я решил проверить. почему выходит варнинг, и оказалось, что для таких случаев строки типа Цитата V32 dummy = S0SPSR; // dummy read of SPIF просто выкинуты и отсутствуют в ассемблерном коде.
Сообщение отредактировал Ykidia - Apr 2 2007, 00:03
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|