Форум обсуждения систем  

Вернуться   Форум обсуждения систем "Умный дом", проектов Ардуино, OpenWRT и других DIY устройств > Форум умного дома > Сделай сам > OpenWRT/LEDE

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 13.05.2016, 14:44   #11
CAHTEXHIK
Junior Member
 
Регистрация: 27.04.2016
Сообщений: 7
Вес репутации: 0
CAHTEXHIK is an unknown quantity at this point
По умолчанию Re: Расширитель gpio (ввода/вывода) TP-LINK TL-MR3020 по i2c на PCF8574

То же, только вместо PCF8574 atmega8 (и тд)

Код:
#include <avr/io.h>
#include <compat/twi.h>
#include <avr/interrupt.h>
 
#define I2CSLAVE_ADDR       0x4E
 
#define PORT_DDR            0xB0 // PORTB Settings
#define PORT_IN             0xB1 // Get PINB
#define PORT_OUT            0xB2 // Set PORTB
 
unsigned char regaddr; // Store the Requested Register Address
unsigned char regdata; // Store the Register Address Data
 
void i2c_slave_action(unsigned char rw_status)
{
    switch(regaddr) {
		//   PORTB ^= 0x03;
        // PORT
        case PORT_DDR:
            if (rw_status == 0)
                // read
                regdata = DDRB;
            else
                // write
                DDRB = regdata;
             
            break;
 
        case PORT_IN:
            if (rw_status == 0)
                // read
                regdata = PINB;
            break;
 
        case PORT_OUT:
            if (rw_status == 1)
                // write
                PORTB = regdata;
               
            break;
    }
}
 
ISR(TWI_vect)
{
    static unsigned char i2c_state;
    unsigned char twi_status;
 
    // Disable Global Interrupt
    cli();
 
    // Get TWI Status Register, mask the prescaler bits (TWPS1,TWPS0)
    twi_status=TWSR & 0xF8;     
 
    switch(twi_status) {
        case TW_SR_SLA_ACK: // 0x60: SLA+W received, ACK returned
            i2c_state=0;    // Start I2C State for Register Address required
            break;
 
        case TW_SR_DATA_ACK:    // 0x80: data received, ACK returned
            if (i2c_state == 0) {
                regaddr = TWDR; // Save data to the register address
                i2c_state = 1;
            } else {
                regdata = TWDR; // Save to the register data
                i2c_state = 2;
            }
            break;
 
        case TW_SR_STOP:    // 0xA0: stop or repeated start condition received while selected
            if (i2c_state == 2) {
                i2c_slave_action(1);    // Call Write I2C Action (rw_status = 1)
                i2c_state = 0;      // Reset I2C State
            }
            break;
 
        case TW_ST_SLA_ACK: // 0xA8: SLA+R received, ACK returned
        case TW_ST_DATA_ACK:    // 0xB8: data transmitted, ACK received
            if (i2c_state == 1) {
                i2c_slave_action(0);    // Call Read I2C Action (rw_status = 0)
                TWDR = regdata;     // Store data in TWDR register
                i2c_state = 0;      // Reset I2C State
            }
            break;
 
        case TW_ST_DATA_NACK:   // 0xC0: data transmitted, NACK received
        case TW_ST_LAST_DATA:   // 0xC8: last data byte transmitted, ACK received
        case TW_BUS_ERROR:  // 0x00: illegal start or stop condition
        default:
            i2c_state = 0;  // Back to the Begining State
    }
    // Clear TWINT Flag
    TWCR |= (1<<TWINT);
    // Enable Global Interrupt
    sei();
}
 
int main(void)
{
    // TWI Pull UP
    PORTC |= ((1<<PINC4) | (1<<PINC5));
 
    // Initial I2C Slave
    TWAR = I2CSLAVE_ADDR & 0xFE;    // Set I2C Address, Ignore I2C General Address 0x00
    TWDR = 0x00;            // Default Initial Value
 
    // Start Slave Listening: Clear TWINT Flag, Enable ACK, Enable TWI, TWI Interrupt Enable
    TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
 
    // Enable Global Interrupt
    sei();
 
    // Initial Variable Used
    regaddr=0;
    regdata=0;
 
    while (1) {
 
    }
 
}
Ноги дергал так:
Код:
# i2cset -y 0 0x27 0xB0 0xff
# i2cset -y 0 0x27 0xB2 0xff
# i2cset -y 0 0x27 0xB2 0x00
# i2cset -y 0 0x27 0xB2 0x01
# i2cget -y 0 0x27 0xB1

0x01
# i2cset -y 0 0x27 0xB2 0x03
# i2cget -y 0 0x27 0xB1

0x03
, где 0x27 - код устройства, далее адрес и состояние.

Извиняюсь если оффтопнул, но в соседней теме у меня так ничего и не вышло со связкой роутер-UART-atmega. Зато вот получилось сделать роутер-i2c-atmega.
Код скоперфильдил отсюда
CAHTEXHIK вне форума   Ответить с цитированием
 


Здесь присутствуют: 2 (пользователей: 0 , гостей: 2)
 
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 08:05. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd. Перевод: zCarot
Яндекс.Метрика