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