static void I2CM_IRQHandler(uint32_t instance) { i2c_master_t *im = &i2c_master_state[instance]; mxc_i2cm_regs_t *regs = MXC_I2CM_GET_I2CM(instance); mxc_i2cm_intfl_t intfl = regs->intfl_f; mxc_i2cm_inten_t inten = regs->inten_f; regs->intfl_f = intfl; if(intfl.tx_done && inten.tx_done) { if(!im->bytes_left) { if(im->stop_bit) { I2CM_WriteToTxFifo(im->index, MXC_S_I2CM_TRANS_TAG_STOP); } inten.tx_done = 0; regs->inten_f = inten; im->buf = NULL; if(im->callback_fn) { im->callback_fn(0); } } else { do_xmit(im); } } if((intfl.rx_fifo_not_empty || intfl.rx_fifo_full || intfl.rx_fifo_2q_full || intfl.rx_fifo_3q_full ) && inten.rx_fifo_empty) { volatile uint16_t *rx_fifo = (uint16_t *)(MXC_I2CM_GET_BASE_FIFO(im->index) + 0x800); uint8_t bytes_to_read = regs->bb_f.rx_fifo_cnt; uint32_t i; if(im->bytes_index < im->bytes_left) { for(i = 0; i < bytes_to_read; i++) { im->buf[im->bytes_index++] = *rx_fifo; } } if(im->bytes_index == im->bytes_left) { inten = regs->inten_f; inten.rx_fifo_2q_full = 0; inten.rx_fifo_3q_full = 0; inten.rx_fifo_full = 0; inten.rx_fifo_empty = 0; regs->inten_f = inten; im->buf = NULL; if(im->callback_fn) { im->callback_fn(im->bytes_index); } } } }
/* ** Send an end of job indication to the client. */ void reply_eoj(int sesfd) { int paperr; DODEBUG_WRITEBUF(("reply_eoj(sesfd=%d)", sesfd)); /* Completely drain output buffer. */ while(ocount || wcomp) { while(wcomp > 0) abSleep(4,TRUE); do_xmit(sesfd); } /* Send the EOJ packet. */ if( (paperr=PAPWrite(sesfd,"",0,TRUE,&wcomp)) != 0) fatal(1,"reply_eoj(): PAPWrite() returned %d",paperr); /* Wait for write to complete. */ do { abSleep(4,TRUE); } while(wcomp > 0); /* See if write failed. */ if(wcomp < 0) fatal(1,"PAPWrite() completed with error %d",wcomp); } /* end of reply_eoj() */
/* ** Get a character from the client. */ int cli_getc(int sesfd) { int paperr; while(bytesleft==0) /* If buffer empty, */ { /* here is where we fill it. */ if(onebuffer && buffer_count) /* If one buffer mode and one */ return -1; /* read done, don't read more. */ if(eoj) /* If end of job, don't */ return -1; /* try any more. */ buffer_count++; /* Add to count of buffers read. */ DODEBUG_READBUF(("cli_getc(): attempting to read")); if( (paperr=PAPRead(sesfd, readbuf, &bytestotal, &eoj, &rcomp)) != 0) { debug("cli_getc(): PAPRead() returned %d, rcomp=%d", paperr, rcomp); eoj=1; return -1; } DODEBUG_READBUF(("cli_getc(): waiting for read to complete")); do { /* wait for the read to complete */ do_xmit(sesfd); /* allow output routine to work */ abSleep(1,TRUE); } while(rcomp > 0); DODEBUG_READBUF(("done, eoj=%d", eoj)); if(rcomp < 0) /* if read completed with error, */ { if(rcomp==sktClosed) { DODEBUG_READBUF(("cli_getc(): other party hung up first")); eoj = 1; return -1; } else { fatal(1, "cli_getc(): PAPRead() completed with code %d", rcomp); } } bytesleft = bytestotal; /* set initial value of bytesleft */ cptr = readbuf; /* move pointer to begining of buffer */ } /* ** If we get this far, we know there ** are bytes in the buffer. */ bytesleft--; /* take a byte */ return *(cptr++); /* from the buffer */ } /* end of cli_getc() */
static int32_t I2CM_TxAsync(i2c_master_t *im) { mxc_i2cm_regs_t *regs = MXC_I2CM_GET_I2CM(im->index); mxc_i2cm_inten_t inten = regs->inten_f; regs->intfl = 0x3FF; inten.tx_done = 1; regs->inten_f = inten; NVIC_EnableIRQ(MXC_I2CM_GET_IRQ(im->index)); if(I2CM_WriteToTxFifo(im->index, (MXC_S_I2CM_TRANS_TAG_START | im->addr))) { /* start + addr (write) */ return -1; } mxc_i2cm_trans_t trans = regs->trans_f; /* start the transaction if it wasn't already started */ if (!trans.tx_in_progress) { trans.tx_start = 1; regs->trans_f = trans; } do_xmit(im); return 0; }