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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> SAM7 + Mega8 и I2C
beer_warrior
сообщение Mar 10 2007, 17:35
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Работаю со связкой - SAM7 + Mega8. SAM7 пишет управляющий байт и читает байт статуса.
И вот интересная картина получается. Поставил как возврат статуса константу 0x55.
1. После включения питания первое чтение 0x55, второе 0xFF, все последующие - 0x55.
2. После записи первое чтение 0xFF, все последующие - 0x55.

На код грешить боюсь - для связки мега-мега обкатан многократно. SAM7 без особых проблем работает с 24с02 на той же шине.

Мне кажется допускаю какую-то логическую неувязку в работе с шиной.(Не закрываю обмен или что-то подобное)


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Mar 10 2007, 18:07
Сообщение #2


дятел
*****

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



Цитата(beer_warrior @ Mar 10 2007, 17:35) *
Работаю со связкой - SAM7 + Mega8. SAM7 пишет управляющий байт и читает байт статуса.
И вот интересная картина получается. Поставил как возврат статуса константу 0x55.
1. После включения питания первое чтение 0x55, второе 0xFF, все последующие - 0x55.
2. После записи первое чтение 0xFF, все последующие - 0x55.

На код грешить боюсь - для связки мега-мега обкатан многократно. SAM7 без особых проблем работает с 24с02 на той же шине.

Мне кажется допускаю какую-то логическую неувязку в работе с шиной.(Не закрываю обмен или что-то подобное)


а работа на SAM7 и на mega8 по прерываниям ?
окончание обмена по NOT ACK или просто STOP от мастера ?
обмен каждый раз по 1 байту ?

P.S. Разбираюсь с той же связкой, так что то же очень интересует тема.
Если приведете куски кода и на SAM и на МЕГА может разберемся вместе.
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Mar 10 2007, 19:09
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



SAM работает поллингом, проще некуда:
Код
bool ReadByteI2C(BYTE addr, BYTE* data)
{
//set device adr
AT91C_BASE_TWI->TWI_MMR = (addr << 16)| AT91C_TWI_MREAD;    
//start
TWI_START();//macros
//write data
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_RXRDY));            
*data = AT91C_BASE_TWI->TWI_RHR;
//stop
TWI_STOP();//macros    
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP));
return true;
}

bool WriteByteI2C(BYTE addr, BYTE data)
{
//set device adr
AT91C_BASE_TWI->TWI_MMR = (addr << 16);
AT91C_BASE_TWI->TWI_THR = data;
//start
TWI_START();//macros
//write data
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXRDY));            
//stop
TWI_STOP();//macros
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP));
return true;
}


bool - потому что предполагается добавить обработку статуса транзакции.


Мега живет на прерывании
привожу только имеющее отношение к делу:

Код
SIGNAL(SIG_2WIRE_SERIAL)
{
//TEST0_ON();
TWCB.sta = TWSR & 0xf8;
switch(TWCB.sta)
    {
//SLAVE    RECEIVE

        case TWS_SLAW_ACK:
            //SLAVE device has been addressed by SLAW
            {
            TWCR = TW_EXE_ACK;    //generate ACK
            break;
            }
        case TWS_DATAR_ACK_SLAW:
            //SLAVE has been got a byte, ACK will generated
            {
            //TEST1_ON();
            data = TWDR;
            TWCR = TW_EXE_ACK;    //switch to adressed mode
            break;
            }
        case TWS_STOP:
            //stop condition has been detected
            {
            TWCR = TW_EXE_ACK;    //& generate ACK
            break;
            }
//SLAVE TRANSMIT
        case TWS_SLAR_ACK:
            //SLAVE device has been addressed by SLAR
            {
            TWDR = 0x55;
            TWCR = TW_EXE_NACK;    //generate NACK
            break;
            }
        case TWS_DATAW_ACK:
            //SLAVE has been transmit a byte and got ACK
            //SLAVE transmit next byte
            {
            break;
            }
        case TWS_DATAW_NACK:
            //SLAVE has been transmit a byte and got NACK
            //end of transmision
            {
            TWCR = TW_EXE_ACK;    //switch to adressed mode
            break;
            }
        }
    }//switch
}
//
//
//
//TW commands
#define    TW_EXE_STA    (1<<TWINT)|(1<<TWIE)|(1<<TWEN)|(1<<TWSTA)    //make start condition
#define    TW_EXE_STO    (1<<TWINT)|(1<<TWIE)|(1<<TWEN)|(1<<TWSTO)    //make stop condition
#define    TW_EXE_ACK    (1<<TWINT)|(1<<TWIE)|(1<<TWEN)|(1<<TWEA)    //transmit byte and wait ACK
#define    TW_EXE_NACK    (1<<TWINT)|(1<<TWIE)|(1<<TWEN)                //transmit byte and wait NACK




//SLAVE RECEIVER
#define TWS_SLAW_ACK        0x60
#define TWS_ARB_LOST_SLAW    0x68
#define TWS_GEN_CALL        0x70
#define TWS_ARB_LOST_GC        0x78
#define TWS_DATAR_ACK_SLAW    0x80
#define TWS_DATAR_NACK_SLAW    0x88
#define TWS_DATAR_ACK_GC    0x90
#define TWS_DATAR_NACK_GC    0x98
#define TWS_STOP            0xa0

//SLAVE TRANSMITTER
#define TWS_SLAR_ACK        0xa8
#define TWS_ARB_LOST_SLAR    0xb0
#define TWS_DATAW_ACK        0xb8
#define TWS_DATAW_NACK        0xc0
#define TWS_DATA_LAST        0xc8


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Mar 10 2007, 19:40
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Еще интересный эффект всплыл. Попробовал в промежутках обращаться к EEPROM. Получается что после операции записи все равно куда - первое чтение битое. Но если писать в Мегу и делать сначала чтение из памяти, а потом из меги - все пучком. Последовательная запись и чтение из памяти - без проблем.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Mar 10 2007, 20:02
Сообщение #5


дятел
*****

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



Цитата(beer_warrior @ Mar 10 2007, 19:40) *
Еще интересный эффект всплыл. Попробовал в промежутках обращаться к EEPROM. Получается что после операции записи все равно куда - первое чтение битое. Но если писать в Мегу и делать сначала чтение из памяти, а потом из меги - все пучком. Последовательная запись и чтение из памяти - без проблем.

Покажите инициализацию на SAM

Правильно ли я понял что у Вас обмен всегда по 1 байту ?
и с EEPROM тоже ?
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Mar 10 2007, 20:14
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Код
//--------------------------------------------------------------------------
void InitI2C(void)
{
//device on
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC,(1 << AT91C_ID_TWI));
//enable device
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_SWRST;
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN;
//clock config
AT91C_BASE_TWI->TWI_CWGR =    ((0x22 << 0)    |    //clk_lo
                            (0x22 << 8)    |    //clk_hi
                            (3 << 16));
}
//--------------------------------------------------------------------------



Вроде нашел зацепку. После изменения константы старая была прочитана еще раз, а потом пошла новая. Т.е. похоже нелады с THR/RHR, что-то там в эррате было на эту тему - сейчас сяду читать.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Mar 10 2007, 20:28
Сообщение #7


дятел
*****

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



для начала попробуйте вот так:
Цитата(beer_warrior @ Mar 10 2007, 20:14) *
Код
//--------------------------------------------------------------------------
void InitI2C(void)
{
//device on
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC,(1 << AT91C_ID_TWI));
//enable device
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_SWRST;
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN;
TWI_RHR; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//clock config
AT91C_BASE_TWI->TWI_CWGR =    ((0x22 << 0)    |    //clk_lo
                            (0x22 << 8)    |    //clk_hi
                            (3 << 16));
}
//--------------------------------------------------------------------------


Но это только для начала.......
даже если заработает!!!
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Mar 10 2007, 20:35
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
TWI_RHR; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Не понял смысла.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Mar 10 2007, 21:26
Сообщение #9


дятел
*****

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



Цитата(beer_warrior @ Mar 10 2007, 20:35) *
Цитата
TWI_RHR; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Не понял смысла.

Читаем мусор который с очень большой вероятностью возникнет в TWI_RHR
после выставления AT91C_TWI_MSEN
А еще после AT91C_TWI_MSEN
1 = As soon as data byte is transferred from TWI_THR to internal shifter or if a NACK error is detected, TXRDY is set at the same time as TXCOMP and NACK. TXRDY is also set when MSEN is set (enable TWI).

Так что искать логику в TWI на SAM7 нет смысла, нужно искать пути как заставить его работать smile.gif
Особенно повеселило вот это из даташита:
In master read mode, if a NACK bit is received, the STOP is automatically performed.

для байтового обмена Atmel рекомендует такие последовательности:
чтение
Код
//* Set control register and send start
*AT91C_TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN | AT91C_TWI_STOP;

//* Wait complete by TXCOMP or TXRDY
Status = *AT91C_TWI_SR;
while (!(status & AT91C_TWI_TXCOMP)){
Status = *AT91C_TWI_SR; }

//* Get data
Value = *AT91C_TWI_RHR;

запись
Код
//* Set control register
*AT91C_TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN | AT91C_TWI_STOP;

//* Set Data register for start transmission
*AT91C_TWI_THR = 0XAA;

//* Wait end transmission
Status = *AT91C_TWI_SR;
while (!(status & AT91C_TWI_TXCOMP)){
Status = *AT91C_TWI_SR; }

то есть START и STOP выставляем одновременно перед приемом передачей 1 байта
только ИМХО, там все равно не все чисто !
например при записи вы можете вобще не выставлять AT91C_TWI_START
передача начнется в любом случае при записи *AT91C_TWI_THR = 0XAA;

Кстати, а чем еще у Вас занята мега ?
Разрешены ли какие-то прерывания еще ?
Если разрешены, то сколько времени они занимают ?
какая частота i2c ?
это все имеет значение sad.gif
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Mar 10 2007, 21:47
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
Так что искать логику в TWI на SAM7 нет смысла, нужно искать пути как заставить его работать

a14.gif a14.gif a14.gif


Вы указали правильное направление. Там что-то с установекой статусных битов.
Сделал не совсем по совету, но близко. Экспериментально установлено - чтение отставало на одну транзакцию. Ввел упреждающее чтение RHR перед подачей команды старт. Чтение исправилось, зато запись вешает SAM вглухую. Сейчас сделаю отладочный вывод из регистра статуса и буду шаманить.


PS. К Меге вопросов нет, так что модераторы могут смело переносить тему в АРМы.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Mar 10 2007, 22:06
Сообщение #11


дятел
*****

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



Цитата(beer_warrior @ Mar 10 2007, 21:47) *
Цитата
Так что искать логику в TWI на SAM7 нет смысла, нужно искать пути как заставить его работать

a14.gif a14.gif a14.gif


Вы указали правильное направление. Там что-то с установекой статусных битов.
Сделал не совсем по совету, но близко. Экспериментально установлено - чтение отставало на одну транзакцию. Ввел упреждающее чтение RHR перед подачей команды старт. Чтение исправилось, зато запись вешает SAM вглухую. Сейчас сделаю отладочный вывод из регистра статуса и буду шаманить.


PS. К Меге вопросов нет, так что модераторы могут смело переносить тему в АРМы.

Я думаю что переносить пока рано smile.gif
С мегой там тоже есть кое-какие вопросы
Ответьте на вопросы прошлого поста про мегу!
Это ВАЖНО!!!
>>Чтение исправилось, зато запись вешает SAM вглухую
Если есть возможность пришлите мне весь код который касается i2c и на АРМ и на меге
Если не хотите публиковать здесь то шлите на PM
Обещаю не выкладывать на всеобщее обсуждение !
Мне это тоже очень нужно, особенно интересует последовательности
при которых у Вас работает с EEPROM и не работает с мега.
У меня подключена только мега, но нужно чтобы и с EEPROM тоже работало
Кстати, а EEPROM какой ?
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Mar 10 2007, 22:13
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Значит так, проблема решена следующим образом:
Код
bool ReadByteI2C(BYTE addr, BYTE* data)
{
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*data = AT91C_BASE_TWI->TWI_RHR;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//set device & internal adr
AT91C_BASE_TWI->TWI_MMR = (addr << 16)| AT91C_TWI_MREAD;    //start
TWI_START();
//write data
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_RXRDY));            
*data = AT91C_BASE_TWI->TWI_RHR;
//stop
TWI_STOP();    
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP));
//*data = AT91C_BASE_TWI->TWI_RHR;
return true;
}

#define TWI_START()        AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;
#define TWI_STOP()        AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;


Весь остальной код, тот же, что и в начале топика.
Закомментированное чтение в конце функции всегда возвращает 0.

Неработающая запись в предыдущем посте - глюк РС-шного софта.

Протестировано записью произвольных значений в PORTD работающий на выход и последующего чтения из PIND. Процесс перемежался с произвольными обращениями к памяти. Пока глюков не замечено.
Следующим номером программы намечен запуск I2C LCD на той же шине. Ежели появятся глюки - сообщу.

Уважаемый singlskv , если будете проездом в Киеве, смело рассчитывайте на пиво cheers.gif


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Mar 10 2007, 22:37
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
Я думаю что переносить пока рано С мегой там тоже есть кое-какие вопросы Ответьте на вопросы прошлого поста про мегу!Это ВАЖНО!!!

О меге:
Код
int  main(void)
{

cli();
adr = eeprom_read_byte(ADR);
DDRD = 0xff;
PORTD = port;
TWS_Init(0x10);
//enable interrupts
sei();

//--------------------------------------------------------------------------
//main loop
for(;;)
    {
    //PORTD++;
    }
return 0;
}//main

__inline__ void TWS_Init(BYTE addr)
{
TWAR = (addr << 1);
TWCR = (1 << TWEN) | (1 << TWIE) |(1 << TWEA);


Фьюзы по умолчанию - живет от внутреннего генератора, слэйву это некритично. Работает в качестве внешнего контроллера клавиатуры - дабы не тратить драгоценные ножки SAMa. Пока писал пост подключил таймер для опроса клавиатуры - ситуация не изменилась.
Код таймера
Код
//------------------------------------------------------------------------
#ifdef _MEGA8_
SIGNAL(SIG_OUTPUT_COMPARE2)
#endif
#ifdef _MEGA88_
SIGNAL(SIG_OUTPUT_COMPARE2A)
#endif
{  
//sinchronous timer operation, 100uS
    system_timer.timer_100us++;
    if(hTimer_100us) hTimer_100us();    
    if(system_timer.timer_100us >= 10)    //100uS * 10 = 1uS
        {
        system_timer.timer_1ms++;
        system_timer.timer_100us = 0;
        if(hTimer_1ms) hTimer_1ms();
        }
    if(system_timer.timer_1ms >= 1000)    //1mS * 1000 = 1s
        {
        system_timer.timer_1s++;
        system_timer.timer_1ms = 0;
        if(hTimer_1s) hTimer_1s();
        }
        
}
//------------------------------------------------------------------------
void InitSysTimer2(void)
{
TCNT2 = 0;
#ifdef _MEGA8_
//OCR2 = 138;
//OCR2 = 8;
OCR2 = 14;
TCCR2 = 0;
TCCR2 = (1 << WGM21)|(1 << CS21);//CTC mode
//TCCR2 = (1 << WGM21)|(1 << CS20);//CTC mode
//TCCR2 = (1 << WGM21)|(1 << CS22)|(1 << CS20);//CTC mode
TIMSK |= (1 << OCIE2);
#endif
#ifdef _MEGA88_
OCR2A = 138;
TCCR2A = 0;
TCCR2A = (1<< WGM21);//;//CTC mode
TCCR2B = 0;
//TCCR2B = (1 << CS21);//clk/8    
TCCR2B = (1 << CS22)|(1 << CS20);//clk/128    
TIMSK2 |= (1<<OCIE2A);
#endif
}
//------------------------------------------------------------------------


EEPROM 24xx
Работает так.
Код
void AT24WriteMem(DWORD addr, BYTE* src, DWORD len)
{
while(len)
    {
    AT24WriteByte(addr,*src);
    addr++;
    src++;
    len--;
    }
}

bool AT24WriteByte(DWORD addr, BYTE data)
{
//set device & internal adr
AT91C_BASE_TWI->TWI_MMR = (AT91C_TWI_IADRSZ_2_BYTE|(0x50 << 16));
AT91C_BASE_TWI->TWI_IADR = addr;
AT91C_BASE_TWI->TWI_THR = data;
//start
TWI_START();
//write data
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXRDY));            
//stop
TWI_STOP();    
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP));
return true;
}


Долгое шаманство с использованием фич автоинкремента адреса приводило к плохо предсказуемым сбоям.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Mar 10 2007, 22:49
Сообщение #14


дятел
*****

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



Цитата(beer_warrior @ Mar 10 2007, 22:13) *
Значит так, проблема решена следующим образом:
Код
bool ReadByteI2C(BYTE addr, BYTE* data)
{
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*data = AT91C_BASE_TWI->TWI_RHR;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//set device & internal adr
AT91C_BASE_TWI->TWI_MMR = (addr << 16)| AT91C_TWI_MREAD;    //start
TWI_START();
//write data
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_RXRDY));            
*data = AT91C_BASE_TWI->TWI_RHR;
//stop
TWI_STOP();    
while(!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP));
//*data = AT91C_BASE_TWI->TWI_RHR;
return true;
}

#define TWI_START()        AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;
#define TWI_STOP()        AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;


Весь остальной код, тот же, что и в начале топика.
Закомментированное чтение в конце функции всегда возвращает 0.

Неработающая запись в предыдущем посте - глюк РС-шного софта.

Протестировано записью произвольных значений в PORTD работающий на выход и последующего чтения из PIND. Процесс перемежался с произвольными обращениями к памяти. Пока глюков не замечено.
Следующим номером программы намечен запуск I2C LCD на той же шине. Ежели появятся глюки - сообщу.

Уважаемый singlskv , если будете проездом в Киеве, смело рассчитывайте на пиво cheers.gif

Пыво это с удовольствием cheers.gif

Но, такое решение:
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*data = AT91C_BASE_TWI->TWI_RHR;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

подходит только для байтового обмена !!!

Если будет последовательное чтение с EEPROM или FRAM то это будет работать криво
Давайте разбираться подробнее, если конечно есть желание...

В двух словах моя проблема:
i2c на меге работает по полингу
i2c на АРМ работает по прерываниям

основная проблема TWI на SAM7 это то, что он работает в "синхронном" режиме
То есть ему глубоко наплевать на то что мега держит линию SCL в 0(пока данные не готовы)
и у него (SAM7) весь трансфер происходит "синхронно"
то есть SAM7 вобще не мониторит состояние линии SCL перед тем как начать передачу!

С этой проблеммой я кое-как разобрался,
НО, раз в секунду (2,3,5 секунд) у меня происходит следующее:
мега получает правильный запрос, готовит ответ и передает его при запросе от мастера
Ответ от меги ТОЧНО готовится правильный
при этом (иногда) SAM7 получает первый байт ответа неправильным
в нем установлен старший бит в 1 хотя должен быть 0

Так как у меня сейчас нет подключенного к i2c "железного" i2c девайса
то поймать где проблемма не получается
По этому просьба, перешлите мне последовательность обращения к eeprom
Возможно это поможет понять все тонкости

P.S. Кстати на счет Меги
Я бы в Вашем коде тоже кое-что поменял.
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Mar 10 2007, 23:34
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
Я бы в Вашем коде тоже кое-что поменял.

Согласен, код писан 3 года назад и с тех пор кочует по проектам. Вижу косяки, только руки не доходят преписать.

Цитата
основная проблема TWI на SAM7 это то, что он работает в "синхронном" режиме То есть ему глубоко наплевать на то что мега держит линию SCL в 0(пока данные не готовы)и у него (SAM7) весь трансфер происходит "синхронно"то есть SAM7 вобще не мониторит состояние линии SCL перед тем как начать передачу!

Опс! Спасибо за наколку. Как-то внимания не обращал.


Цитата
По этому просьба, перешлите мне последовательность обращения к eeprom Возможно это поможет понять все тонкости


Да вобщем то я уже дал запись. Дам и чтение -
Код
void AT24ReadMem(DWORD addr, BYTE* src, DWORD len)
{
//DWORD AT24_Read(BYTE* data, BYTE dadr, DWORD address,  DWORD size)
unsigned int status;
// Set the TWI Master Mode Register
AT91C_BASE_TWI->TWI_MMR = (0x50 << 16)| AT91C_TWI_IADRSZ_2_BYTE | AT91C_TWI_MREAD;    
// Set TWI Internal Address Register
AT91C_BASE_TWI->TWI_IADR = addr;
// Start transfer
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;
status = AT91C_BASE_TWI->TWI_SR;
while (len-- >1)
    {
    // Wait RHR Holding register is full
    while (!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_RXRDY));
    // Read byte
    *(src++) = AT91C_BASE_TWI->TWI_RHR;
    }
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;
status = AT91C_BASE_TWI->TWI_SR;
// Wait transfer is finished
while (!(AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP));
// Read last byte
*src = AT91C_BASE_TWI->TWI_RHR;
}


Честно признаюсь, что этот фрагмент содран где-то на Сахаре.
Благополучно прожил в нескольких проектах. А вот запись повела себя ненадежно поэтому была переделана под байтовый обмен.

А какой формат обмена у вас?
адрес -> внутренний адрес-> данные
или
адрес -> вычитывание большого блока


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 30th June 2025 - 14:58
Рейтинг@Mail.ru


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