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

 
 
 
Reply to this topicStart new topic
> MicroBlaze I2C - XIic, отправка-прием, отправить и сразу принять
AVR
сообщение Oct 22 2012, 01:04
Сообщение #1


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Не понимаю что я делаю не так. Не могу найти фукнцию, которая бы записала один байт (адрес регистра внутри slave) и затем стала бы читать N байт.

Вот код:
Код
    XUartLite_RecvByte(XPAR_UARTLITE_1_BASEADDR);

    u8 msg[16];

    msg[0] = 0x00;
    int sent = 0;
    sent = XIic_Send(XPAR_IIC_0_BASEADDR, 0x38, msg, 1, XIIC_REPEATED_START);
    for(int i = 0; i < 16; i++) msg[i] = 0;

    int received;
    received = XIic_Recv(XPAR_IIC_0_BASEADDR, 0x38, msg, 10, XIIC_STOP);

    xil_printf("sent=%d\n\r", sent);
    xil_printf("received=%d\n\r", received);

    xil_printf("received data: ");
    for(int i = 0; i < 10; i++) xil_printf("%02X ", msg[i]);
    xil_printf(" OK\n\r");

Код
sent=1
received=0
received data: 00 00 00 00 00 00 00 00 00 00  OK

Вот с точки зрения даташита я должен отправить адрес регистра который хочу читать, а затем уже принять байт начиная с него:
Прикрепленное изображение

На деле же получается вот что, запись заканчивается новым стартом (XIIC_REPEATED_START)
Прикрепленное изображение

Тут линии такие:
Project.unit<0>.dataChannel<0>=mb/fpga_0_Generic_IIC_Bus_Sda_pin_T
Project.unit<0>.dataChannel<1>=mb/fpga_0_Generic_IIC_Bus_Sda_pin_O
Project.unit<0>.dataChannel<2>=mb/fpga_0_Generic_IIC_Bus_Scl_pin_T
Project.unit<0>.dataChannel<3>=mb/fpga_0_Generic_IIC_Bus_Scl_pin_O

Ну а как без XIIC_REPEATED_START? Тогда если XIIC_STOP то стоп и возникнет. ACK я видеть к сожалению не могу, _Sda_pin_O у меня увы выдает все время ноль, но зато на _Scl_pin_T должны быть правильные клоки достоверно быть видны.

Неужели возможно самый распространенный сценарий они не поддерживают? Когда пишется один байт с адресом а затем адрес регистра 8 бит и сразу чтение?

Вопрос: как осуществить нормальную запись одного байта и затем сразу чтение??? Я бьюсь уже очень много дней. Но работу с теми же датчиками по I2C на ARM процессоре с Linux я осилил ща 30 минут и всё сразу работало, а тут какой-то затык.


--------------------
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Oct 24 2012, 15:24
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



Цитата(AVR @ Oct 22 2012, 04:04) *
for(int i = 0; i < 16; i++) msg[i] = 0;
int received;
received = XIic_Recv(XPAR_IIC_0_BASEADDR, 0x38, msg, 10, XIIC_STOP);


Не знаю как работает функция XIic_Recv(), но по моему msg нужно заполнить 0xFF.
Go to the top of the page
 
+Quote Post
AVR
сообщение Oct 26 2012, 13:40
Сообщение #3


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Получилось так:
Код
int test_i2c::i2c_read(int i2c_address, unsigned char reg_address, unsigned char *data, int read_count)
{
    int received;
    unsigned short status_reg;
    xil_printf("reg_address=%d\n\r", reg_address);

    do
    {
        status_reg = XIic_ReadReg(XPAR_IIC_0_BASEADDR, XIIC_SR_REG_OFFSET);
        if(!(status_reg & XIIC_SR_BUS_BUSY_MASK))
        {
            received = XIic_Send(XPAR_IIC_0_BASEADDR, i2c_address, (u8*)&reg_address, 1, XIIC_STOP);

            if(received != 1)
            {
                XIic_WriteReg(XPAR_IIC_0_BASEADDR, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK);
                XIic_WriteReg(XPAR_IIC_0_BASEADDR, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK);
            }
        }

    } while(received != 1);

    received = XIic_Recv(XPAR_IIC_0_BASEADDR, i2c_address, data, read_count, XIIC_STOP);
    return received;
}

Черт ногу сломит, но хотя бы работает (это типа low level), потом перепишу на "высшем" уровне, с прерываниями и т.п.

Тестировал с акселерометром:
Код
        int xyz[3];
        received = i2c_read(0x38, 2, msg, 6);

        xil_printf("received data: ");
        for(int k = 0; k < 6; k++) xil_printf("%02X ", msg[k]);
        xil_printf(" END\n\r");

        for(int i = 0; i < 3; i++)
        {
            xyz[i] = ((msg[i*2] >> 6) & 0x03) + (msg[i*2 + 1] << 2);
            if(xyz[i] & (1<<9))
            {
                xyz[i] &= ~(1<<9);
                xyz[i] = -(512 - xyz[i]);
            }
        }

        xil_printf("x=%d y=%d z=%d\n\r", xyz[0], xyz[1], xyz[2]);

Код
reg_address=2
received data: 81 20 01 FF 01 03  END
x=130 y=-4 z=12


--------------------
Go to the top of the page
 
+Quote Post
xor.kruger
сообщение Aug 9 2013, 11:55
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 290
Регистрация: 17-08-08
Из: Чернигов
Пользователь №: 39 647



А проблемы с записью были ?
У меня та же фигня когда пытаюсь записать байты данных с помощью XIic_Send.
Ни у кого нету функции записи для микроблейза ?
Go to the top of the page
 
+Quote Post
xor.kruger
сообщение Aug 13 2013, 06:36
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 290
Регистрация: 17-08-08
Из: Чернигов
Пользователь №: 39 647



Разобрался.
Привожу пример работающих функций, может кому-то пригодится.
Запись:
Код
int WriteI2CBuffer(XIic *InstancePtr, unsigned char device, void * source, int len)
{
    unsigned int count;
    unsigned char * ptr;

    ptr = source;
    count = XIic_Send(InstancePtr->BaseAddress, device, ptr, len, XIIC_STOP);
    if(count != len)
        count = -1;
    else
       count = 0;
    return count;
}

Чтение:
Код
int ReadI2CBuffer(XIic *InstancePtr, unsigned char device, void * destination, int len)
{
    unsigned int count;
    unsigned char * ptr;

    ptr = destination;
    count = XIic_Recv(InstancePtr->BaseAddress, device, ptr, len, XIIC_STOP);
    if(count != len)
        count = -1;
    else
        count = 0;
    return count;
}

Запись 6-ти байт начиная с 7-го регистра:
Код
WriteBuffer[0] = 0x07;
    WriteBuffer[1] = 0xA0;
    WriteBuffer[2] = 0xC2;
    WriteBuffer[3] = 0xc9;
    WriteBuffer[4] = 0xd8;
    WriteBuffer[5] = 0xe7;
    WriteBuffer[6] = 0x80;
    // Start the IIC device.
    Status = XIic_Start(&Iic);
    if (Status != XST_SUCCESS) {
        xil_printf("Failed to start the IIC device\r\n");
        return XST_FAILURE;
    }
    Status = WriteI2CBuffer(InstancePtr, IIC_SLAVE_DEVICE_ADDRESS, WriteBuffer, 7);
    // Stop the IIC device.
    Status = XIic_Stop(&Iic);
    if (Status != XST_SUCCESS) {
        xil_printf("Failed to stop the IIC device\r\n");
        return XST_FAILURE;
    }
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 5th July 2025 - 07:44
Рейтинг@Mail.ru


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