|
MSP-EXP430F5529, I2C slave transmitter проблема |
|
|
|
Oct 5 2011, 15:50
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Добрый день!
Есть борд MSP-EXP430F5529. Запускаю I2C. Среда IAR. Загрузил пример от TI MSP430F55xx_uscib0_i2c_05, который делает борд ведомым передатчиком и отправляет число по I2C мастеру. Заметил странность, мастер получает числа как будто деленные на 2. В теле программы создал константу и отправляю ее на передачу, мастером вижу, что число в два раза меньше, к примеру оправляю 0xAA получаю 0x55, отправляю 0хFF получаю 0x7F. Такое ощущение что сдвиговый регистр отнимает единицу от количества требуемых сдвигов, из-за этого получается деление на два. Читал мануал, код вроде правильный, а непонимание есть. Что это такое, как это понять и устранить?
|
|
|
|
|
 |
Ответов
(15 - 29)
|
Oct 11 2011, 06:35
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Резисторы по 4.7кОм. Проверяю на частоте от 400кГц и ниже. Абсолютно ничего секретного, питание FTDI и борда 3.3В резисторы есть со стороны FTDI и со стороны борда. Эти два устройства физически соединяются тремя проводами: (SDA, SCL, GND). Уже попробовал частоту тактирования MSP повышать до 25Мгц, макс. частота обмена при котором получаю нормальную, не сдвинутую дату примерно 320кГц. Могу картинку с осциллографа показать если нужно. Вот код: Код #include <msp430f5529.h>
unsigned char TXData; void SetVcoreUp (unsigned int level);
void main(void) { volatile unsigned int i;
WDTCTL = WDTPW+WDTHOLD; // Stop WDT P1DIR |= 0x01; // Set P1.0 to output direction P1OUT = 0x01; P1DIR |= BIT1; // P1.1 output
P1DIR |= BIT0; // ACLK set out to pins P1SEL |= BIT0; P2DIR |= BIT2; // SMCLK set out to pins P2SEL |= BIT2; P7DIR |= BIT7; // MCLK set out to pins P7SEL |= BIT7;
//********************* I2C **************************** P3SEL |= 0x03; // Assign I2C pins to USCI_B0 UCB1CTL1 |= UCSSEL1; UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode UCB0I2COA = 0x48; // Own Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0IE |= UCTXIE + UCSTTIE + UCSTPIE; // Enable TX interrupt // Enable Start condition interrupt TXData = 0x7F; // Used to hold TX data
//********************************************************* // Increase Vcore setting to level3 to support fsystem=25MHz // NOTE: Change core voltage one level at a time.. SetVcoreUp (0x01); SetVcoreUp (0x02); SetVcoreUp (0x03); UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO UCSCTL4 |= SELA_2; // Set ACLK = REFO
__bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_7; // Select DCO range 50MHz operation UCSCTL2 = FLLD_1 + 762; // Set DCO Multiplier for 25MHz // (N + 1) * FLLRef = Fdco // (762 + 1) * 32768 = 25MHz // Set FLL Div = fDCOCLK/2 __bic_SR_register(SCG0); // Enable the FLL control loop
// Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx // UG for optimization. // 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle __delay_cycles(782000);
// Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag __bis_SR_register(GIE); // Enter LPM0 w/ interrupts while(1) {} }
void SetVcoreUp (unsigned int level) { // Open PMM registers for write PMMCTL0_H = PMMPW_H; // Set SVS/SVM high side new level SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; // Set SVM low side to new level SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; // Wait till SVM is settled while ((PMMIFG & SVSMLDLYIFG) == 0); // Clear already set flags PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Set VCore to new level PMMCTL0_L = PMMCOREV0 * level; // Wait till new level reached if ((PMMIFG & SVMLIFG)) while ((PMMIFG & SVMLVLRIFG) == 0); // Set SVS/SVM low side to new level SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Lock PMM registers for write access PMMCTL0_H = 0x00; }
// USCI_B0 State ISR #pragma vector = USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: // Vector 6: STTIFG UCB0IFG &= ~UCSTTIFG; // Clear start condition int flag break; case 8: // Vector 8: STPIFG //TXData++; // Increment TXData UCB0IFG &= ~UCSTPIFG; // Clear stop condition int flag break; case 10: break; // Vector 10: RXIFG case 12: // Vector 12: TXIFG UCB0TXBUF = TXData; // TX data break; default: break; } } Скорость 320kbps: Адрес
adr_320.BMP ( 16.97 килобайт )
Кол-во скачиваний: 4 передача байта
byte_320.BMP ( 15.94 килобайт )
Кол-во скачиваний: 2 стоп
stop_320.BMP ( 12.84 килобайт )
Кол-во скачиваний: 2Скорость 400kbps: Адрес
adr_400.BMP ( 17.17 килобайт )
Кол-во скачиваний: 4 передача байта
byte_400.BMP ( 15.87 килобайт )
Кол-во скачиваний: 5 стоп
stop_400.BMP ( 12.98 килобайт )
Кол-во скачиваний: 4Должен добавить, что FTDI не поддерживает растягивание клоков, но скорости 400kbps, он успешно работал с C51, PIC, AVR, ARM.
|
|
|
|
|
Oct 11 2011, 09:37
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Посмотрите на этот скрин (адрес). Поймал граничное состояние, мастер иногда получает нормальную дату, а иногда плохую. Так как FTDI не поддерживает растягивание клоков, то последний бит клока для ASK/NASK, придавлен MSP. MSP пытается снизить скорость для решения внутренних задач.
DS0000.BMP ( 16.78 килобайт )
Кол-во скачиваний: 10. Растягивание приходиться только на половину клока, поэтому, иногда нормально, а иногда нет. Остается вопрос: Зачем MSP потребовалось притормозить при частоте ядра и периферии в 25МГц?
|
|
|
|
|
Oct 11 2011, 19:48
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Цитата А описание бага USCI30 в errata не в тему? В errata речь идет о том, когда модуль USCI работает как master receiver / slave receiver. Если прочитать за slave, то проблему можно обойти при контроле UCSCLLOW и при определенном чтении регистра приемника, учитываю проблемный бит клока. В моем случае slave transmitter. К тому же по описанию после бита R/W модуль обязан удерживать линию SCL в нуле и держать ее до тех пор, пока не загрузиться байт в регистр UCBxTXBUF, а затем давать ASK (стр 683 user guide, slau208i). Другое дело, почему MSP загружает байт так долго, при такой то частоте.
|
|
|
|
|
Oct 12 2011, 06:10
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Цитата конфликт при котором помимо (взаимо)действия pull-up и open drain на шину выдается "жесткая" лог.1. Вопрос: откуда? FTDI не поддерживает clock stretching. После принятия адреса и бита R\W MSP обязан сделать след. действия: The USCI module is automatically configured as a transmitter and UCTR and UCTXIFG become set. The SCL line is held low until the first data to be sent is written into the transmit buffer UCBxTXBUF. Then the address is acknowledged, the UCSTTIFG flag is cleared, and the data is transmitted. Поэтому получается, что MSP держит ckock после бита R\W перед битом ASK, до тех пор, пока байт не загрузится в UCBxTXBUF, т.к FTDI имеет источники тока на выходах SDA и SCL, которые позволяют даже на низком сопротивлении open drain иметь такую ступеньку. На картинке ASK clock похож как бы на стул. Так вот спинка этого стула, это момент когда MSP отпустил линию SCL.
|
|
|
|
|
Oct 12 2011, 14:32
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(*rust* @ Oct 12 2011, 11:10)  Поэтому получается, что MSP держит ckock после бита R\W перед битом ASK, до тех пор, пока байт не загрузится в UCBxTXBUF, Правильно. А как же иначе управлять асинхронным процессом? Тут нет никакого криминала, все в пределах спецификации I2C. Цитата(*rust* @ Oct 12 2011, 11:10)  т.к FTDI имеет источники тока на выходах SDA и SCL, которые позволяют даже на низком сопротивлении open drain иметь такую ступеньку. На картинке ASK clock похож как бы на стул. Так вот спинка этого стула, это момент когда MSP отпустил линию SCL. Э-э-э, позвольте! Что за источники тока? Источники втекающего тока (внутренний pull-down)?  Дык это явное нарушение спецификации I2C! В соответствии со спецификацией входной ток должен быть не выше ±10 мкА, т.е входное сопротивление не менее 500кОм. И причем тут спрашивается MSP430? Выходной каскад пина MSP430 вполне способен принять входной втекающий ток 15мА, создав при этом уровень напряжения VOL не выше 0,6В. В даташите это явно указано. По спецификации I2C для Standard- и Fast-mode требования для VOL гораздо скромнее: не менее 3мА@0,4В и не менее 6мА@0,6В. По вашей картинке в момент конфликта на шине уровень примерно в полпитания. Если MSP430 в это время тянет шину к нулю, то выходит, что FTDI выдает лог.1 с током не меньше 30-40 мА. То бишь проблема-то в FTDI заключена. С какого фига она выходной ток лог.1 создает в тот момент, когда его быть не должно? Сделайте эксперимент, уменьшив pull-up резисторы на шине до 560 Ом. Что при этом будет? Увеличится ли высота "сидения стула"? Ну и смотрите внимательно настройки FTDI, возможно вы ее неправильно конфигурируете для работы с I2C.
|
|
|
|
|
Oct 12 2011, 17:53
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Цитата Дык это явное нарушение спецификации I2C! А никто не говорит что FTDI работает по спецификации I2C. Я связывался с изготовителем и прояснял у них этот вопрос. Непонятно другое, что MSP делает так долго??? Тактовая 25МГц, один такт 40нС, скорость I2C - 400кГц, задержка SCL - 3мкС. Что можно делать за 75 тактов????? AVR, С51 с тактовой 8МГц справлялись c I2C(400кГц) легко, работая с той же самой FTDI.
|
|
|
|
|
Oct 12 2011, 19:03
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(*rust* @ Oct 12 2011, 22:53)  А никто не говорит что FTDI работает по спецификации I2C. Я связывался с изготовителем и прояснял у них этот вопрос. Тогда непонятно, чего вы тут на MSP430 бочку катите? Цитата(*rust* @ Oct 12 2011, 22:53)  Что можно делать за 75 тактов????? Вход в прерывание - 6 тактов, выход - 5 тактов. В симуляторе IAR есть счетчик циклов. Хотя с симуляцией периферии в IAR полный швах, но можно попробовать посимулировать "вручную", управляя прерываниями и их флагами. Я попробовал для вашего примера. Если источник прерывания в функции не обрабатывается, то прерывание выполняется 20 тактов (вход в прерывание, переход по таблице и выход). Если обрабатывается (например, запись в регистр UCB0TXBUF), то - 25 тактов. Три источника прерывания - вызывают прерывание три раза. 25*3=75 тактов. Похоже на правду?  P.S. поправка. Ошибся при подсчете, не там брейкпоинт ставил. Обработка прерывания 23 и 28 тактов Причем это при выборе модели памяти Small, когда не используется расширенный набор команд. При выборе модели памяти Large получается уже 26 и 32 такта соответственно, за счет того, что для сохранения/восстановления контекста (регистра R15) используются команды PUSHM.A и POPM.A.
Сообщение отредактировал rezident - Oct 12 2011, 19:45
|
|
|
|
|
Oct 13 2011, 09:50
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Убрал FTDI. В качестве мастера выступил PIC, работающий по спецификации I2C. Скорость HS 1Mbps, менять не могу т.к девайс не мой. см. картинку. Пульсы на втором канале - это пребывание MSP в обработчике прерывания I2C. Прерывания разрешены для пустого буфера передатчика и стоп условия.
DS0001.BMP ( 25.44 килобайт )
Кол-во скачиваний: 3Частота MSP 8Mhz
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|