Димон Безпарольный 2 15 июня, 2017 Опубликовано 15 июня, 2017 (изменено) · Жалоба В настройках не нашел: /* I2C2 init function */ void MX_I2C2_Init(void) { hi2c2.Instance = I2C2; hi2c2.Init.ClockSpeed = 100000; hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c2.Init.OwnAddress1 = 144; hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c2.Init.OwnAddress2 = 0; hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_ENABLE; hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; HAL_I2C_Init(&hi2c2); } Как контроллер понимает что он Slave? Как организовать прерывание при совпадении SlaveAdr? Как организовать передачу с помощью DMA из памяти? Изменено 15 июня, 2017 пользователем Димон Безпарольный Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alag57 0 16 июня, 2017 Опубликовано 16 июня, 2017 · Жалоба Как контроллер понимает что он Slave? RM0038 Reference manual: 26.3.1 Mode selection By default, it operates in slave mode. The interface automatically switches from slave to master, after it generates a START condition and from master to slave, if an arbitration loss or a Stop generation occurs, allowing multimaster capability. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Димон Безпарольный 2 16 июня, 2017 Опубликовано 16 июня, 2017 (изменено) · Жалоба RM0038 Reference manual: Да, я это уже прочитал. Спасибо. Просто не знаю с чего начать писать код. Примеров в Сети не нашел. Нужен I2C slave со стратегией: - ответ на Slave ADR и передача Slave Transmit 16байт. Куб конечно помогает сконфигурировать интерфейс но кто устанавливает hi2c2.Mode = HAL_I2C_MODE_SLAVE; не пойму. Может где есть пример? Попробую начать долбить slave адресом в чип и контролировать установку бита Bit 1 ADDR: Address sent (master mode)/matched (slave mode) Изменено 16 июня, 2017 пользователем Димон Безпарольный Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Димон Безпарольный 2 19 июня, 2017 Опубликовано 19 июня, 2017 (изменено) · Жалоба Сделал машину состояний. Стабильно начало работать только после того, как я обеспечил обработку ошибок. void I2C2_EV_IRQHandler(void) { /* USER CODE BEGIN I2C2_EV_IRQn 0 */ switch(I2C_GetLastEvent(I2C2)) { //SLAVE Receive case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: //EV1 0x00020002 { I2C_clear_ADDR(); //CntTR = 0; break; } case I2C_EVENT_SLAVE_BYTE_RECEIVED: //EV2 0x00020040 { //Read it, so no one is waiting, clears BTF if necessary. Read DR Dum1 = I2C2->DR; break; } case I2C_EVENT_SLAVE_STOP_DETECTED: //End of receive, EV4 0x00000010 { //if(I2C_GetFlagStatus(I2C_FLAG_ADDR) == SET) {I2C_clear_ADDR();} //---------------- volatile int State; //Clear STOPF State = I2C2->SR1; // I2C2->CR1 |= 1; //PE----------------------- break; } //Transmit case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: //EV1 0x00060082 { I2C_clear_ADDR(); I2C2->DR = Dum1; //Send first byte break; } case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: //EV3 0x00060084 case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: //----------------------------- { //Read flag and write next byte to clear BTF if present I2C_GetFlagStatus(I2C_FLAG_BTF); I2C2->DR = ++CntTR; break; } //Alternative Cases for address match case I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED: {break;}//EV1 0x00820000 case I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED: {break;}//EV1 0x00860080 //How the FUCK did you get here? I should probably raise some error, but fuck it, it's late default: {break;} } /* USER CODE END I2C2_EV_IRQn 0 */ //HAL_I2C_EV_IRQHandler(&hi2c2); /* USER CODE BEGIN I2C2_EV_IRQn 1 */ /* USER CODE END I2C2_EV_IRQn 1 */ } void I2C2_ER_IRQHandler(void) { /* USER CODE BEGIN I2C2_ER_IRQn 0 */ //Dum1 = I2C2->SR1; /* USER CODE END I2C2_ER_IRQn 0 */ //HAL_I2C_ER_IRQHandler(&hi2c2); /* USER CODE BEGIN I2C2_ER_IRQn 1 */ GPIOB->BSRR = 1<<13; I2C2->SR1 = ~((1<<10) & ((uint32_t)0x0000FFFF)); //AF Clear //I2C2->CR2 |= I2C_CR2_ITEVTEN; //I2C2->CR2 |= I2C_CR2_ITBUFEN; //I2C2->CR2 |= I2C_CR2_ITERREN; /* USER CODE END I2C2_ER_IRQn 1 */ } При ошибках загорается светодиод. В цикле 1с он гасится. Так вот. Ошибка возникает только одна - Ack failure. Думаю что она возникает когда мастер выдает NACK на последнем байте. Других мыслей нет. Пока обработчик принимает один байт и выдает нумерованные байты. На мастере вызывается функция HAL_I2C_Mem_Read(&hi2c1, 0x33<<1, 0x55, 1, &GAS_Data[0], 20, 200); Она передает Slave+W, Байт адреса, повторный старт, Slave+R и читает 20байт. Кажется так. Работает исправно. Но избавится от Ack failure пока не могу. Изменено 21 июня, 2017 пользователем IgorKossak [codebox] для длинного кода. [code]-для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться