|
SAM3U и I2C, как slave работает не правильно. |
|
|
|
Jun 1 2011, 11:33
|
Частый гость
 
Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335

|
Добрый день! Пытаюсь реализовать I2S на SAM3U, причем проц. должен работать как slave. Прежде всего хочу отметить что в описании на slave mode есть ошибки. 1.Бит SVREAD регистра TWI_SR говорит об направлении (прием\передача). лог.1-чтение мастером, лог 0-запись мастером, что вытекает из описания битов регистра TWI_SR(стр.656). На рисунке 33-32, стр. 661. наоборот. 2. Бит RXRDY регистра TWI_SR говорит о состоянии приемника. лог 1- был принят байт в регистр приемника TWI_RHR, после последнего чтения, лог 0- не был принят байт в регистр приемника TWI_RHR, после последнего чтения. На рисунке 33-32, стр. 661. опять же наоборот. Но ошибки это не главное, чудеса начинаются после запуска. После того как был принят свой адрес, направление передачи "R"-чтение, sam3u посылает ASK-это нормально, и я должен положить байт в регистр передачи TWI_THR. Я так и делаю, но в зависимости от значения байта, мой SAM3U(slave) либо отпускает линию SDA или нет - а вот это уже странно. Как вообще slave может удерживать линию SDA? Судите сами. (адрес slave -10) 1 картинка- после ASKа загружаю 0xFF. sam3u отпускает шину SDA - нормально. Далее мастер формирует ПОВСТАРТ и СТОП-условие
receive_FF.bmp ( 19 килобайт )
Кол-во скачиваний: 172 картинка- после ASKа загружаю 0x01. sam3u не отпускает шину SDA- не понятно. Далее мастер пытается сформировать СТОП, но Sam3u пытается удерживать линию SDA в нуле.
receive_01_first.bmp ( 18.54 килобайт )
Кол-во скачиваний: 143 картинка для информации, что происходит после 2 картинки, когда линия SDA в каком-то непонятном состоянии.
receive_01_second.bmp ( 18.51 килобайт )
Кол-во скачиваний: 8А теперь главный вопрос, кто виноват и что делать? Я готов написать в ATMEL, но хотелось бы услышать, мнения форумчан. Может где-то мой косяк зарыт? Код перекраивал много раз, итог один.
|
|
|
|
|
 |
Ответов
|
Sep 8 2011, 17:07
|
дятел
    
Группа: Свой
Сообщений: 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.
|
|
|
|
|
Sep 8 2011, 18:08
|
дятел
    
Группа: Свой
Сообщений: 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 драйвера у мну нет как такового нет, но кто в теме поймет... если стер что лишнее, телеграфируйте...
|
|
|
|
Сообщений в этой теме
*rust* SAM3U и I2C Jun 1 2011, 11:33   sonycman Цитата(aaarrr @ Jun 11 2011, 16:39) Они п... Jun 11 2011, 14:07    aaarrr Цитата(sonycman @ Jun 11 2011, 18:07) Пос... Jun 11 2011, 14:24     sonycman Цитата(aaarrr @ Jun 11 2011, 18:24) Вот у... Jun 13 2011, 13:04      aaarrr Цитата(sonycman @ Jun 13 2011, 17:04) Ну ... Jun 13 2011, 21:01 BurglarInt Цитата(*rust* @ Jun 1 2011, 15:33)
*rus... Jun 1 2011, 12:04 *rust* stan@ngfp.ru
ЦитатаПро атмеловский TWI ничего хор... Jun 1 2011, 12:24 aaarrr Цитата(*rust* @ Jun 1 2011, 16:24) Slave ... Jun 1 2011, 12:36 BurglarInt *rust*, письмо на твой e-mail я отправил, спасибо. Jun 1 2011, 12:26 *rust* У FTDI232 100 процентов не I2C, многое не по специ... Jun 1 2011, 12:43 SergeyDDD По идеологии I2C, таких ступенек как у Вас принцип... Jun 11 2011, 14:02 *rust* Привожу мою переписку с тех. службой ATMEL, хотя о... Jun 23 2011, 12:53
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|