我的ARM平台是 Cortex A9,MSP430G2231通过P1.6、P1.7与ARM核I2C总线通信,MSP430其他引脚上挂载众多其他设备模块,如射频、SIM卡等。
ARM上跑的是Linux系统,Linux内核有I2C总线驱动,单片机部分的程序有功能需求:
1. ARM端程序下发I2C命令通知MSP430关闭射频(ARM端->MSP430);
2. MSP430端程序检测到SIM卡插入(引脚中断检测),则发I2C命令通知ARM端进行相应的处理(MSP430 ->ARM端)。
所以,我除了写单片机部分的程序,还应该需要写ARM端这部分通信的I2C设备驱动程序。
因为我看点Linux的I2C总线驱动,似乎都是在充当着Master,所以,我想是否在单片机端都应该配置成slave,但是如果是slave的话,当实现需求2的时候,不能主动发起I2C命令….
因此,ARM端程序和MSP430端程序各是要采取什么模式,求教…
Lina Lian:
Kyle wang,你好。MSP430G2231这边的USI的I2C mode应该支持多 master形式,可以进行总线仲裁。具体请参照user guide的14.2.4.8 Arbitration。
Kyle wang:
回复 Lina Lian:
Lina Lian,您好!那如上我所述问题该如何实现呢?主要是当MSP430选择其I2C模式后,ARM端的Linux I2C如何配置选择与之对应的模式?
Lina Lian:
回复 Kyle wang:
Kyle wang, 你先查查看ARM的I2C是否支持multi-master I2C systems下的arbitration,如果支持的话,那你可以两遍都设为master,在应用过程中如果ARM和MSP430同时发送数据的话,总线仲裁就会起作用。但是如果ARM不支持的话,你就把ARM设为master,MSP3430设为slave,两外将MSP430的一个GPIO接至ARM,当MSP430检测到SIM卡插入,想要发送数据给ARM时,就先给通过GPIOARM一个中断,告诉ARM我要传数了即可。自己看着灵活应用吧。
Kyle wang:
回复 Lina Lian:
Lina Lian ,感谢您的解答!我觉得第二种方法挺好的,但是需要硬件方面的改动。(1)我有个笨办法不知道是否可以:在ARM端linux程序中以定时轮询(如1s)方式发I2C消息给MSP430查询当前各模块状态,这种方式是否可行?(2)在I2C模式中,main函数里省电模式是否配置为LPM0为最佳?
Lina Lian:
回复 Kyle wang:
Kyle wang,
方法(1)肯定是可行的,但是对ARM和MSP430都增加了负担,可能在一定程度上导致ARM和MSP430的实时性的下降。
(2)请问你的I2C模块的时钟源选择的是什么?请根据user guide ‘2.3 Operating Modes’,对LPM模式进行合理选择。
Kyle wang:
回复 Lina Lian:
Lina Lian,您好!我I2C模块的时钟源直接照搬例程中的设置void System_Clock_Init(void){ WDTCTL = WDTPW + WDTHOLD; // Stop watchdog if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF) { while(1); // If calibration constants erased // do not load, trap CPU!! } BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ;}void Setup_USI_Slave(void){ USICTL0 = USIPE6 + USIPE7 + USISWRST; // Port & USI mode setup USICTL1 = USII2C + USIIE + USISTTIE; // Enable I2C mode & USI interrupt USICKCTL = USICKPL; // Setup clock polarity USICNT |= USIIFGCC; // Disable automatic clear control USICTL0 &= ~USISWRST; // Enable USI USICTL1 &= ~USIIFG; // Clear pending flag DataDirection = Receive; __enable_interrupt(); }