Advertisement
Guest User

Untitled

a guest
Oct 16th, 2019
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.88 KB | None | 0 0
  1.  
  2. void Task_I2C_Server_FSM(void)
  3. {
  4.     static enum {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11} next_state = S0;
  5.     static uint8_t dummy, num_bytes_read=0, is_last_read=0;
  6.     SET_BIT(DEBUG_I2C_CODE);                    //  set i2c bit high
  7.     switch(next_state)
  8.     {
  9.         case S0:
  10.             // Initial function checks
  11.             if(g_I2C_Msg.Command != READ && g_I2C_Msg.Status == IDLE)
  12.             {
  13.                 CLEAR_BIT(DEBUG_I2C_CODE);                  //  set i2c bit low
  14.                 return;
  15.             }
  16.             else if(g_I2C_Msg.Command == READ)
  17.             {
  18.                 g_I2C_Msg.Status = READING;
  19.                 I2C_TRAN;                                                   //  set to transmit mode       
  20.                 SET_BIT(DEBUG_MSG_ON_BUS);              //  set msg on bus bit high        
  21.                 I2C_M_START;                                            //  send start     
  22.                 I2C0->D = g_I2C_Msg.Dev_adx;                                //  send dev address (write)
  23.                 lock_detect = 0;
  24.                 next_state = S1;
  25.             }
  26.             else
  27.             {
  28.                 next_state = S11;
  29.             }
  30.             break;
  31.         case S1:
  32.             //  check for completion
  33.             SET_BIT(DEBUG_I2C_BUSY_WAIT);               //  set i2c busy-wait bit high
  34.             while( ( ( I2C0->S & I2C_S_IICIF_MASK ) == 0 ) & ( lock_detect < LOCK_DETECT_THRESHOLD )) {
  35.                 lock_detect++;
  36.                 next_state = S1;
  37.             }
  38.             //else
  39.             //{
  40.                 next_state = S2;
  41.             //}
  42.             CLEAR_BIT(DEBUG_I2C_BUSY_WAIT);             //  set i2c busy-wait bit low
  43.             break;
  44.         case S2:
  45.             I2C0->S |= I2C_S_IICIF_MASK;
  46.             CLEAR_BIT(DEBUG_I2C_BUSY_WAIT);             //  set i2c busy-wait bit low
  47.             I2C0->D = g_I2C_Msg.Reg_adx;                                //  send register address
  48.             lock_detect = 0;
  49.             next_state = S3;
  50.             break;
  51.         case S3:
  52.             //  check for completion
  53.             SET_BIT(DEBUG_I2C_BUSY_WAIT);               //  set i2c busy-wait bit high
  54.             while( ( ( I2C0->S & I2C_S_IICIF_MASK ) == 0 ) & ( lock_detect < LOCK_DETECT_THRESHOLD )) {
  55.                 lock_detect++;
  56.                 next_state = S3;
  57.             }
  58.             //else
  59.             //{
  60.                 next_state = S4;
  61.             //}
  62.             CLEAR_BIT(DEBUG_I2C_BUSY_WAIT);             //  set i2c busy-wait bit low
  63.             break;
  64.         case S4:
  65.             I2C0->S |= I2C_S_IICIF_MASK;
  66.             CLEAR_BIT(DEBUG_I2C_BUSY_WAIT);             //  set i2c busy-wait bit low
  67.             I2C_M_RSTART;                                           //  repeated start                                 
  68.             I2C0->D = g_I2C_Msg.Dev_adx | 0x01 ;                //  send dev address (read)
  69.             lock_detect = 0;
  70.             next_state = S5;
  71.             break;
  72.         case S5:
  73.             //  check for completion
  74.             SET_BIT(DEBUG_I2C_BUSY_WAIT);               //  set i2c busy-wait bit high
  75.             while( ( ( I2C0->S & I2C_S_IICIF_MASK ) == 0 ) & ( lock_detect < LOCK_DETECT_THRESHOLD )) {
  76.                 lock_detect++;
  77.                 next_state = S5;
  78.             }
  79.             //else
  80.             //{
  81.                 next_state = S6;
  82.             //}
  83.             CLEAR_BIT(DEBUG_I2C_BUSY_WAIT);             //  set i2c busy-wait bit low
  84.             break;
  85.         case S6:
  86.             I2C0->S |= I2C_S_IICIF_MASK;
  87.             I2C_REC;                                                    //  set to receive mode
  88.             next_state = S7;
  89.             break;
  90.         case S7:
  91.             if(num_bytes_read < g_I2C_Msg.Data_count)
  92.             {
  93.                 next_state = S8;
  94.             }
  95.             else
  96.             {
  97.                 g_I2C_Msg.Status = READ_COMPLETE;
  98.                 next_state = S11;
  99.             }
  100.             break;
  101.         case S8:
  102.             is_last_read = (num_bytes_read == g_I2C_Msg.Data_count-1)? 1: 0;
  103.             if (is_last_read){
  104.                 NACK;                                                   // tell HW to send NACK after read                         
  105.             } else {
  106.                 ACK;                                                    // tell HW to send ACK after read                              
  107.             }
  108.             dummy = I2C0->D;                                //  dummy read
  109.             next_state = S9;
  110.             break;
  111.         case S9:
  112.             //  check for completion
  113.             SET_BIT(DEBUG_I2C_BUSY_WAIT);               //  set i2c busy-wait bit high
  114.             while( ( ( I2C0->S & I2C_S_IICIF_MASK ) == 0 ) & ( lock_detect < LOCK_DETECT_THRESHOLD )) {
  115.                 lock_detect++;
  116.                 next_state = S9;
  117.             }
  118.             //else
  119.             //{
  120.                 next_state = S10;
  121.             //}
  122.             CLEAR_BIT(DEBUG_I2C_BUSY_WAIT);             //  set i2c busy-wait bit low
  123.             break;
  124.         case S10:
  125.             I2C0->S |= I2C_S_IICIF_MASK;
  126.             if (is_last_read){
  127.                 I2C_M_STOP;                                     //  send stop
  128.                 CLEAR_BIT(DEBUG_MSG_ON_BUS);        //  set msg on bus bit low
  129.             }
  130.             data[num_bytes_read++] = I2C0->D; //    read data  
  131.             next_state = S7;
  132.             break;
  133.         case S11:
  134.             CLEAR_BIT(DEBUG_I2C_CODE);                  //  set i2c bit low
  135.             next_state = S0;
  136.             return;
  137.         default:
  138.             return;
  139.     }
  140.     CLEAR_BIT(DEBUG_I2C_CODE);                  //  set i2c bit low
  141. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement