|
f149 UART1(SPI mode)&DataFlash - грабли |
|
|
|
Jun 10 2005, 07:28
|
Частый гость
 
Группа: Свой
Сообщений: 96
Регистрация: 10-06-05
Из: Новосибирск
Пользователь №: 5 890

|
Пытаюсь отработать процедуры для AT45DB161. UART0 - SerialPort, UART1 SPI 3-wire. Чтение и запись обоих буферов DataFlash проходит, есть грабельки, но не смертельные. Прямое чтение страницы MM из DataFlash как и запись MM через оба буфера - вообще без проблем. Операции стирания страниц, запись содержимого любого из буферов в любую страницу MM, загрузка любой страницы MM в любой буфер - не проходят вообще. Перебор уровней оптимизации IAR-овского компайлера не влияет, процедуры то простенькие, существенной разницы в ассемблерных листингах нет. Передрал несколько вариантов инициализации порта, вот так выглядит самый устойчивый. Код // - initialisation spi1 UART module ----------- void spi1_init (void) { U1CTL |= CHAR + SYNC + MM + SWRST; // 8-bit, SPI, Master U1TCTL |= CKPL + SSEL1 + STC; // Polarity, SMCLK, 3-wire U1BR0 = 0x02; // SPICLK = SMCLK/2 ~ 4MHz U1BR1 = 0x00; U1MCTL = 0x00; ME2 |= USPIE1; // Module enable U1CTL &= ~SWRST; // Restart USART SPI, SPI enable // IE2 |= URXIE1 + UTXIE1; // RX and TX interrupt enable } Опыта работы с DataFlash не так много. Собственно сами процедуры работы перенес с HiTech для pic18-го и DF AT45D011 Вторую неделю бъюсь и здравых мыслей уже нет. Остались только дурацкий колпак и бубен ...
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 18)
|
Jun 10 2005, 08:03
|

Частый гость
 
Группа: Свой
Сообщений: 138
Регистрация: 1-06-04
Из: Nighny Novgorod
Пользователь №: 27

|
Цитата(O.L. @ Jun 10 2005, 10:28) Вторую неделю бъюсь и здравых мыслей уже нет. Остались только дурацкий колпак и бубен ... телепаты тоже в отпуске - что за "не смертельные грабельки и процедуры простенькие"?
--------------------
|
|
|
|
|
Jun 10 2005, 08:29
|
Частый гость
 
Группа: Свой
Сообщений: 96
Регистрация: 10-06-05
Из: Новосибирск
Пользователь №: 5 890

|
"Несмертельные" грабли, Это при записи страницы в нулевой байт всегда пишется 0. А простенькие процедуры они завсегда тривиальные, типа такого: Код // - erasing DataFlash ------------------------- void erasing (unsigned int page_cnt) { RLedOn; // Led red anabled _DINT(); while(!(P5IN & DF_RDY_BUSY)); // waite P5OUT &= ~DF_CHIP_SEL; // enabled DataFlash TXBUF1 = PAGE_ERASE; while ((IFG2&UTXIFG1)!=UTXIFG1); // USART1 TX buffer ready? TXBUF1 = (char)(page_cnt>>8); while ((IFG2&UTXIFG1)!=UTXIFG1); // USART1 TX buffer ready? TXBUF1 = (char)page_cnt; while ((IFG2&UTXIFG1)!=UTXIFG1); // USART1 TX buffer ready? TXBUF1 = 0x00; while ((IFG2&UTXIFG1)!=UTXIFG1); // USART1 TX buffer ready? P5OUT |= DF_CHIP_SEL; // disabled DataFlash _EINT();
} и ассемблер у ней соответствующий: Код \ __code void erasing(unsigned int) \ erasing: \ 000000 B012.... CALL #??Subroutine3_0 \ ??erasing_0: \ 000004 D2B33000 BIT.B #0x1, &0x30 \ 000008 FD2B JNC ??erasing_0 \ 00000A F2C020003100 BIC.B #0x20, &0x31 \ 000010 F24081007F00 MOV.B #0x81, &0x7f \ ??erasing_1: \ 000016 F2B020000300 BIT.B #0x20, &0x3 \ 00001C FC2B JNC ??erasing_1 \ 00001E B012.... CALL #??Subroutine6_0 \ ??erasing_2: \ 000022 F2B020000300 BIT.B #0x20, &0x3 \ 000028 FC2B JNC ??erasing_2 \ 00002A C24C7F00 MOV.B R12, &0x7f \ ??erasing_3: \ 00002E F2B020000300 BIT.B #0x20, &0x3 \ 000034 FC2B JNC ??erasing_3 \ 000036 .... JMP ??Subroutine0_0
// 6_0 \ ??Subroutine6_0: \ 000000 0F4C MOV.W R12, R15 \ 000002 8F10 SWPB R15 \ 000004 C24F7F00 MOV.B R15, &0x7f \ 000008 3041 RET // 3_0 \ ??Subroutine3_0: \ 000000 E2C22100 BIC.B #0x4, &0x21 \ 000004 32C2 DINT \ 000006 0343 NOP \ 000008 3041 RET // 0_0 \ ??Subroutine0_0: \ 00001C C2437F00 MOV.B #0x0, &0x7f \ ??write_page_flash_4: \ 000020 F2B020000300 BIT.B #0x20, &0x3 \ 000026 FC2B JNC ??write_page_flash_4 // 8_0 \ ??Subroutine8_0: \ 000000 F2D020003100 BIS.B #0x20, &0x31 \ 000006 32D2 EINT \ 000008 3041 RET Все как надо, только не работает ...
|
|
|
|
|
Jun 10 2005, 10:00
|
Частый гость
 
Группа: Свой
Сообщений: 96
Регистрация: 10-06-05
Из: Новосибирск
Пользователь №: 5 890

|
Цитата(kpv @ Jun 10 2005, 16:05) при таком варианте, по опросу, попробуй использовать TXEPT UxTXBUF and TX shift register are empty Слабоват я пока в знании матчасти, а в том, что вы написали, определенно есть смысл. Переписал все, erasing теперь работает, но в буфер ни в первый, ни во второй данные записываться перестали ... В общем дело двинулось, и это уже неплохо.
|
|
|
|
|
Jun 10 2005, 10:06
|

Частый гость
 
Группа: Свой
Сообщений: 138
Регистрация: 1-06-04
Из: Nighny Novgorod
Пользователь №: 27

|
Цитата(O.L. @ Jun 10 2005, 13:00) Слабоват я пока в знании матчасти на русском почитайте - лучше, может быть, усвоится www.gaw.ru у меня на сайте старенький перевод лежит. Цитата(O.L. @ Jun 10 2005, 13:00) но в буфер ни в первый, ни во второй данные записываться перестали код в студию, ассемблерный не надоть...
--------------------
|
|
|
|
|
Jun 10 2005, 10:11
|

Частый гость
 
Группа: Свой
Сообщений: 138
Регистрация: 1-06-04
Из: Nighny Novgorod
Пользователь №: 27

|
Цитата(O.L. @ Jun 10 2005, 12:53) У меня кварц 7 372 800, но при U1BR1 = 0x00, а U1BR0 = 0x03, U1BR0 = 0x04 и т.д. регистр статуса микросхемы просто не читается. всё сходится - spi работает на большой скорости и пока, по опросу, бит освобождения UxTXBUF проверяется, есть большая вероятность, что за это время и передача закончится, в случае низких скоростей, получается так, что не успевает на 100%
--------------------
|
|
|
|
|
Jun 10 2005, 10:20
|
Частый гость
 
Группа: Свой
Сообщений: 96
Регистрация: 10-06-05
Из: Новосибирск
Пользователь №: 5 890

|
Цитата(kpv @ Jun 10 2005, 17:06) Цитата(O.L. @ Jun 10 2005, 13:00) Слабоват я пока в знании матчасти на русском почитайте - лучше, может быть, усвоится www.gaw.ru у меня на сайте старенький перевод лежит. Цитата(O.L. @ Jun 10 2005, 13:00) но в буфер ни в первый, ни во второй данные записываться перестали код в студию, ассемблерный не надоть... да совственно все без затей по Serial получаем порцию данных 512+служебка засовываем все это в буфер DataFlash Код // - write max page size 528byte to buffer DataFlash - void write_to_buffer (unsigned char * sprt, unsigned char a_buff) { unsigned int buffer_cnt = 0; RLedOn; // Led red anabled _DINT(); while(!(P5IN & DF_RDY_BUSY)); // waite blok cleared P5OUT &= ~DF_CHIP_SEL; // enabled DataFlash if (a_buff == BUFFER_1) // if active Buffer1 TXBUF1 = BUFFER_1_WRITE; else TXBUF1 = BUFFER_2_WRITE; while ((IFG2&UTXIFG1)!=UTXIFG1); TXBUF1 = 0x00; // don't care 8 bits while ((IFG2&UTXIFG1)!=UTXIFG1); // USART1 TX buffer empty? TXBUF1 = (char)(buffer_cnt>>8); // first two byte buffer addr while ((IFG2&UTXIFG1)!=UTXIFG1); // USART1 TX buffer empty? TXBUF1 = (char)buffer_cnt; // buffer addr(max. 2^8 = 256 pages) while ((U1TCTL&TXEPT)!= TXEPT); // USART1 TX buffer is empty? while(++buffer_cnt < (MAX_LEN+1)) { TXBUF1 = *sprt++; while ((U1TCTL&TXEPT)!= TXEPT); // USART1 TX buffer is empty? } P5OUT |= DF_CHIP_SEL; // disabled DataFlash _EINT(); }
|
|
|
|
|
Jun 10 2005, 10:30
|

Частый гость
 
Группа: Свой
Сообщений: 138
Регистрация: 1-06-04
Из: Nighny Novgorod
Пользователь №: 27

|
все, как было, можно было и оставить, только перед самым концом, когда #cs поднимаешь, добавить это Код while ((U1TCTL&TXEPT)!= TXEPT); а лучше, конечно, работать через прерывание
--------------------
|
|
|
|
|
Jun 10 2005, 10:59
|
Частый гость
 
Группа: Свой
Сообщений: 96
Регистрация: 10-06-05
Из: Новосибирск
Пользователь №: 5 890

|
Всяко по прерываниям лучше, я ж не спорю. Доберусь и до них, с буферами только разберусь  . Но похоже, где то в программе я сам с переключениями буферов лажанулся. Запись в память через буфер работает, мне его очисти потом не удается. Смысл DataFlas-ки в проекте такой. Нулевая страница для бэкапа, на экстренный случай. Последняя - примитивная файловая таблица. А все остальное пространство под хранение нескольких файлов. Какие то записываются один раз, какие то динамические. Вобщем флаги, пнризнаки, семафорчики ... сейчас чайку попью и алгоритм из разрухи начну восстанавливать. Часиков шесть у меня еще есть  Спасибо за помощь.
|
|
|
|
|
Apr 11 2006, 18:49
|
Участник

Группа: Свой
Сообщений: 43
Регистрация: 26-01-06
Из: Минск, Беларусь
Пользователь №: 13 651

|
Поднимаю старую тему. Есть F149 и две SPI-DataFlash - AT25F2048 и AT45DB161B. Инициализацию SPI (UART1) сделал на основе примеров из этой темы. Никакой связи с памятью наладить не удалось - выяснилось что на выводе контроллера P5.3 нет тактового сигнала UCLK. Вместо него или высокий уровень если установлен бит CKPL, или низкий если бит не установлен (по крайней мере вывод рабочий). Почему так - понять не могу. Из программы удалил всё, что не касается SPI. Осталось вот что: Код int main() {
WDTCTL = WDTPW + WDTHOLD; IE1 |= OFIE + WDTIE; IFG1 |= OFIFG; __enable_interrupt(); AT25SEL &= ~AT25LN; AT25DIR |= AT25LN; AT25CS_HI; AT45SEL &= ~AT45LN; AT45DIR |= AT45LN; AT45CS_HI; IE2 &= ~(UTXIE1 + URXIE1); U1CTL = SWRST; U1CTL |= CHAR + SYNC + MM; U1TCTL = CKPL + SSEL1 + STC; U1BR1 = 0x00; U1BR0 = 0x04; U1MCTL = 0x00; ME2 |= USPIE1; U1CTL &= ~SWRST; //IE2 |= UTXIE1 + URXIE1;
P5SEL |= 0x0E; P5DIR |= 0x0A;
P1DIR = 0x10; //проверка наличия SMCLK P1SEL = 0x10;
while(1) {
}
return 0; } и тактирование (кварц 7,32 МГц и 32КГц) Код #pragma vector = NMI_VECTOR __interrupt void OSCfault_ISR(void) { BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0; BCSCTL1 = DIVA_0 + RSEL2 + RSEL1 + RSEL0; DCOCTL = DCO1 + DCO2; while ((IFG1 & OFIFG) != 0) IFG1 &=~OFIFG; BCSCTL2 = SELM_2 + DIVM_0 + DIVS_0 + SELS; } На ноге 16 SMCLK есть. Пробовал разные варианты U1BR1 и U1BR0, пробовал тактирование от ACLK - результат тот же. Конфигурация выводов после выполнения программы: P5SEL=0b00001110 P5DIR=0b00011011 P5OUT=0b00010001 (т.е. вывод 5.3 - периферийный модуль, на вывод, обе памяти в состоянии сброса) вроде бы всё правильно.... и не работает. нужен свежий взгляд. Подскажите в каком направлении копать, пожалуйста. (может ли дело быть в схемотехнике? может, какая обвязка нужна - у меня всё соединено напрямую).
|
|
|
|
|
Apr 11 2006, 19:52
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
//Nikson, два момента. 1. Вы бы не поленились еще хидер с дефайнами к исходнику приложить. А то как можно найти чужую ошибку, когда такой блок видишь? Цитата AT25SEL &= ~AT25LN; AT25DIR |= AT25LN; AT25CS_HI; AT45SEL &= ~AT45LN; AT45DIR |= AT45LN; AT45CS_HI; 2. SPI это синхронный интерфейс для обмена данными. Чтобы что-то принять, нужно что-то передать. Где у вас в исходнике команда записи в UxTXBUF? Или вы предполагаете, что UCLK для SPI сам по себе постоянно генерится? В общем RTFM. P.S. ИМХО не совсем хорошо залезать в чужую тему со своими проблемами. Заведите свою собственную. Так более корректно будет.
|
|
|
|
|
Apr 11 2006, 21:12
|
Участник

Группа: Свой
Сообщений: 43
Регистрация: 26-01-06
Из: Минск, Беларусь
Пользователь №: 13 651

|
rezident, Да, точно. Эти 2 куска управляют только сигналами ChipSelect для двух микросхем памяти. На SPI влияния не оказывают, поэтому из поля зрения упустил. Что касается UCLK и U1TXBUF... У меня-то именно передача и не работала. Поиск неисправности в первую очередь начал с проверки тактового сигнала. Обнаружилось, что его нет - вот я и бросился активно его искать, максимально урезав код, убрал всё что хоть как-то могло повлиять (в том числе и запись данных в буфер передатчика)- до этого момента был уверен, что он должен генерироваться постоянно пока включён модуль, независимо от состояния приёма/передачи в данный момент. Ну не знаю, почему я это так придумал  ....К сожалению, теперь выходит что не UCLK дело и надо рыть глубже. По крайней мере не буду топтаться на одном месте. Спасибо. ЗЫ. Хорошо, замечание по поводу тем принято. Приношу свои извинения. Просто иногда на форумах проповедуется идеология "все схожие вопросы в одной теме". Сделано для того, чтобы человек при решении проблемы поиском наткнулся на одну тему, прочитал её от начала до конца и разобрался. А не рылся в залежах тем-близнецов. ИМХО какая-то логика в этом есть, но в чужой монастырь со своим уставом не ходят
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|