Exemplo n.º 1
0
static void i2c_tx_irq(IRQn_Type irq_num, uint32_t index)
{
    i2c_t *obj = i2c_data[index].async_obj;
    if ((REG(SR2.UINT32) & SR2_NACKF)) {
        /* Slave sends NACK */
        i2c_set_err_noslave(obj);
        i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK;
        i2c_abort_asynch(obj);
        ((void (*)())i2c_data[index].async_callback)();
        return;
    }
    if (obj->tx_buff.pos == obj->tx_buff.length) {
        /* All datas have tranferred */
        
        /* Clear TEND */
        REG(SR2.UINT32) &= ~(SR2_TEND);
        
        /* If not repeated start, send stop. */
        if (i2c_data[index].shouldStop && obj->rx_buff.length == 0) {
            (void)i2c_set_STOP(obj);
            (void)i2c_wait_STOP(obj);
            i2c_set_SR2_NACKF_STOP(obj);
            i2c_transfer_finished(obj);
        } else {
            (void)i2c_restart(obj);
            (void)i2c_wait_START(obj);
            /* SR2.START = 0 */
            REG(SR2.UINT32) &= ~SR2_START;
            if (obj->rx_buff.length) {
                /* Ready to read */
                i2c_set_MR3_ACK(obj);
                
                /* Disable INTRIICTEI */
                REG(IER.UINT8[0]) &= ~(1 << 6);
                
                /*  Send Slave address */
                if (i2c_read_address_write(obj, (i2c_data[index].address | 0x01)) != 0) {
                    i2c_set_err_noslave(obj);
                    i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
                    i2c_abort_asynch(obj);
                    ((void (*)())i2c_data[index].async_callback)();
                    return;
                }
            } else {
                i2c_transfer_finished(obj);
            }
        }
    } else {
        /* Send next 1 byte */
        if (i2c_do_write(obj, *(uint8_t *)obj->tx_buff.buffer) != 0) {
            i2c_set_err_noslave(obj);
            i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
            i2c_abort_asynch(obj);
            ((void (*)())i2c_data[index].async_callback)();
            return;
        }
        obj->tx_buff.buffer = (uint8_t *)obj->tx_buff.buffer + 1;
        ++obj->tx_buff.pos;
    }
}
Exemplo n.º 2
0
void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint)
{
    MBED_ASSERT(obj);
    MBED_ASSERT(tx ? tx_length : 1);
    MBED_ASSERT(rx ? rx_length : 1);
    MBED_ASSERT((REG(SER.UINT32) & SER_SAR0E) == 0); /* Slave mode */
    
    obj->tx_buff.buffer = (void *)tx;
    obj->tx_buff.length = tx_length;
    obj->tx_buff.pos = 0;
    obj->tx_buff.width = 8;
    obj->rx_buff.buffer = rx;
    obj->rx_buff.length = rx_length;
    obj->rx_buff.pos = SIZE_MAX;
    obj->rx_buff.width = 8;
    i2c_data[obj->i2c.i2c].async_obj = obj;
    i2c_data[obj->i2c.i2c].async_callback = handler;
    i2c_data[obj->i2c.i2c].event = 0;
    i2c_data[obj->i2c.i2c].shouldStop = stop;
    i2c_data[obj->i2c.i2c].address = address;
    i2c_irqs_set(obj, 1);
    
    /* There is a STOP condition for last processing */
    if (obj->i2c.last_stop_flag != 0) {
        if (i2c_start(obj) != 0) {
            i2c_set_err_noslave(obj);
            i2c_data[obj->i2c.i2c].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
            i2c_abort_asynch(obj);
            ((void (*)())handler)();
            return;
        }
    }
    obj->i2c.last_stop_flag = stop;
    
    if (rx_length && tx_length == 0) {
        /* Ready to read */
        i2c_set_MR3_ACK(obj);
        
        /* Disable INTRIICTEI */
        REG(IER.UINT8[0]) &= ~(1 << 6);
        
        address |= 0x01;
    }
    /* Send Slave address */
    if (i2c_do_write(obj, address) != 0) {
        i2c_set_err_noslave(obj);
        i2c_data[obj->i2c.i2c].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
        i2c_abort_asynch(obj);
        ((void (*)())handler)();
        return;
    }
}
Exemplo n.º 3
0
Arquivo: I2C.cpp Projeto: 0xc0170/mbed
void I2C::abort_transfer(void)
{
    lock();
    i2c_abort_asynch(&_i2c);
    unlock_deep_sleep();
    unlock();
}
Exemplo n.º 4
0
static void i2c_err_irq(IRQn_Type irq_num, uint32_t index)
{
    i2c_t *obj = i2c_data[index].async_obj;
    i2c_abort_asynch(obj);
    i2c_data[index].event = I2C_EVENT_ERROR;
    ((void (*)())i2c_data[index].async_callback)();
}
Exemplo n.º 5
0
static void i2c_rx_irq(IRQn_Type irq_num, uint32_t index)
{
    i2c_t *obj = i2c_data[index].async_obj;
    if (obj->rx_buff.pos == SIZE_MAX) {
        if ((REG(SR2.UINT32) & SR2_NACKF) != 0) {
            /* Slave sends NACK */
            (void)i2c_set_STOP(obj);
            /* dummy read */
            if (REG(DRR.UINT32)) {}
            (void)i2c_wait_STOP(obj);
            i2c_set_SR2_NACKF_STOP(obj);
            obj->i2c.last_stop_flag = 1;
            
            i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK;
            i2c_abort_asynch(obj);
            ((void (*)())i2c_data[index].async_callback)();
            return;
        }
        if (obj->rx_buff.length == 1) {
            /* length == 1 */
            /* Set MR3 WAIT bit is 1 */;
            REG(MR3.UINT32) |=  MR3_WAIT;
            i2c_set_MR3_NACK(obj);
        } else if (obj->rx_buff.length == 2) {
            /* Set MR3 WAIT bit is 1 */
            REG(MR3.UINT32) |= MR3_WAIT;
        }
        /* dummy read */
        if (REG(DRR.UINT32)) {}
        obj->rx_buff.pos = 0;
        return;
    }
    if ((REG(SR2.UINT32) & SR2_NACKF) != 0) {
        /* Slave sends NACK */
        i2c_set_err_noslave(obj);
        i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK;
        i2c_abort_asynch(obj);
        ((void (*)())i2c_data[index].async_callback)();
        return;
    } else {
        switch (obj->rx_buff.length - obj->rx_buff.pos) {
            case 1:
                /* Finished */
                /* If not repeated start, send stop. */
                if (i2c_data[index].shouldStop) {
                    (void)i2c_set_STOP(obj);
                    /* RIICnDRR read */
                    *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF;
                    /* RIICnMR3.WAIT = 0 */
                    REG(MR3.UINT32) &= ~MR3_WAIT;
                    (void)i2c_wait_STOP(obj);
                    i2c_set_SR2_NACKF_STOP(obj);
                } else {
                    (void)i2c_restart(obj);
                    /* RIICnDRR read */
                    *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF;
                    /* RIICnMR3.WAIT = 0 */
                    REG(MR3.UINT32) &= ~MR3_WAIT;
                    (void)i2c_wait_START(obj);
                    /* SR2.START = 0 */
                    REG(SR2.UINT32) &= ~SR2_START;
                }
                
                i2c_transfer_finished(obj);
                return;
                
            case 2:
                i2c_set_MR3_NACK(obj);
                break;
                
            case 3:
                /* this time is befor last byte read */
                /* Set MR3 WAIT bit is 1 */
                REG(MR3.UINT32) |= MR3_WAIT;
                break;
                
            default:
                i2c_set_MR3_ACK(obj);
                break;
        }
        *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF;
        obj->rx_buff.buffer = (uint8_t *)obj->rx_buff.buffer + 1;
        ++obj->rx_buff.pos;
    }
}