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

Twi в SAM7s128

Всем доброго времени суток! Я понимаю, что тема избитая, но перечитав с дюжину веток на этом и других форумах, я решения так и не нашел. Надеюсь на понимание уважаемых форумчан. Собственно не могу добиться хотя бы изменения состояния на линиях TWD и TWCK у at91sam7128. Привожу кусок кода который использую для инициализации интерфейса:

 

/* Function of definition I2C */

void I2C_INIT () {

pPIO -> PIO_PDR = pPIO -> PIO_PDR | 0x18; // disable PA3 PA4 I/O for using by I2C

pPIO -> PIO_PPUDR = 0xFFFFFFE7; // Отключаю pull-up резисторы везде кроме 3 и 4 линий

pPIO -> PIO_ASR = pPIO -> PIO_ASR | 0x18; // наверное необязательно, но указываю что линии 3 и 4 - это периферия А

pPIO -> PIO_MDER = pPIO -> PIO_MDER | 0x18; // линии 3 и 4 с открытым стоком

pP_M_C -> PMC_PCER = pP_M_C -> PMC_PCER | 0x200; // clock enable I2C

AT91C_BASE_TWI -> TWI_CR = AT91C_TWI_SWRST; // программный сброс

AT91C_BASE_TWI -> TWI_CWGR = 0x8383; // частота ~200kHz

AT91C_BASE_TWI -> TWI_MMR = AT91C_TWI_IADRSZ_1_BYTE | ((unsigned int) 0x42 << 16); // adress and size of internal adress

}

/********************************************************/

 

записи:

 

/********************************************************/

void I2C_WR (int intadress) {

int status;

AT91C_BASE_TWI -> TWI_IADR = intadress;

AT91C_BASE_TWI -> TWI_MMR &= 0xFFFFEFFF;

AT91C_BASE_TWI -> TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN | AT91C_TWI_STOP;

 

 

//* Set Data register for start transmission

AT91C_BASE_TWI -> TWI_THR = 0xAA; // !!!!!!!!! Здесь ничего не происходит!!!! Содержимое регистра THR и TXDATA не изменяются

 

status = AT91C_BASE_TWI -> TWI_THR; //..чтение этого регистра дает 0x00 !!!!

//* Wait end transmission

status = AT91C_BASE_TWI -> TWI_SR;

while (!(status & AT91C_TWI_TXCOMP)) {

status = AT91C_BASE_TWI -> TWI_SR;

}

}

///////////////////////////////////////////////////////////////////////////////

Если честно перепробовал кучу вариантов реализации, с учетом рекомендаций Atmel (на их сайте), уже голова кругом. Подскажите, где я делаю что-то неправильно?

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


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

Подскажите, где я делаю что-то неправильно?

- читаете write only регистры

pPIO -> PIO_PDR = pPIO -> PIO_PDR | 0x18; // disable PA3 PA4 I/O for using by I2C

- используете безымянные константы, что потенциально может привести к ошибкам

 

Посмотрите еще эту и эту темы, и подумайте, надо ли Вам вообще это счастье.

 

Для себя я решил однозначно, что пользоваться TWI на SAM7S и SAM7X не стоит.

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


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

Для себя я решил однозначно, что пользоваться TWI на SAM7S и SAM7X не стоит.

Аналогично - пробовал реализовать аппаратный TWI на sam7s64, в результате реализовал вручную все - разбираться, что не так работало просто не было времени.

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


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

aaarrr, alvy, cпасибо за совет. Если честно не думал, что когда-нибудь столкнусь с подобным. Сталкиваясь с такими глюками обычно грешу на "человечесский фактор" (опыт приучил). Надеялся, что разобраться с железом будет проще, чем написать свой кусок программы.

To aaarrr: Вы где-то здесь выкладывали свой вариант реализации софтового I2C. Можно его использовать?

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


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

To aaarrr: Вы где-то здесь выкладывали свой вариант реализации софтового I2C. Можно его использовать?

По первой ссылке. Вариант дебильный, конечно, но вполне работоспособен. Используйте на здоровье.

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


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

Нет, не будет.

 

Камень AT91SAM7S64. Периферия TLV320AIC20, LM8333, FM1073V23. Используется аппаратный TWI, прекрасно работает. Обработчик по прерываниям. Весьма странно, что бытует мнение о неработоспособном TWI в SAM'ах.

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


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

Камень AT91SAM7S64. Периферия TLV320AIC20, LM8333, FM1073V23. Используется аппаратный TWI, прекрасно работает. Обработчик по прерываниям.

Рад за вас, Вам повезло.

 

Весьма странно, что бытует мнение о неработоспособном TWI в SAM'ах.

А для тех, кому не так повезло, Атмел сочинил чудный документ, в котором, например, предлагается решать проблему зависания шины добавлением транзисторов, коммутирующих питание слейвов (стр.7), и убить себя об стену ничего не делать, если в системе есть слейвы, использующие clock stretching (стр.27-28).

 

И пусть каждый сам для себя решает, продолжать ли ему есть кактус использовать TWI, добавляя ненужные транзисторы и выбирая "подходящие" слейвы, или просто заменить драйвер на bit-bang.

Кстати, в линуксовом кернеле так и поступили.

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


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

Nikitoc Вы неправильно делаете инициализацию TWI. Вот пример как я инициализировал:

 

#include <AT91SAM7S256.H>

#include <lib_AT91SAM7S256.H>

#include "..\Main\main.h"

 

#define SPEED_I2C 200000 // Частота работы шины I2C в Гц.

#define CLKDIV (MAINCLK/(2*SPEED_I2C)-3) // Не должен быть выше 255 или меньше 0

 

//----------------------------------------------------------------------------

void i2c_init (void)

{

AT91F_TWI_CfgPIO(); // Подключаем TWI к выходам PA3 и PA4

*AT91C_PIOA_PPUDR = (AT91C_PA4_TWCK | AT91C_PA3_TWD); // Отключаем внутренние подтягивающие резисторы

*AT91C_PIOA_MDER = (AT91C_PA4_TWCK | AT91C_PA3_TWD); // Включаем режим управления - открытый коллектор

AT91F_TWI_CfgPMC(); // Разрешим тактирование TWI

AT91F_TWI_Configure(AT91C_BASE_TWI); // Отключаем все прерывания, делаем сброс TWI и устанавливаем в режим мастера

*AT91C_TWI_CWGR = ((0x00 << 16) | (CLKDIV << 8) | (CLKDIV));

*AT91C_TWI_MMR = 0; // Устанавливаем 0 адрес Slave; режим записи; не использование адресации внутренних регистров slave device

}

 

//----------------------------------------------------------------------------

void i2c_write_byte(char value)

{

int Status;

 

*AT91C_TWI_MMR &= ~AT91C_TWI_MREAD; // Установим режим записи

*AT91C_TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP | AT91C_TWI_MSEN;

*AT91C_TWI_THR = value; // Записываем данные в регистр передачи, тем самым запуская передачу

Status = *AT91C_TWI_SR; // Читаем регистр статуса

while (!(Status & AT91C_TWI_TXCOMP)) Status = *AT91C_TWI_SR; // Ждем завершения передачи

}

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


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

По первой ссылке. Вариант дебильный, конечно, но вполне работоспособен. Используйте на здоровье.

 

Ничуть не дибильный, на 60кгц работал без особых затей. Я разве что подогнул обработку очереди чётотам_poll за один вызов

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


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

Всем огромное спасибо за участие и дельные советы. Помучившись чуток я написал свой софтверный I2C специально под удивительную видеокамеру ov7670 (там создатели назвали I2C интерфейс странным словом SCCB :) ) Конечно, лучше всегда иметь под рукой универсальную библиотеку TWI, но так оказалось быстрее. Тему, думаю, можно считать закрытой. Еще раз всем спасибо.

2 Sergey_K: обязательно попробую Ваш вариант инициализации.

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


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

А в SAM9 которые ARM926 - там как дело с TWI обстоит? надеюсь атмелы исправили ошибки.

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


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

А в SAM9 которые ARM926 - там как дело с TWI обстоит? надеюсь атмелы исправили ошибки.

В SAM9261S, например, исправили.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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