Hi,
I am using the MQX 4.0 with Codewarrior for use on the K70. When I initialize I2C0 all is fine, I added the I2C1 initialization code to the BSP, see below. But when I try to initialize the I2C1 it causes an interrupt before the initialization can complete. I can initialize the I2C1 and communicate using a PE program. Could there be a part in the BSP for the twr k70 that is configuring the pins I need for I2C1 before it is called, and then causing my interrupt?
_mqx_int _bsp_i2c_io_init
(
uint_32 dev_num
)
{
PORT_MemMapPtr pctl;
SIM_MemMapPtr sim = SIM_BASE_PTR;
switch (dev_num)
{
case 0:
pctl = (PORT_MemMapPtr)PORTE_BASE_PTR;
pctl->PCR[18] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK;
pctl->PCR[19] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK;
sim->SCGC4 |= SIM_SCGC4_IIC2_MASK ;
break;
case 1: //I2C1, LP Added 7/25/13
pctl = (PORT_MemMapPtr)PORTF_BASE_PTR;
pctl->PCR[3] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK ; // PTF3, I2C1_SDA, LP Added 7/25/13
pctl->PCR[2] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK; // PTF2, I2C1_SCL, LP Added 7/25/13
sim->SCGC4 |= SIM_SCGC4_IIC2_MASK ;
break;
default:
/* Do nothing if bad dev_num was selected */
return -1;
}
return MQX_OK;
}
已解决! 转到解答。
In MK70F12.h:
define SIM_SCGC4_IIC2_MASK SIM_SCGC4_IIC0_MASK
so you enable clock gate for I2C0 module in both case statements, but not for I2C1. To enable clock for IIC1 module in case 1:, make sure you set the IIC1 bit 7 of SIM_SCGC4 register. Writing to a peripheral module register with clock gated causes a hard fault exception.
In MK70F12.h:
define SIM_SCGC4_IIC2_MASK SIM_SCGC4_IIC0_MASK
so you enable clock gate for I2C0 module in both case statements, but not for I2C1. To enable clock for IIC1 module in case 1:, make sure you set the IIC1 bit 7 of SIM_SCGC4 register. Writing to a peripheral module register with clock gated causes a hard fault exception.
Martin,
Thanks that was it! I changed to below and it works.
_mqx_int _bsp_i2c_io_init
(
uint_32 dev_num
)
{
PORT_MemMapPtr pctl;
SIM_MemMapPtr sim = SIM_BASE_PTR;
switch (dev_num)
{
case 0:
pctl = (PORT_MemMapPtr)PORTE_BASE_PTR;
pctl->PCR[18] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK;
pctl->PCR[19] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK;
sim->SCGC4 |= SIM_SCGC4_IIC2_MASK ;
break;
case 1: //I2C1, LP Added 7/25/13
pctl = (PORT_MemMapPtr)PORTF_BASE_PTR;
pctl->PCR[3] = PORT_PCR_MUX(2) | PORT_PCR_ODE_MASK | PORT_PCR_ISF_MASK; // PTF3, I2C1_SDA, LP Added 7/25/13
pctl->PCR[2] = PORT_PCR_MUX(2) | PORT_PCR_ODE_MASK| PORT_PCR_ISF_MASK; // PTF2, I2C1_SCL, LP Added 7/25/13
sim->SCGC4 |= SIM_SCGC4_IIC1_MASK ; //Clock Gate, LP Updated 7/31/13
break;
default:
/* Do nothing if bad dev_num was selected */
return -1;
}
return MQX_OK;
}
I did notice my Muxing was wrong, I updated that as below, but still same interrupt happening.
_mqx_int _bsp_i2c_io_init
(
uint_32 dev_num
)
{
PORT_MemMapPtr pctl;
SIM_MemMapPtr sim = SIM_BASE_PTR;
switch (dev_num)
{
case 0:
pctl = (PORT_MemMapPtr)PORTE_BASE_PTR;
pctl->PCR[18] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK;
pctl->PCR[19] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK;
sim->SCGC4 |= SIM_SCGC4_IIC2_MASK ;
break;
case 1: //I2C1, LP Added 7/25/13
pctl = (PORT_MemMapPtr)PORTF_BASE_PTR;
pctl->PCR[3] = PORT_PCR_MUX(2) | PORT_PCR_ODE_MASK ; // PTF3, I2C1_SDA, LP Added 7/25/13
pctl->PCR[2] = PORT_PCR_MUX(2) | PORT_PCR_ODE_MASK; // PTF2, I2C1_SCL, LP Added 7/25/13
sim->SCGC4 |= SIM_SCGC4_IIC2_MASK ;
break;
default:
/* Do nothing if bad dev_num was selected */
return -1;
}
return MQX_OK;
}
As part of the BSP, the clocks are all done in the _bsp_gpio_io_init for all ports. I am not sure how to determine which interrupt is being invoked, just that I end up in the _int_kernel_isr function when trying to initialize the I2C1 port. I am using exact same functions for I2C0 as I2C1.