Перейти к содержанию
    

Они практически в полном составе унаследованы от SAM7, разве что убрали наиболее одиозные глюки и добавили PDC. Идеология, однако, осталась прежней: мастер синхронного интерфейса у них может вылететь в overrun/underrun.

 

Мое общение с TWI на SAM3 закончилось довольно быстро. Сдуру был написан честный драйвер с PDC и прерываниями, однако на тестировании выяснилось, что из 10 слейвов в составе устройства отзываются 8. Два AD9887 принципиально не дают ACK после адреса.

Памятуя безблагодатные пляски с бубном при аналогичных симптомах на SAM7, не стал даже разбираться в причинах сего явления и просто откатился на bit-band.

Если не сложно, покажите запуск PDC для I2C,

не могу понять как его стартовать в различных вариантах:

-запись от мастера слейву

-чтение от слейва

ну или полный драйвер запостите с PDC

если запостите полный драйвер, обещаю опубликовать свое решение, если конечно выгорит...,

ну и как бонус могу опубликовать решение для SAM7.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну или полный драйвер запостите с PDC

Держите. Но только совершенный as is, никаких комментариев не будет - наелся я уже атмеловского TWI и слышать о нем больше не хочу.

iic.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

[/quote name=aaarrr' date='Sep 8 2011, 21:45' post='970432]

Держите. Но только совершенный as is, никаких комментариев не будет - наелся я уже атмеловского TWI и слышать о нем больше не хочу.

iic.rar

//------------------------------------------------------------------------------
static void I2cISR(void) __attribute__ ((interrupt ("IRQ")));

// I2C
#define I2C_SEND_BUFF_LENGTH     2
#define I2C_RECV_BUFF_LENGTH     8
#define I2C_MEGA_ADDR         0xB2  // адрес меги на шине i2c

enum
{
 I2C_STATE_FREE = 0,
 I2C_STATE_SEND,
 I2C_STATE_RECEIVE,
 I2C_STATE_RECEIVED
};

//------------------------------------------------------------------------------
//  DWORD I2cSetSpeed(DWORD baud)
//  Установка скорости уарта
//  Input:
//    baud     -  скорость i2c
//  Output: реальная скорость уарта
//----
DWORD I2cSetSpeed(DWORD baud)
{
 int div, ckdiv, chdiv, cldiv;

 div = MCK_FREQUENCY / baud;
 div -= 6; // const 
 ckdiv = 0;
 while (div > 510)
 {
   ckdiv++;
   if (ckdiv >= 8) return 0;
   div >>= 1;
 }
 chdiv = div >> 1;
 cldiv = div - chdiv;

 TWI_IDR = 0xFFFFFFFF;
 AIC_ICCR = (1 << TWI_ID);
 TWI_CR = TWI_CR_SWRST;
 TWI_CR = TWI_CR_MSEN;
 TWI_CWGR = (ckdiv << 16) | (chdiv << 8) | cldiv;

 return baud;
}

typedef struct
{
 DWORD State;
 DWORD Index;
 DWORD MessageLength;
 BYTE OutBuff[i2C_SEND_BUFF_LENGTH];
 BYTE InBuff[i2C_RECV_BUFF_LENGTH];
} Mega;

Mega mega;


BYTE Do_ticks;
DWORD Do_state;

DWORD Di_time;
DWORD Di_cnt[6];

WORD DiLastFiltrWidth[5];  // размер окна фильтрации
WORD DiFiltrCounter[5];    // счетчик фильтра

DWORD SecondCounter;

void SysTimerHandler()
{
 DWORD tmp, i, bit;
 static DWORD StateTimeout;

 if (++SecondCounter >= 1000)
 {
   SecondCounter = 0;
   base.WorkingTime++;
   TimeFromStart++;
 }

..................

 if (mega.State != I2C_STATE_RECEIVED) StateTimeout++;
 else                                  StateTimeout = 0;
 if (StateTimeout >= 2)
 {
   StateTimeout = 0;

   TWI_IDR = 0xFFFFFFFF;
   TWI_CR = TWI_CR_MSDIS;
   PMC_PCDR = (1 << TWI_ID);

   PIOA_PER = BIT1;
   PIOA_OER = BIT1;

   for (i = 0; i < 9; i++)
   {
     PIOA_SODR = BIT1;
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");
     PIOA_CODR = BIT1;
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");asm("nop");asm("nop");asm("nop");
     asm("nop");
   }
   PIOA_SODR = BIT1;
   PIOA_ODR = BIT1;
   PIOA_PDR = BIT1;

   PMC_PCER = (1 << TWI_ID);
   I2cSetSpeed(140000);
   mega.State = I2C_STATE_FREE;
 }

 switch (mega.State)
 {
   case I2C_STATE_RECEIVED:
............
       TWI_MMR = ((I2C_MEGA_ADDR >> 1) << 16);
       TWI_THR = mega.OutBuff[0];
       TWI_CR = TWI_CR_STOP;
       TWI_IER = TWI_IER_TXRDY | TWI_IER_TXCOMP;
       break;
     }

   case I2C_STATE_FREE:
     if (mega.State == I2C_STATE_FREE) DI &= ~BIT7;  // нет связи с мегой

     mega.State = I2C_STATE_SEND;
     mega.Index = 0;
...........

     TWI_MMR = ((I2C_MEGA_ADDR >> 1) << 16);
     TWI_THR = mega.OutBuff[0];
     TWI_CR = TWI_CR_STOP;
     TWI_IER = TWI_IER_TXRDY | TWI_IER_TXCOMP;
     break;
 }

...........................
}

//------------------------------------------------------------------------------
//  static void I2cISR(void)
//  Обработчик прерывания I2C
//----
static void I2cISR(void)
{
 DWORD sr;
 AIC_IVR = 0;
 sr = TWI_SR;

 if (mega.State == I2C_STATE_SEND)
 {
   if (sr & TWI_SR_TXRDY)
   {
     mega.Index++;
     TWI_THR = mega.OutBuff[1];
     TWI_IDR = 0xFFFFFFFF;
     TWI_IER = TWI_IER_TXCOMP;
   }
   if (sr & TWI_SR_TXCOMP)
   {
     if ((sr & TWI_SR_NACK) || (mega.Index == 0))
     {
       TWI_IDR = 0xFFFFFFFF;
       mega.State = I2C_STATE_FREE;
     }
     else
     {
       mega.State = I2C_STATE_RECEIVE;
       mega.MessageLength = I2C_RECV_BUFF_LENGTH;
       mega.Index = 0;
       TWI_MMR = ((I2C_MEGA_ADDR >> 1) << 16) | TWI_MMR_MREAD;
       TWI_RHR;
       TWI_CR = TWI_CR_START;
       TWI_IDR = 0xFFFFFFFF;
       TWI_IER = TWI_IER_TXCOMP | TWI_IER_RXRDY;
     }
   }
 }
 else if (mega.State == I2C_STATE_RECEIVE)
 {
   if (sr & TWI_SR_RXRDY)
   {
     mega.InBuff[mega.Index] = TWI_RHR;
     mega.Index++;
     if (mega.Index == (I2C_RECV_BUFF_LENGTH - 1))
     {
       TWI_CR = TWI_CR_STOP;
     }
     else if (mega.Index == I2C_RECV_BUFF_LENGTH)
     {
       TWI_IDR = 0xFFFFFFFF;
       mega.State = I2C_STATE_RECEIVED;
     }
   }
   else if (sr & TWI_SR_TXCOMP)
   {
     TWI_IDR = 0xFFFFFFFF;
     mega.State = I2C_STATE_RECEIVED;
   }
 }
 else
 {
   TWI_IDR = 0xFFFFFFFF;
   mega.State = I2C_STATE_FREE;
   TWI_RHR;
 }

 AIC_EOICR = 0;
}

вот как и обещал, пример для SAM7

драйвера у мну нет как такового нет,

но кто в теме поймет...

если стер что лишнее, телеграфируйте...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...