Raspberry Pi 和 ATMEGA324PA 之间的 SMBus 通话 - AVR 不延长时钟
Talking SMBus between RaspberryPi and ATMEGA 324PA - AVR not clock stretching
我正在尝试将 ATMEGA 324PA 作为 SMBus slave 运行。
我在 Pi 上使用以下代码:
import smbus as smbus
i2c = smbus.SMBus(1)
i2c_addr = 0x30
result = i2c.read_block_data( i2c_addr, reg )
在 AVR 上,我使用的是:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "smb_slave.h"
#define SMB_COMMAND_RETURN_VENDOR_STRING 0x10
int main(void)
{
// Set data direction of PORTB as output and turn off LEDs.
DDRA = 0xff;
PORTA = 0xff;
// Initialize SMBus
SMBusInit();
SMBEnable();
// Enable interrupts globally
sei();
for (;;)
{
}
return 0;
}
void ProcessReceiveByte(SMBData *smb)
{
smb->txBuffer[0] = ~PIND;
smb->txLength = 1;
}
static void ReturnVendorString(SMBData *smb)
{
unsigned char *vendor = (unsigned char*) "Vendor[=11=]";
unsigned char i;
unsigned char temp;
i = 0;
// Copy vendor ID string from EEPROM.
while ((temp = vendor[i]) != '[=11=]')
{
i++;
smb->txBuffer[i] = temp;
}
smb->txBuffer[0] = i; // Byte count.
smb->txLength = i + 1; // Number of bytes to be transmitted including byte count.
smb->state = SMB_STATE_WRITE_READ_REQUESTED;
PORTA ^= 0x40; // debug
}
static void UndefinedCommand(SMBData *smb)
{
// Handle undefined requests here.
smb->error = TRUE;
smb->state = SMB_STATE_IDLE;
}
void ProcessMessage(SMBData *smb)
{
if (smb->state == SMB_STATE_WRITE_REQUESTED)
{
switch (smb->rxBuffer[0]) // Command code.
{
case SMB_COMMAND_RETURN_VENDOR_STRING: // Block read, vendor ID.
ReturnVendorString(smb);
break;
default:
UndefinedCommand(smb);
break;
}
}
else
{
smb->state = SMB_STATE_IDLE;
}
}
使用(gcc 改编的)版本:http://www.atmel.com/images/AVR316.zip from http://www.atmel.com/devices/ATMEGA324A.aspx?tab=documents
部分功能正常,正如我的逻辑分析器显示的那样:
但我认为我做错了什么,因为 AVR 没有确认读取,也没有时钟延展,也没有发送响应。
接下来我应该看哪里?
我对 RasPi 上的 Python smbus 模块有信心吗?
我看到的可能与 https://github.com/raspberrypi/linux/issues/254 有关吗?
我尝试使用 Beaglebone 的 SMBus(替换 Raspberry Pi)。
在我向 i2c 总线添加一些 10K 上拉电阻后,这非常有效。 (Raspberry Pi 在 i2c 引脚上有内部上拉。)
您链接的问题就是问题所在——i2c 时钟拉伸在 Raspberry Pi 上被简单地破坏了。更多信息:http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
如果传感器有替代输出,例如 UART,有时这是一种选择,但对于某些项目,我不得不使用微型或 Beaglebone 或其他东西。
我正在尝试将 ATMEGA 324PA 作为 SMBus slave 运行。
我在 Pi 上使用以下代码:
import smbus as smbus
i2c = smbus.SMBus(1)
i2c_addr = 0x30
result = i2c.read_block_data( i2c_addr, reg )
在 AVR 上,我使用的是:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "smb_slave.h"
#define SMB_COMMAND_RETURN_VENDOR_STRING 0x10
int main(void)
{
// Set data direction of PORTB as output and turn off LEDs.
DDRA = 0xff;
PORTA = 0xff;
// Initialize SMBus
SMBusInit();
SMBEnable();
// Enable interrupts globally
sei();
for (;;)
{
}
return 0;
}
void ProcessReceiveByte(SMBData *smb)
{
smb->txBuffer[0] = ~PIND;
smb->txLength = 1;
}
static void ReturnVendorString(SMBData *smb)
{
unsigned char *vendor = (unsigned char*) "Vendor[=11=]";
unsigned char i;
unsigned char temp;
i = 0;
// Copy vendor ID string from EEPROM.
while ((temp = vendor[i]) != '[=11=]')
{
i++;
smb->txBuffer[i] = temp;
}
smb->txBuffer[0] = i; // Byte count.
smb->txLength = i + 1; // Number of bytes to be transmitted including byte count.
smb->state = SMB_STATE_WRITE_READ_REQUESTED;
PORTA ^= 0x40; // debug
}
static void UndefinedCommand(SMBData *smb)
{
// Handle undefined requests here.
smb->error = TRUE;
smb->state = SMB_STATE_IDLE;
}
void ProcessMessage(SMBData *smb)
{
if (smb->state == SMB_STATE_WRITE_REQUESTED)
{
switch (smb->rxBuffer[0]) // Command code.
{
case SMB_COMMAND_RETURN_VENDOR_STRING: // Block read, vendor ID.
ReturnVendorString(smb);
break;
default:
UndefinedCommand(smb);
break;
}
}
else
{
smb->state = SMB_STATE_IDLE;
}
}
使用(gcc 改编的)版本:http://www.atmel.com/images/AVR316.zip from http://www.atmel.com/devices/ATMEGA324A.aspx?tab=documents
部分功能正常,正如我的逻辑分析器显示的那样:
但我认为我做错了什么,因为 AVR 没有确认读取,也没有时钟延展,也没有发送响应。
接下来我应该看哪里?
我对 RasPi 上的 Python smbus 模块有信心吗?
我看到的可能与 https://github.com/raspberrypi/linux/issues/254 有关吗?
我尝试使用 Beaglebone 的 SMBus(替换 Raspberry Pi)。
在我向 i2c 总线添加一些 10K 上拉电阻后,这非常有效。 (Raspberry Pi 在 i2c 引脚上有内部上拉。)
您链接的问题就是问题所在——i2c 时钟拉伸在 Raspberry Pi 上被简单地破坏了。更多信息:http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
如果传感器有替代输出,例如 UART,有时这是一种选择,但对于某些项目,我不得不使用微型或 Beaglebone 或其他东西。