📄 upsd_i2c.lst
字号:
412
413 This function is used to receive data from master, only for Slave.
414
415 Data_Ptr - unsigned char*
416 - address pointer of receive buffer
417 N_Ptr - unsigned char*
418 - the length of data buffer received from master.
419
420 return value:
421
422 I2C_TIME_OUT 9 //Indicate I2C overtime.
423 I2C_SR_END 11 //Indicate a receiving has been finished in Slave model
424 I2C_NACK 13 //Indicate I2C no acknowledge
425 I2C_BUSLOST 14 //Indicate I2C bus lost
426 I2C_SX_APP 15 //Indicate I2C Slave is required to transmit data to master
427 I2C_BUSY 16 //Indicate I2C bus is busy
C51 COMPILER V7.20 UPSD_I2C 07/21/2004 17:06:28 PAGE 8
428 -------------------------------------------------------------------------*/
429 unsigned char upsd_i2c_Slave_Recv(unsigned char* Data_Ptr,
430 unsigned char* N_Ptr)
431 {
432 1 EA=0;
433 1 i2c_rcv_buf=Data_Ptr;
434 1 i2c_master = 0;
435 1 i2c_xmitr = 0; // set up for Slave transmitter
436 1 i2c_data_index=0;
437 1 i2c_state=I2C_SR;
438 1 slave_addressed = 0;
439 1 S2CON|=AA;
440 1
441 1 #if IDLE_MODE_DEMO // only here for idle mode demonstration purposes
ET0 = 0; // disable timer 0 int. so only I2C int brings uPSD out of idle mode
PSD8xx_reg.DATAOUT_B&=0xFC; // PB0 & PB1 = 0 - (LEDs on)
#endif
445 1
446 1 EA=1;
447 1
448 1 #if IDLE_MODE_DEMO // only here for idle mode demonstration purposes
PCON |= 0x01; // puts uPSD in idle mode
PSD8xx_reg.DATAOUT_B|=0x03; // PB0 & PB1 = 1 - (LEDs off)
ET0 = 1; // enable timer 0 interrupt
#endif
453 1
454 1 if(upsd_i2c_Timeout(I2C_SR,1000)==1){
455 2 EA=0;
456 2 i2c_state=I2C_TIME_OUT;
457 2 return(i2c_state);
458 2 } //Slave receive timeout
459 1 else {
460 2 EA=0;
461 2 *N_Ptr=i2c_data_index-1;
462 2 return(i2c_state);
463 2 } // Return I2C current state
464 1 }
465 /*------------------------------------------------------------------------
466 I2C Interrupt Service Routine
467 ------------------------------------------------------------------------*/
468
469 void i2c_isr (void) interrupt I2C_VECTOR using 2 {
470 1
471 1 dummybyte=S2STA; // Clear INTR flag
472 1 toggle = 0; // Reset timeout counter
473 1 //------Master transmit operation--------------------------------------------
474 1 if (i2c_master & i2c_xmitr) // mstr transmitter mode
475 1 {
476 2 S2CON &= ~STA; // clear STA
477 2 if ((S2STA & BLOST) !=0) // if bus lost, read dummybyte to turn to Slave mode
478 2 {
479 3 S2DAT=dummy;
480 3 i2c_state=I2C_BUSLOST; // Indicate the bus lost
481 3 return;
482 3 }
483 2 else if ((S2STA & _ACKREP) !=0)
484 2 {
485 3 S2CON |=STO;
486 3 S2DAT=dummy; // if no ACK, send STOP condition to Bus
487 3 i2c_state=I2C_NACK; // Indicate no ACK
488 3 return;
489 3 }
C51 COMPILER V7.20 UPSD_I2C 07/21/2004 17:06:28 PAGE 9
490 2 if((i2c_data_index)<(i2c_data_len-1))
491 2 {
492 3 S2DAT = i2c_xmit_buf[i2c_data_index]; // send data from Master
493 3 i2c_data_index++; // increment data-pointer
494 3 }
495 2 else if((i2c_data_index)==(i2c_data_len-1))
496 2 {
497 3 S2CON |= STO; // set STO (stop bit) for last data byte to send
498 3 S2DAT = i2c_xmit_buf[i2c_data_index]; // send data from Master
499 3 i2c_data_index++;
500 3 }
501 2 else if((i2c_data_index)==(i2c_data_len))
502 2 {
503 3 S2DAT=dummy;
504 3 i2c_state=I2C_MX_END; // Indicate the operation has completed
505 3 }
506 2 }
507 1 //------Master receive operation--------------------------------------------
508 1 if (i2c_master & ~i2c_xmitr) // master receive mode
509 1 {
510 2 S2CON &= ~STA; // clear STA
511 2 if(i2c_data_index<i2c_data_len)
512 2 {
513 3 if((S2CON&AA)==0)
514 3 {
515 4 S2DAT=dummy; //
516 4 if ((dummybyte & _ACKREP) !=0)
517 4 {
518 5 S2CON |=STO;
519 5 i2c_data_index=0;
520 5 S2DAT=dummy;
521 5 i2c_state=I2C_NACK; // indicate no ACK
522 5 return;
523 5 }
524 4 else if(i2c_data_len == 1)
525 4 {
526 5 S2CON&=~AA;
527 5 i2c_data_index ++;
528 5 return;
529 5 }
530 4 else
531 4 {
532 5 S2CON |= AA; // enable ACK
533 5 i2c_data_index ++;
534 5 return;
535 5 }
536 4 }
537 3 else
538 3 {
539 4 // Begin receiving data
540 4 i2c_rcv_buf[i2c_data_index-1] = S2DAT; // receive data
541 4 i2c_data_index++; // increment data-pointer
542 4 if(i2c_data_index==i2c_data_len){S2CON&=~AA;}
543 4 }
544 3 }
545 2 else if(i2c_data_index==i2c_data_len) // End the reception of data
546 2 {
547 3 S2CON |=STO;
548 3 i2c_rcv_buf[i2c_data_index-1] = S2DAT;
549 3 i2c_state=I2C_MR_END; // indicate operation has completed
550 3 }
551 2 }
C51 COMPILER V7.20 UPSD_I2C 07/21/2004 17:06:28 PAGE 10
552 1 //------Slave operation--------------------------------------------
553 1 if(i2c_master==0)
554 1 {
555 2 if(((S2CON&ADDR)!=0)||!i2c_processing) // if ADDR bit is set or if coming out of idle
556 2 { // mode, then a START and address match detected.
557 3 i2c_processing = 1; // indicate processing I2C transaction
558 3 S2CON&=~ADDR; //Clear ADDR flag
559 3 slave_addressed = 1;
560 3 if(dummybyte & TX_MODE)
561 3 {
562 4 i2c_state=I2C_SX_APP; // indicate Slave is required to transmit data to master
563 4 S2CON &= ~AA; // disable ACK
564 4 }
565 3 else
566 3 {
567 4 S2DAT=dummy; // Write dummy
568 4 i2c_xmitr=0; // set up for Slave receive
569 4 S2CON |=AA; // enable ACK to prepare receive data
570 4 i2c_data_index=0;
571 4 i2c_state=I2C_SR; // indicate Slave is receiving
572 4 }
573 3 }
574 2 else
575 2 {
576 3 if(slave_addressed != 1)
577 3 {
578 4 return;
579 4 }
580 3 else if(i2c_xmitr==1) //Slave transmit data
581 3 {
582 4 if(((dummybyte&STOP)!=0)||((dummybyte&_ACKREP)!=0)) //if STOP or NACK received, then master
583 4 // is done reading data from slave.
584 4 {
585 5 S2DAT=dummy;
586 5 i2c_state=I2C_SX_END; // indicate Slave transmitted all data
587 5
588 5 i2c_processing = 0; // indicate not processing I2C transaction
589 5
590 5 }
591 4 else
592 4 {
593 5 S2DAT = i2c_xmit_buf[i2c_data_index]; // Send data
594 5 i2c_data_index++; // Increment data-pointer
595 5 }
596 4 }
597 3 else if(i2c_xmitr==0) // Slave receive data mode
598 3 {
599 4 if((dummybyte & STOP)!=0)
600 4 {
601 5 S2DAT = dummy; // STOP bit received while in slave receiver mode
602 5 S2CON &= ~ENI; // This disable/enable I2C is needed for transfers
603 5 S2CON |= ENI; // from master without data (START-ADDR-WRITE-STOP).
604 5 // This type of transfer is used by a master as a
605 5 // type of device detect. If the slave ACKS, then
606 5 // the device is detected by the master.
607 5 i2c_state = I2C_SR_END; // Indicate the data has been received completely
608 5
609 5 i2c_processing = 0; // indicate not processing I2C transaction
610 5
611 5 S2CON &= ~AA; // Disable ACK.
612 5
613 5 }
C51 COMPILER V7.20 UPSD_I2C 07/21/2004 17:06:28 PAGE 11
614 4 i2c_rcv_buf[i2c_data_index] = S2DAT; // Get data byte from Master
615 4 i2c_data_index++; // increment data-pointer
616 4 }
617 3 }
618 2 }
619 1 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -