Exemple #1
0
void ipmi_i2c_ram_dev_service(ipmi_i2c_ram_dev *dev, unsigned long status)
{
    unsigned long slave_act_status;

    if (status)
    {
        slave_act_status = I2CSlaveStatus(dev->bus->i2c_hw_slave_base);     // 读取从机状态
        switch (slave_act_status)
        {
            case I2C_SLAVE_ACT_NONE:                            // 主机没有请求任何动作
                break;

            case I2C_SLAVE_ACT_RREQ_FBR:                        // 主机已发送从机地址和数据地址首字节
                dev->ram_reg_addr = I2CSlaveDataGet(dev->bus->i2c_hw_slave_base);
                dev->ram_reg_addr &= dev->ram_reg_size;
                break;

            case I2C_SLAVE_ACT_RREQ:                            // 主机已经发送数据到从机
                dev->ram_reg[dev->ram_reg_addr++]= I2CSlaveDataGet(dev->bus->i2c_hw_slave_base);
                dev->ram_reg_addr &= dev->ram_reg_size;
                break;

            case I2C_SLAVE_ACT_TREQ:                            // 主机请求从机发送数据
                if (0)
                {
                    OSSemPend(dev->read_lock);                  // 等待从机数据准备好
                }
                I2CSlaveDataPut(dev->bus->i2c_hw_slave_base, dev->ram_reg[dev->ram_reg_addr++]);
                dev->ram_reg_addr &= dev->ram_reg_size;
                break;

            default:
                break;
        }
    }

    if (0)  /* TODO: 从机接收到全部数据,考虑最后一次写完成后使用定时器 */
    {
        OSSemPost(dev->write_lock);
    }
}
Exemple #2
0
void i2c3_slave_interrupt(void) {
    unsigned long status = I2CSlaveIntStatusEx(I2C3_SLAVE_BASE, false);
    if (status & I2C_SLAVE_INT_START) {
    	//Start condition
    }
    else if (status & I2C_SLAVE_INT_STOP) {
    	//Stop condition
    }
    else if (status & I2C_SLAVE_INT_DATA) {
    	//Data in or out
		status = I2CSlaveStatus(I2C3_SLAVE_BASE);
		if (status & I2C_SCSR_RREQ) {
			data_recv = I2CSlaveDataGet(I2C3_SLAVE_BASE);
			data_send = data_recv * 2;
		}
		else if (status & I2C_SCSR_TREQ) {
			I2CSlaveDataPut(I2C3_SLAVE_BASE, data_send);
		}
    }
    I2CSlaveIntClearEx(I2C3_SLAVE_BASE, status);
}
Exemple #3
0
void TwoWire::I2CIntHandler(void) {
    //clear data interrupt
    HWREG(SLAVE_BASE + I2C_O_SICR) = I2C_SICR_DATAIC;
    uint8_t startDetected = 0;
    uint8_t stopDetected = 0;

    if(HWREG(SLAVE_BASE + I2C_O_SRIS) & I2C_SLAVE_INT_START) {
        startDetected = 1;
        //clear raw start interrupt
        HWREG(SLAVE_BASE + I2C_O_SICR) = I2C_SICR_STARTIC;
    }
    else if(HWREG(SLAVE_BASE + I2C_O_SRIS) & I2C_SLAVE_INT_STOP) {
        stopDetected = 1;
        HWREG(SLAVE_BASE + I2C_O_SICR) = I2C_SICR_STOPIC;
    }

    switch(I2CSlaveStatus(SLAVE_BASE) & (I2C_SCSR_TREQ | I2C_SCSR_RREQ)) {

    case(I2C_SLAVE_ACT_RREQ)://data received
        if(I2CSlaveStatus(SLAVE_BASE) & I2C_SCSR_FBR)
            currentState = SLAVE_RX;
        if(!RX_BUFFER_FULL) {
            rxBuffer[rxWriteIndex] = I2CSlaveDataGet(SLAVE_BASE);
            rxWriteIndex = (rxWriteIndex + 1) % BUFFER_LENGTH;
        }

        break;

    case(I2C_SLAVE_ACT_TREQ)://data requested

        if(startDetected) {
            uint8_t oldWriteIndex = txWriteIndex;
            user_onRequest();

            //
            // send data if onRequest() wrote data that has
            // yet to be sent
            //
            if(oldWriteIndex != txWriteIndex) {
                I2CSlaveDataPut(SLAVE_BASE, txBuffer[txReadIndex]);
                txReadIndex = (txReadIndex + 1) % BUFFER_LENGTH;
            }

        }

        else if(!TX_BUFFER_EMPTY) {
            I2CSlaveDataPut(SLAVE_BASE, txBuffer[txReadIndex]);
            txReadIndex = (txReadIndex + 1) % BUFFER_LENGTH;
        }

        else
            I2CSlaveDataPut(SLAVE_BASE, 0);

        break;

    default:
        break;
    }

    if(stopDetected && currentState == SLAVE_RX) {
        int avail = available();
        user_onReceive(avail);
        currentState = IDLE;
    }

}
//*****************************************************************************
//
// Configure the I2C0 master and slave and connect them using loopback mode.
//
//*****************************************************************************
int
main(void)
{
unsigned long ulDataTx[NUM_I2C_DATA];
unsigned long ulDataRx[NUM_I2C_DATA];
unsigned long ulindex;

    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
    // crystal on your board.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_16MHZ);

    //
    // The I2C0 peripheral must be enabled before use.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

    //
    // For this example I2C0 is used with PortB[3:2].  The actual port and
    // pins used may be different on your part, consult the data sheet for
    // more information.  GPIO port B needs to be enabled so these pins can
    // be used.
    // TODO: change this to whichever GPIO port you are using.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //
    // Configure the pin muxing for I2C0 functions on port B2 and B3.
    // This step is not necessary if your part does not support pin muxing.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);

    //
    // Select the I2C function for these pins.  This function will also
    // configure the GPIO pins pins for I2C operation, setting them to
    // open-drain operation with weak pull-ups.  Consult the data sheet
    // to see which functions are allocated per pin.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);

    //
    // Enable loopback mode.  Loopback mode is a built in feature that is
    // useful for debugging I2C operations.  It internally connects the I2C
    // master and slave terminals, which effectively let's you send data as
    // a master and receive data as a slave.
    // NOTE: For external I2C operation you will need to use external pullups
    // that are stronger than the internal pullups.  Refer to the datasheet for
    // more information.
    //
    HWREG(I2C0_MASTER_BASE + I2C_O_MCR) |= 0x01;

    //
    // Enable and initialize the I2C0 master module.  Use the system clock for
    // the I2C0 module.  The last parameter sets the I2C data transfer rate.
    // If false the data rate is set to 100kbps and if true the data rate will
    // be set to 400kbps.  For this example we will use a data rate of 100kbps.
    //
    I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), false);

    //
    // Enable the I2C0 slave module. This module is enabled only for testing
    // purposes.  It does not need to be enabled for proper operation of the
    // I2Cx master module.
    //
    I2CSlaveEnable(I2C0_SLAVE_BASE);

    //
    // Set the slave address to SLAVE_ADDRESS.  In loopback mode, it's an
    // arbitrary 7-bit number (set in a macro above) that is sent to the
    // I2CMasterSlaveAddrSet function.
    //
    I2CSlaveInit(I2C0_SLAVE_BASE, SLAVE_ADDRESS);

    //
    // Tell the master module what address it will place on the bus when
    // communicating with the slave.  Set the address to SLAVE_ADDRESS
    // (as set in the slave module).  The receive parameter is set to false
    // which indicates the I2C Master is initiating a writes to the slave.  If
    // true, that would indicate that the I2C Master is initiating reads from
    // the slave.
    //
    I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, SLAVE_ADDRESS, false);

    //
    // Set up the serial console to use for displaying messages.  This is
    // just for this example program and is not needed for I2C operation.
    //
    InitConsole();

    //
    // Display the example setup on the console.
    //
    UARTprintf("I2C Loopback Example ->");
    UARTprintf("\n   Module = I2C0");
    UARTprintf("\n   Mode = Single Send/Receive");
    UARTprintf("\n   Rate = 100kbps\n\n");

    //
    // Initalize the data to send.
    //
    ulDataTx[0] = 'I';
    ulDataTx[1] = '2';
    ulDataTx[2] = 'C';

    //
    // Initalize the receive buffer.
    //
    for(ulindex = 0; ulindex < NUM_I2C_DATA; ulindex++)
    {
        ulDataRx[ulindex] = 0;
    }

    //
    // Indicate the direction of the data.
    //
    UARTprintf("Tranferring from: Master -> Slave\n");

    //
    // Send 3 peices of I2C data from the master to the slave.
    //
    for(ulindex = 0; ulindex < NUM_I2C_DATA; ulindex++)
    {
        //
        // Display the data that the I2C0 master is transferring.
        //
        UARTprintf("  Sending: '%c'  . . .  ", ulDataTx[ulindex]);

        //
        // Place the data to be sent in the data register
        //
        I2CMasterDataPut(I2C0_MASTER_BASE, ulDataTx[ulindex]);

        //
        // Initiate send of data from the master.  Since the loopback
        // mode is enabled, the master and slave units are connected
        // allowing us to receive the same data that we sent out.
        //
        I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);

        //
        // Wait until the slave has received and acknowledged the data.
        //
        while(!(I2CSlaveStatus(I2C0_SLAVE_BASE) & I2C_SCSR_RREQ))
        {
        }

        //
        // Read the data from the slave.
        //
        ulDataRx[ulindex] = I2CSlaveDataGet(I2C0_SLAVE_BASE);

        //
        // Wait until master module is done transferring.
        //
        while(I2CMasterBusy(I2C0_MASTER_BASE))
        {
        }

        //
        // Display the data that the slave has received.
        //
        UARTprintf("Received: '%c'\n", ulDataRx[ulindex]);
    }

    //
    // Reset receive buffer.
    //
    for(ulindex = 0; ulindex < NUM_I2C_DATA; ulindex++)
    {
        ulDataRx[ulindex] = 0;
    }

    //
    // Indicate the direction of the data.
    //
    UARTprintf("\n\nTranferring from: Slave -> Master\n");

    //
    // Modifiy the data direction to true, so that seeing the address will
    // indicate that the I2C Master is initiating a read from the slave.
    //
    I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, SLAVE_ADDRESS, true);

    //
    // Do a dummy receive to make sure you don't get junk on the first receive.
    //
    I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

    //
    // Dummy acknowledge and wait for the receive request from the master.
    // This is done to clear any flags that should not be set.
    //
    while(!(I2CSlaveStatus(I2C0_SLAVE_BASE) & I2C_SLAVE_ACT_TREQ))
    {
    }

    for(ulindex = 0; ulindex < NUM_I2C_DATA; ulindex++)
    {
        //
        // Display the data that I2C0 slave module is transferring.
        //
        UARTprintf("  Sending: '%c'  . . .  ", ulDataTx[ulindex]);

        //
        // Place the data to be sent in the data register
        //
        I2CSlaveDataPut(I2C0_SLAVE_BASE, ulDataTx[ulindex]);

        //
        // Tell the master to read data.
        //
        I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

        //
        // Wait until the slave is done sending data.
        //
        while(!(I2CSlaveStatus(I2C0_SLAVE_BASE) & I2C_SLAVE_ACT_TREQ))
        {
        }

        //
        // Read the data from the master.
        //
        ulDataRx[ulindex] = I2CMasterDataGet(I2C0_MASTER_BASE);

        //
        // Display the data that the slave has received.
        //
        UARTprintf("Received: '%c'\n", ulDataRx[ulindex]);
    }


    //
    // Tell the user that the test is done.
    //
    UARTprintf("\nDone.\n\n");

    //
    // Return no errors
    //
    return(0);
}