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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> SAM3U и I2C, как slave работает не правильно.
singlskv
сообщение Sep 8 2011, 17:07
Сообщение #16


дятел
*****

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



Цитата(aaarrr @ Jun 11 2011, 16:39) *
Они практически в полном составе унаследованы от SAM7, разве что убрали наиболее одиозные глюки и добавили PDC. Идеология, однако, осталась прежней: мастер синхронного интерфейса у них может вылететь в overrun/underrun.

Мое общение с TWI на SAM3 закончилось довольно быстро. Сдуру был написан честный драйвер с PDC и прерываниями, однако на тестировании выяснилось, что из 10 слейвов в составе устройства отзываются 8. Два AD9887 принципиально не дают ACK после адреса.
Памятуя безблагодатные пляски с бубном при аналогичных симптомах на SAM7, не стал даже разбираться в причинах сего явления и просто откатился на bit-band.
Если не сложно, покажите запуск PDC для I2C,
не могу понять как его стартовать в различных вариантах:
-запись от мастера слейву
-чтение от слейва
ну или полный драйвер запостите с PDC
если запостите полный драйвер, обещаю опубликовать свое решение, если конечно выгорит...,
ну и как бонус могу опубликовать решение для SAM7.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 8 2011, 17:45
Сообщение #17


Гуру
******

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



Цитата(singlskv @ Sep 8 2011, 21:07) *
ну или полный драйвер запостите с PDC

Держите. Но только совершенный as is, никаких комментариев не будет - наелся я уже атмеловского TWI и слышать о нем больше не хочу.
Прикрепленный файл  iic.rar ( 1.32 килобайт ) Кол-во скачиваний: 114
Go to the top of the page
 
+Quote Post
singlskv
сообщение Sep 8 2011, 18:08
Сообщение #18


дятел
*****

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



[/quote name='aaarrr' date='Sep 8 2011, 21:45' post='970432']
Держите. Но только совершенный as is, никаких комментариев не будет - наелся я уже атмеловского TWI и слышать о нем больше не хочу.
Прикрепленный файл  iic.rar ( 1.32 килобайт ) Кол-во скачиваний: 114

[/quote]
CODE

//------------------------------------------------------------------------------
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
драйвера у мну нет как такового нет,
но кто в теме поймет...
если стер что лишнее, телеграфируйте...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 15:18
Рейтинг@Mail.ru


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