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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> TWI в sam7s
Goofy
сообщение Jan 29 2008, 17:11
Сообщение #1


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

Группа: Свой
Сообщений: 169
Регистрация: 17-09-07
Из: Красноярск
Пользователь №: 30 600



Впервые для себя запускаю TWI на sam7s.

Использована атмеловская lib_twi

Запись
Код
int AT91F_TWI_WriteSingle(const AT91PS_TWI pTwi,
                        int SlaveAddr,
                        char *data)
{
    unsigned int end = 0, status, err=0;

    /* Enable Master Mode */
  //  AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN;

    /* Set the TWI Master Mode Register */
    AT91C_BASE_TWI->TWI_MMR =  (SlaveAddr<<16 ) & ~AT91C_TWI_MREAD;

    /* Write the data to send into THR. Start conditionn DADDR and R/W bit
       are sent automatically */
    AT91C_BASE_TWI->TWI_THR = *data;
    
    AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;

    /* NACK errata handling */
    /* Do not poll the TWI_SR */
    /* Wait 3 x 9 TWCK pulse (max) 2 if IADRR not used, before reading TWI_SR */
    /* From 400Khz down to 1Khz, the time to wait will be in µs range.*/
    /* In this example the TWI period is 1/400KHz */
   AT91F_TWI_WaitMicroSecond (40);

    while (!end)
    {
      status = AT91C_BASE_TWI->TWI_SR;
      if ((status & AT91C_TWI_NACK) == AT91C_TWI_NACK)
      {
        err++;
        end=1;
      }
    /*  Wait for the Transmit ready is set */
      if ((status & AT91C_TWI_TXRDY) == AT91C_TWI_TXRDY)
        end=1;
    }
    AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;
    /* Wait for the Transmit complete is set */
    status = AT91C_BASE_TWI->TWI_SR;
    while (!(status & AT91C_TWI_TXCOMP))
      status = AT91C_BASE_TWI->TWI_SR;

    return err;
}


Инициализация (вызывается для 100кГц)
Код
void AT91F_TWI_Open(int TwiClock)
{
    /* Configure TWI PIOs */
    AT91F_TWI_CfgPIO ();

    /* Configure PMC by enabling TWI clock */
    AT91F_TWI_CfgPMC ();

    /* Reset the TWI */
    AT91C_BASE_TWI->TWI_CR = AT91C_TWI_SWRST;

    
    /* Configure TWI in master mode */
    AT91F_TWI_Configure (AT91C_BASE_TWI);


    /* Set TWI Clock Waveform Generator Register */
  //AT91C_BASE_TWI->TWI_CWGR=0x047575;
    AT91F_SetTwiClock(TwiClock);
}


Расчёт делителей
Код
void AT91F_SetTwiClock(int TwiClock)
{
  unsigned int cldiv,ckdiv=1;

  /* CLDIV = ((Tlow x 2^CKDIV) -3) x Tmck */
  /* CHDIV = ((THigh x 2^CKDIV) -3) x Tmck */
  /* Only CLDIV is computed since CLDIV = CHDIV (50% duty cycle) */
          cldiv = ( (MCK/(2*TwiClock))-3 ) / pow(2,ckdiv);
  while (  cldiv> 255 )
  {
   ckdiv++;
   cldiv = ( (MCK/(2*TwiClock))-3 ) / pow(2,ckdiv);

  }
  AT91C_BASE_TWI->TWI_CWGR =(ckdiv<<16)|((unsigned int)cldiv << 8)|(unsigned int)cldiv;
}



Проблема в том, что процедура передачи просто виснит, очевидно не получая из статус регистра TXRDY. TWI инициализирован приведённой выше процедурой.
Я не ошибаюсь, считая, что "железные" проблемы никак не влияют на работу модуля внутри?
Пока не идёт речи о корректности передачи, лишь о факте того, что статус регистр не ведёт себя должным образом.
Есть ли вероятность что модуль битый напрочь?
Go to the top of the page
 
+Quote Post
Хомяк
сообщение Jan 30 2008, 04:06
Сообщение #2


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

Группа: Свой
Сообщений: 99
Регистрация: 12-02-07
Из: Свердловск
Пользователь №: 25 269



Запускал TWI на AT91SAM7A3 проблем не было.
Но у меня функция AT91F_SetTwiClock() маленько по другому была.
И еще что цепляется на шину?
Резисторы подтягивающие стоят?

Сообщение отредактировал Хомяк - Jan 30 2008, 04:08
Go to the top of the page
 
+Quote Post
Goofy
сообщение Jan 30 2008, 05:27
Сообщение #3


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

Группа: Свой
Сообщений: 169
Регистрация: 17-09-07
Из: Красноярск
Пользователь №: 30 600



Цитата(Хомяк @ Jan 30 2008, 11:06) *
Запускал TWI на AT91SAM7A3 проблем не было.
Но у меня функция AT91F_SetTwiClock() маленько по другому была.
И еще что цепляется на шину?
Резисторы подтягивающие стоят?


Эту функцию я правил чуть чуть, думал, мало ли...

Подтяжка стоит. Только влияет ли это на процесс обновления регистров самого TWI ?
Go to the top of the page
 
+Quote Post
gladov
сообщение Jan 30 2008, 10:49
Сообщение #4


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

Группа: Свой
Сообщений: 169
Регистрация: 10-11-05
Из: Воронеж
Пользователь №: 10 687



Сразу бросается в глаза, что Вы делаете при передаче принудительно START|STOP. По DS на at91Sam7X от октября 2007г., этого делать не надо. А может быть и нельзя. Я тоже долго мучил TWI и столкнулся с проблемой - если при передаче принудительно дернуть START, то последующая операция чтения глючит. Ни старт, ни стоп при передаче не надо включать.

Цитата(Goofy @ Jan 30 2008, 08:27) *
Эту функцию я правил чуть чуть, думал, мало ли...

Подтяжка стоит. Только влияет ли это на процесс обновления регистров самого TWI ?


Влияет. Встречал реализацию (не помню в каком камне), когда аппаратный i2c сильно глючил без подтяжки.
Go to the top of the page
 
+Quote Post
Goofy
сообщение Jan 30 2008, 11:20
Сообщение #5


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

Группа: Свой
Сообщений: 169
Регистрация: 17-09-07
Из: Красноярск
Пользователь №: 30 600



Цитата(gladov @ Jan 30 2008, 17:49) *
Сразу бросается в глаза, что Вы делаете при передаче принудительно START|STOP. По DS на at91Sam7X от октября 2007г., этого делать не надо. А может быть и нельзя. Я тоже долго мучил TWI и столкнулся с проблемой - если при передаче принудительно дернуть START, то последующая операция чтения глючит. Ни старт, ни стоп при передаче не надо включать.
Влияет. Встречал реализацию (не помню в каком камне), когда аппаратный i2c сильно глючил без подтяжки.


Принудительный старт выставил ради эксперимента. Убрал обратно. Дело в том, что SCL SDA линии красоты ради были подключены через MAX3002 чтобы синхронизировать уровни с 5В, что собственно не диктуется необходимостью (выводы sam7s к 5в терпимы, подтяжка внешняя, 100К припаял для начала). Ради уменьшения глючности отрезал дорожки от MAX3002, соеденил с 5В частью шины напрямую. При инициализации выходит что ключи на ножках sam7s256 открыты, на шине нулевой уровень. Цикл так же виснит. crying.gif

Сообщение отредактировал Goofy - Jan 30 2008, 11:23
Go to the top of the page
 
+Quote Post
gladov
сообщение Jan 30 2008, 12:44
Сообщение #6


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

Группа: Свой
Сообщений: 169
Регистрация: 10-11-05
Из: Воронеж
Пользователь №: 10 687



Цитата(Goofy @ Jan 30 2008, 14:20) *
Принудительный старт выставил ради эксперимента. Убрал обратно. Дело в том, что SCL SDA линии красоты ради были подключены через MAX3002 чтобы синхронизировать уровни с 5В, что собственно не диктуется необходимостью (выводы sam7s к 5в терпимы, подтяжка внешняя, 100К припаял для начала). Ради уменьшения глючности отрезал дорожки от MAX3002, соеденил с 5В частью шины напрямую. При инициализации выходит что ключи на ножках sam7s256 открыты, на шине нулевой уровень. Цикл так же виснит. crying.gif


А 100К не много? Рекомендуют от 5 до 10 ставить. А почему бы не попробовать остановить цикл во время висяка и не посмотреть что лежит в TWI_SR?
Go to the top of the page
 
+Quote Post
Goofy
сообщение Jan 30 2008, 12:52
Сообщение #7


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

Группа: Свой
Сообщений: 169
Регистрация: 17-09-07
Из: Красноярск
Пользователь №: 30 600



Цитата(gladov @ Jan 30 2008, 19:44) *
А 100К не много? Рекомендуют от 5 до 10 ставить. А почему бы не попробовать остановить цикл во время висяка и не посмотреть что лежит в TWI_SR?


Обстановка изменилась.
Для sam7s обязательным судя по всему является

AT91C_BASE_PIOA->PIO_MDER=AT91C_PA4_TWCK|AT91C_PA3_TWD;

Резисторы переставил на 10к. Однако верхний уровень сигнала явно не 5 вольт. Зависание прекратилось когда на шину подцепил приёмное устройство. Попытка заглянуть в сигнал осцилографом (25рF, TWI инициализируется под частоту 50гц) снова вешает цикл и ничего не наблюдается. Будем разбираться ...

Сообщение отредактировал Goofy - Jan 30 2008, 12:54
Go to the top of the page
 
+Quote Post
Хомяк
сообщение Jan 30 2008, 13:16
Сообщение #8


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

Группа: Свой
Сообщений: 99
Регистрация: 12-02-07
Из: Свердловск
Пользователь №: 25 269



Я на TWI вешал 24LC256
подтягивал 2к

Привожу свой код
Кварц 16МГц работал на частоте квалца , без ФАПЧ

Код
//==============================================================================
//  Функция             : AT91F_SetTwiClock
//  Описание            :
//  входные параметры   :
//  выходные параметры  :
//==============================================================================
void AT91F_SetTwiClock(void)
{
  int sclock;

  /* Here, CKDIV = 1 and CHDIV=CLDIV  ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6)*/

  sclock = (10*MCK /AT91C_TWI_CLOCK);
  if (sclock % 10 >= 5)
      sclock = (sclock /10) - 5;
  else
      sclock = (sclock /10)- 6;
  sclock = (sclock + (4 - sclock %4)) >> 2;    // div 4

  AT91C_BASE_TWI->TWI_CWGR    = ( 1<<16 ) | (sclock << 8) | sclock;
}
//==============================================================================
//  Функция             : AT91F_TWI_Open
//  Описание            :
//  входные параметры   :
//  выходные параметры  :
//==============================================================================
void AT91F_TWI_Open(void)
{
  AT91F_TWI_CfgPIO();                     // configure TWI PIOs
  AT91F_TWI_CfgPMC();                     // enable clock TWI
  AT91F_TWI_Configure (AT91C_BASE_TWI);   // configure in MASTER mode
  AT91F_SetTwiClock();
}
//==============================================================================
//  Функция             : AT91F_TWI_WriteByte
//  Описание            :
//  входные параметры   :
//  выходные параметры  :
//==============================================================================
int AT91F_TWI_WriteByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data2send, int nb)
{
  unsigned int status,counter=0,error=0;

  // Set TWI Internal Address Register
  if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;

  // Set the TWI Master Mode Register
  pTwi->TWI_MMR = mode & ~AT91C_TWI_MREAD;
  if(nb <2)
  {
    pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN | AT91C_TWI_STOP;
    pTwi->TWI_THR = *data2send;
  }
  else
  {
    // Set the TWI Master Mode Register
    for(counter=0;counter<nb;counter++)
    {
      pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
      if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
      status = pTwi->TWI_SR;
      if ((status & ERROR) == ERROR) error++;
      while (!(status & AT91C_TWI_TXRDY))
      {
        status = pTwi->TWI_SR;
        if ((status & ERROR) == ERROR) error++;
      }
      pTwi->TWI_THR = *(data2send+counter);
   }
  }
  status = pTwi->TWI_SR;
  if ((status & ERROR) == ERROR) error++;
  while (!(status & AT91C_TWI_TXCOMP))
  {
    status = pTwi->TWI_SR;
    if ((status & ERROR) == ERROR) error++;
  }
  return error;
}
//==============================================================================
//  Функция             : AT91F_TWI_ReadByte
//  Описание            :
//  входные параметры   :
//  выходные параметры  :
//==============================================================================
int AT91F_TWI_ReadByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data, int nb)
{
  unsigned int status,counter=0,error=0;

  // Set TWI Internal Address Register
  if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;

  // Set the TWI Master Mode Register
  pTwi->TWI_MMR = mode | AT91C_TWI_MREAD;

  // Start transfer
  if (nb == 1)
  {
    pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
    status = pTwi->TWI_SR;
    if ((status & ERROR) == ERROR) error++;
    while (!(status & AT91C_TWI_TXCOMP))
    {
      status = pTwi->TWI_SR;
      if ((status & ERROR) == ERROR) error++;
    }
    *(data) = pTwi->TWI_RHR;
   }
   else
   {
     pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
     status = pTwi->TWI_SR;
     if ((status & ERROR) == ERROR) error++;

     // Wait transfer is finished
     while (!(status & AT91C_TWI_TXCOMP))
     {
       status = pTwi->TWI_SR;
       if ((status & ERROR )== ERROR) error++;
        if(status & AT91C_TWI_RXRDY)
        {
      *(data+counter++) = pTwi->TWI_RHR;
      if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
    }
     }
   }
   return 0;
}
//==============================================================================
//  Функция             :
//  Описание            :
//  входные параметры   :
//  выходные параметры  :
//==============================================================================
void TWI_ReadByte(const AT91PS_TWI pTwi ,int mode, char *data, int nb)
{
  unsigned int status,counter=0;
  // Set TWI Internal Address Register
  // without internal address ??????
  //if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;

  // Set the TWI Master Mode Register
  // Use MS 7 bits as mode ??????
  pTwi->TWI_MMR = mode | AT91C_TWI_MREAD;

  // Start transfer
  if (nb == 1)
  {
    pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
    status = pTwi->TWI_SR;
    //if ((status & ERROR) == ERROR) error++;
    while (!(status & AT91C_TWI_TXCOMP));
    *(data) = pTwi->TWI_RHR;
  }
  else
  {
    pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
    status = pTwi->TWI_SR;
    // Wait transfer is finished
    while (!(status & AT91C_TWI_TXCOMP))
    {
      AT91F_DBGU_Printk("\n\rTEST_AT91F_TWI_ReadByte_1");
      if(status & AT91C_TWI_RXRDY)
      {
         *(data+counter++) = pTwi->TWI_RHR;
         AT91F_DBGU_Printk("\n\rTEST_AT91F_TWI_ReadByte_2");
         if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
         //AT91F_DBGU_Printk("\n\rTEST_AT91F_TWI_ReadByte_3");
      }
    }
  }
}


Сообщение отредактировал Хомяк - Jan 30 2008, 13:18
Go to the top of the page
 
+Quote Post
Goofy
сообщение Feb 1 2008, 05:03
Сообщение #9


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

Группа: Свой
Сообщений: 169
Регистрация: 17-09-07
Из: Красноярск
Пользователь №: 30 600



Проблема решилась.
При отсутствии устройства на шине по запрашиваемому адресу, цикл виснит. Буду вводить таймауты.
Go to the top of the page
 
+Quote Post
Ruslan1
сообщение Feb 4 2008, 18:30
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025



Цитата(Goofy @ Feb 1 2008, 07:03) *
Проблема решилась.
При отсутствии устройства на шине по запрашиваемому адресу, цикл виснит. Буду вводить таймауты.

Какое-то время назад тут уже подымалась тема TWI. Тема для меня больная, но повторяться не буду, только выводы:

Хотите иметь надежное устройство- делайте софтовый TWI. Чтобы Ваше устройство работало так, как хотите Вы и не зависало от каждой иголки на шине.

Подчеркну, это мой личный выстраданный опыт, никому свое мнение навязывать не буду.
Причем это я на других АРМах грыз (AT91RM9200). Но "чуйствую", что уши у проблемы те же.
Go to the top of the page
 
+Quote Post
Terrabyte
сообщение Feb 7 2008, 11:09
Сообщение #11


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

Группа: Свой
Сообщений: 124
Регистрация: 2-01-07
Из: Russia
Пользователь №: 24 042



всё будет хорошо господа! читайте документ:
http://electronix.ru/forum/index.php?act=A...st&id=16553
Go to the top of the page
 
+Quote Post
cebotor
сообщение Feb 7 2008, 11:58
Сообщение #12


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

Группа: Свой
Сообщений: 135
Регистрация: 6-04-07
Из: Бронницы
Пользователь №: 26 809



Цитата(gladov @ Jan 30 2008, 13:49) *
Влияет. Встречал реализацию (не помню в каком камне), когда аппаратный i2c сильно глючил без подтяжки.

а не в процессорах ли ST ?
в подтверждение могу сказать что на STM32 при инициализации TWI в случае неправильной подтяжки
мастер встает в такое кривое состояние что потом никогда не может сгенерировать start condition


--------------------
если еррата пуста - это не хорошо а плохо
Go to the top of the page
 
+Quote Post
pan_oleg
сообщение Apr 4 2008, 11:40
Сообщение #13


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

Группа: Участник
Сообщений: 76
Регистрация: 16-11-07
Пользователь №: 32 387



вот у меня такая ситуация, на STM32 не может сгенерировать start,
подтяжка 5 к, на шине еепромка, виснет только при чтении из еепромки,
что поменять с подтяжкой?
Go to the top of the page
 
+Quote Post
singlskv
сообщение Apr 6 2008, 21:27
Сообщение #14


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Terrabyte @ Feb 7 2008, 15:09) *
всё будет хорошо господа! читайте документ:
http://electronix.ru/forum/index.php?act=A...st&id=16553
Terrabyte а может быть Вы сможете подитожить инфу по работе i2c ?
и выложить ее на всеобщее обозрение в виде FAQ ?
Готов выдать Вам еще несколько мыслей, но хотелось бы на выходе получить готовую
апликайшен про то как нужно пользоваться i2c на samxxxxx....
Сам буду ей пользоваться..... smile.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 7 2008, 05:02
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



ИМХО, TWI на SAM7 все же неработоспособен. У меня есть несколько "почти работающих" вариантов, но все они благополучно сыпятся на попытке общения с SAA7113. Софтверный во сто крат лучше, поверьте smile.gif
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 Текстовая версия Сейчас: 18th July 2025 - 18:24
Рейтинг@Mail.ru


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