реклама на сайте
подробности

 
 
> MSP-EXP430F5529, I2C slave transmitter проблема
*rust*
сообщение Oct 5 2011, 15:50
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Добрый день!

Есть борд MSP-EXP430F5529. Запускаю I2C. Среда IAR.
Загрузил пример от TI MSP430F55xx_uscib0_i2c_05, который делает борд ведомым передатчиком и отправляет число по I2C мастеру.
Заметил странность, мастер получает числа как будто деленные на 2. В теле программы создал константу и отправляю ее на передачу, мастером вижу, что число в два раза меньше, к примеру оправляю 0xAA получаю 0x55, отправляю 0хFF получаю 0x7F.
Такое ощущение что сдвиговый регистр отнимает единицу от количества требуемых сдвигов, из-за этого получается деление на два. Читал мануал, код вроде правильный, а непонимание есть.
Что это такое, как это понять и устранить?
Go to the top of the page
 
+Quote Post
3 страниц V  < 1 2 3 >  
Start new topic
Ответов (15 - 29)
*rust*
сообщение Oct 8 2011, 09:53
Сообщение #16


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Частоту тактирования поднял уже до 16МГц, MSP передает корректные данные по I2c только на скорости до 200 kbps, дальше опять сдвиг на один бит. На какой частоте тактирования MSP сможет нормально передавать данные по I2C на скорости 400 kbps, если вообще в частоте дело?
Go to the top of the page
 
+Quote Post
*rust*
сообщение Oct 10 2011, 17:25
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Неужели с такой проблемой никто не сталкивался?
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 10 2011, 19:48
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Дык все-таки, какие по величине резисторы pull-up на шине? И почему вы так боитесь показать всю схему подключения целиком? Ну не верю я что там есть что-то секретное sm.gif
Go to the top of the page
 
+Quote Post
*rust*
сообщение Oct 11 2011, 06:35
Сообщение #19


Частый гость
**

Группа: Участник
Сообщений: 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.
Go to the top of the page
 
+Quote Post
*rust*
сообщение Oct 11 2011, 09:37
Сообщение #20


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Посмотрите на этот скрин (адрес). Поймал граничное состояние, мастер иногда получает нормальную дату, а иногда плохую. Так как FTDI не поддерживает растягивание клоков, то последний бит клока для ASK/NASK, придавлен MSP. MSP пытается снизить скорость для решения внутренних задач.
Прикрепленный файл  DS0000.BMP ( 16.78 килобайт ) Кол-во скачиваний: 10
.
Растягивание приходиться только на половину клока, поэтому, иногда нормально, а иногда нет.
Остается вопрос: Зачем MSP потребовалось притормозить при частоте ядра и периферии в 25МГц?
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 11 2011, 15:05
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(*rust* @ Oct 11 2011, 14:37) *
Остается вопрос: Зачем MSP потребовалось притормозить при частоте ядра и периферии в 25МГц?

А описание бага USCI30 в errata не в тему?
Go to the top of the page
 
+Quote Post
*rust*
сообщение Oct 11 2011, 19:48
Сообщение #22


Частый гость
**

Группа: Участник
Сообщений: 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 загружает байт так долго, при такой то частоте.
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 11 2011, 22:34
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



На вашей осциллограмме присутствует "ступенька", которой быть не должно. Она может свидетельствовать о том, что на шине возникает конфликт при котором помимо (взаимо)действия pull-up и open drain на шину выдается "жесткая" лог.1. Вопрос: откуда? Какой именно пин/выход/устройство создает этот конфликт "жесткой" лог1. и open drain?
Go to the top of the page
 
+Quote Post
*rust*
сообщение Oct 12 2011, 06:10
Сообщение #24


Частый гость
**

Группа: Участник
Сообщений: 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.
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 12 2011, 14:32
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 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)? wacko.gif Дык это явное нарушение спецификации 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.
Go to the top of the page
 
+Quote Post
*rust*
сообщение Oct 12 2011, 17:53
Сообщение #26


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Цитата
Дык это явное нарушение спецификации I2C!

А никто не говорит что FTDI работает по спецификации I2C. Я связывался с изготовителем и прояснял у них этот вопрос. Непонятно другое, что MSP делает так долго??? Тактовая 25МГц, один такт 40нС, скорость I2C - 400кГц, задержка SCL - 3мкС. Что можно делать за 75 тактов????? AVR, С51 с тактовой 8МГц справлялись c I2C(400кГц) легко, работая с той же самой FTDI.
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 12 2011, 19:03
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(*rust* @ Oct 12 2011, 22:53) *
А никто не говорит что FTDI работает по спецификации I2C. Я связывался с изготовителем и прояснял у них этот вопрос.
Тогда непонятно, чего вы тут на MSP430 бочку катите? laughing.gif
Цитата(*rust* @ Oct 12 2011, 22:53) *
Что можно делать за 75 тактов?????

Вход в прерывание - 6 тактов, выход - 5 тактов. В симуляторе IAR есть счетчик циклов. Хотя с симуляцией периферии в IAR полный швах, но можно попробовать посимулировать "вручную", управляя прерываниями и их флагами. Я попробовал для вашего примера. Если источник прерывания в функции не обрабатывается, то прерывание выполняется 20 тактов (вход в прерывание, переход по таблице и выход). Если обрабатывается (например, запись в регистр UCB0TXBUF), то - 25 тактов. Три источника прерывания - вызывают прерывание три раза. 25*3=75 тактов. Похоже на правду? wink.gif
P.S. поправка. Ошибся при подсчете, не там брейкпоинт ставил. Обработка прерывания 23 и 28 тактов Причем это при выборе модели памяти Small, когда не используется расширенный набор команд. При выборе модели памяти Large получается уже 26 и 32 такта соответственно, за счет того, что для сохранения/восстановления контекста (регистра R15) используются команды PUSHM.A и POPM.A.

Сообщение отредактировал rezident - Oct 12 2011, 19:45
Go to the top of the page
 
+Quote Post
*rust*
сообщение Oct 12 2011, 21:10
Сообщение #28


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



rezident, спасибо за подробный ответ и Ваши хлопоты!
Еще раз внимательно прочитав мануал в части I2C, я немного переделал оригинальный пример от TI. Стал загружать байт в TXBUF по входу в прерывание по UCSTTIFG (на самом деле этот бит выставляется когда распознан свой адрес и известно направление чтение\запись) - это помогло. Скорость 400kpbs стала доступна при частоте ядра 16MHz.
В конечном счете макс. частота ядра, в конкретно этом случае, может быть только 8MHz (иначе выхожу за рамки в потреблении), но скорость передачи нормальных данных падает до 200kbps.

Как Вы думаете можно ли при такой частоте 8MHz организовать обмен на 400kbps, и что для этого нужно сделать?
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 13 2011, 09:19
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(*rust* @ Oct 13 2011, 02:10) *
Как Вы думаете можно ли при такой частоте 8MHz организовать обмен на 400kbps, и что для этого нужно сделать?
Нет, не получится. Посчитайте сами. Даже если МК будет обрабатывать только прерывание USCI, то 8МГц/32такта=250кГц. А ведь кроме записи по прерыванию в UCB0TXBUF нужно еще в основной программе данные готовить/подтаскивать/относить к этому конвейеру. Так, что при 8МГц выше 100кГц я бы не рассчитывал.
Go to the top of the page
 
+Quote Post
*rust*
сообщение Oct 13 2011, 09:50
Сообщение #30


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



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


Частота MSP 8Mhz
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 06:38
Рейтинг@Mail.ru


Страница сгенерированна за 0.01587 секунд с 7
ELECTRONIX ©2004-2016