예제 #1
0
/**
 * @Function PutChar(char ch)
 * @param ch - the char to be sent out the serial port
 * @return None.
 * @brief  adds char to the end of the circular buffer and forces the interrupt flag 
 * high if nothing is currently transmitting
 * @author Max Dunne, 2011.11.10 */
void PutChar(char ch)
{
    if (getLength(transmitBuffer) != QUEUESIZE) {
        AddingToTransmit = TRUE;
        writeBack(transmitBuffer, ch);
        AddingToTransmit = FALSE;
        if (U1STAbits.TRMT) {
            INTSetFlag(INT_U1TX);
        }
        //re-enter the interrupt if we removed a character while getting another one
        if (TransmitCollisionOccured) {
            INTSetFlag(INT_U1TX);
            TransmitCollisionOccured = FALSE;
        }
    }
}
예제 #2
0
uint8 FIFOI2C_addQueue(uint16 device, uint8 byte_buffer[], FIFOI2C_Device_Commands state_buffer[], uint32 buffer_length)
{
    int i = 0, ind = 0;

    //Check for potential overflow of the TX buffer.
    if ((FIFOI2C_Devices_List[device].transmit_buffer_length + buffer_length) >= (FIFOI2C_TRANSMIT_BUFFER_SIZE - 1))
    {
        return -1;
    }
    else
    {
        //Adds the byte and state buffers to the Device's buffer
        while (i < buffer_length)
        {
            FIFOI2C_TX_Byte txb;
            txb.tx_byte = byte_buffer[i];
            txb.device_command = state_buffer[i];
            ind = FIFOI2C_Devices_List[device].transmit_buffer_length;
            FIFOI2C_Devices_List[device].transmit_buffer[ind] = txb;
            FIFOI2C_Devices_List[device].transmit_buffer_length++;
            i++;
        }

        //If FIFOI2C isn't running, then start it
        if (FIFOI2C_isRunning == 0)
        {
            FIFOI2C_currentDevice = device;
            FIFOI2C_isRunning = 1;
            //Trigger to I2C2 Master IRQ is interrupts are enabled.
            INTSetFlag(INT_I2C2M);
        }
    }
}
예제 #3
0
void UARTPutStr( char *tx_data )
{
    // take the output semaphore
    xSemaphoreTake( outputStringBuffer, portMAX_DELAY );

    // format string for Tx ISR
    sprintf( tx_buffer, "%s", tx_data );

    // set Tx interrupt
    INTSetFlag( INT_U1TX );
}
예제 #4
0
/**
 * @Function GetChar(void)
 * @param None.
 * @return ch - char from the serial port
 * @brief  reads first character from buffer or returns 0 if no chars available
 * @author Max Dunne, 2011.11.10 */
char GetChar(void)
{
    char ch;
    if (getLength(receiveBuffer) == 0) {
        ch = 0;
    } else {
        GettingFromReceive = TRUE;
        ch = readFront(receiveBuffer);
        GettingFromReceive = FALSE;
    }
    //re-enter the interrupt if we added a character while transmitting another one
    if (ReceiveCollisionOccured) {
        INTSetFlag(INT_U1RX);
        ReceiveCollisionOccured = FALSE;
    }
    return ch;
}
예제 #5
0
int FIFOSPI2_pushTxQueue(uint8 data[], int length, int deviceSSLine)
{
    int i = 0;
    //If the send buffer isn't full then add another char
    if ((TxBuffer_Index + length) < FIFOSPI2_BUFFERSIZE)
    {

//        //Adds a token to signify end signal group.
//        SendBufferFlags[SendBuffer_Index + length - 1] = 1;

        //Add each byte to the buffer
        while (i < length)
        {
            //Populate SendBuuferFlags with which device we a re sending to.
            TxBufferFlags[i] = deviceSSLine;
            TxBuffer[TxBuffer_Index++] = data[i];
            i++;
        }

        //If SPI2 IRQ is not running then start it
        if (FIFOSPI2_isRunnning == 0)
        {
            FIFOSPI2_isRunnning = 1;
            
            //If the device is on and ready to send
            if (SPI2CONbits.ON == 1)
            {
                //Start sending
                INTSetFlag(INT_SPI2TX);
                INTEnable(INT_SPI2TX, INT_ENABLED);
            }
        }

        return 1;
    }
    //Overflow error
    else
    {
        return -1;
    }
}
예제 #6
0
UINT8 FIFOI2C2_pushTxQueue(UINT16 device, UINT8 byte_buffer[], FIFOI2C2_Device_Commands state_buffer[], UINT32 buffer_length)
{
    int i = 0, ind = 0;
    FIFOI2C2_TX_Byte txb;

    //Check for potential overflow of the TX buffer.
    if ((FIFOI2C2_Devices_List[device].transmit_buffer_length + buffer_length) >= (FIFOI2C2_TRANSMIT_BUFFER_SIZE - 1))
    {
        return -1;
    }
    else
    {
        //Adds the byte and state buffers to the Device's transmit buffer
        while (i < buffer_length)
        {
            //Selects this i-th byte
            txb.tx_byte = byte_buffer[i];
            //Selects the i-th command
            txb.device_command = state_buffer[i];
            //Sets the index to the current device's transmit buffer length
            ind = FIFOI2C2_Devices_List[device].transmit_buffer_length;
            //transfer the byte to the current devices buffer
            FIFOI2C2_Devices_List[device].transmit_buffer[ind] = txb;
            FIFOI2C2_Devices_List[device].transmit_buffer_length++;
            i++;
        }

        //If FIFOI2C2 isn't running, then start it
        if (FIFOI2C2_isRunning == 0)
        {
            FIFOI2C2_currentDevice = device;
            FIFOI2C2_isRunning = 1;
            //Trigger to I2C2 Master IRQ is interrupts are enabled.
            INTSetFlag(INT_I2C2M);
        }
    }

    return 1;
}
예제 #7
0
//******************************************************************************
//Interrupt Request Routines
//******************************************************************************
void __ISR(_I2C_2_VECTOR, IPL5AUTO) __I2C2Interrupt(void)
{

    int i = 0;
    int ind = 0, ind2 = 0;
    FIFOI2C2_RX_Byte rxb;

    if (INTGetFlag(INT_I2C2B)) //Bus Collision
    {
        INTClearFlag(INT_I2C2B);

        //TODO: Set an error, or reset the transmission.
    }
    if (INTGetFlag(INT_I2C2M)) //Master Intterupt
    {
        INTClearFlag(INT_I2C2M);

        //If we have received a byte, read it.
        if (FIFOI2C2_nextInterruptReceive == 1)
        {
            //Setup indexes (easier to read)
            ind = FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer_current;
            ind2 = FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].receive_buffer_length;

            //Read the received byte and the current command we are on.
            rxb.device_command = FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer[ind].device_command;
            //read the transmitted byte
            rxb.rx_byte = I2C2RCV;

            //Write rxb to the receive buffer
            FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].receive_buffer[ind2] = rxb;

            //increment indexes
            FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].receive_buffer_length++;
            FIFOI2C2_nextInterruptReceive = 0;
        }

        //Switch statement for the current_device's transmit byte's device_state
        ind = FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer_current;
        switch(FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer[ind].device_command)
        {
            case FIFOI2C2_DEVICE_COMMAND_CMDERROR:
                ind = 0; //filler
                break;
            case FIFOI2C2_DEVICE_COMMAND_START:
                I2C2CONbits.SEN = 1;    //start condition sequence
                break;
            case FIFOI2C2_DEVICE_COMMAND_TX_BYTE:
                I2C2TRN = FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer[ind].tx_byte; //transmit byte
                break;
            case FIFOI2C2_DEVICE_COMMAND_RESTART:
                I2C2CONbits.RSEN = 1;   //repeated start condition sequence
                break;
            case FIFOI2C2_DEVICE_COMMAND_RX_BYTE:
                I2C2CONbits.RCEN = 1;   //Receive byte sequence
                //Flag for next intr to be for receiving said byte
                FIFOI2C2_nextInterruptReceive = 1;
                break;
            case FIFOI2C2_DEVICE_COMMAND_ACK:
                I2C2CONbits.ACKDT = 0;  //ACK
                I2C2CONbits.ACKEN = 1;  //Send ACK sequence
                break;
            case FIFOI2C2_DEVICE_COMMAND_NACK:
                I2C2CONbits.ACKDT = 1;  //NACK
                I2C2CONbits.ACKEN = 1;  //Send NACK sequence
                break;
            case FIFOI2C2_DEVICE_COMMAND_STOP:
                I2C2CONbits.PEN = 1;  //Stop routine
                break;
            case FIFOI2C2_DEVICE_COMMAND_CMDEND:
                //Loop through all devices and check if they have something (or more somethings) to send.

                //Check Current Device first
                if ((FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer_current + 1) >=
                        FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer_length)
                {
                    //Turn off I2C IRq routine
                    FIFOI2C2_isRunning = 0;

                    //Reset transmit indexes
                    FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer_current = 0;
                    FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer_length = 0;

                    //Check other devices now
                    while (i < FIFOI2C2_DEVICES_COUNT)
                    {
                        //If not this device (since we already checked it)
                        if (i != FIFOI2C2_currentDevice)
                        {
                            if(FIFOI2C2_Devices_List[i].transmit_buffer_length >
                                    FIFOI2C2_Devices_List[i].transmit_buffer_current) //If they have something to send
                            {
                                //Set device as the current device
                                FIFOI2C2_currentDevice = i;
                                //Turn back on FIFOI2C2
                                FIFOI2C2_isRunning = 1;
                                //Kick-Start Operation
                                INTSetFlag(INT_I2C2M);
                            }
                        }
                        i++;
                    }

                    //Done so quit routine.
                    return;
                }
                else
                {
                    //Keep it running
                    INTSetFlag(INT_I2C2M);
                }

                break;

            default:
                break;
        }

        //Increment next cmd to tx
        FIFOI2C2_Devices_List[FIFOI2C2_currentDevice].transmit_buffer_current++;
    }

}
예제 #8
0
//******************************************************************************
//Interrupt Request Routines
//******************************************************************************
void __ISR(_SPI_2_VECTOR, IPL4AUTO)__SPI2Interrupt(void)
{
    
    //Receive interupt
    if (INTGetFlag(INT_SPI2RX))
    {
        //If it's RX's turn
        if (isTransmitsTurn == 0) 
        {
            //Set the flag so it's TX's turn next
            isTransmitsTurn = 1;

            //Read byte from buffer
            RxBuffer[RxBuffer_Index++] = SPI2BUF;

            //Clear Interrupt flag
            INTClearFlag(INT_SPI2RX);


            //If the current device we are sending to doesn't match the next byte's device
            if (TxBufferFlags[TxBuffer_TxIndex] != TxBufferFlags[TxBuffer_TxIndex -1])
            {
                //TODO: decide if it's better just to deselect all devices.
                //Deselect the current device
                switch (TxBufferFlags[RxBuffer_Index - 1])
                {
                        case 0:
                            FIFOSPI2_DeviceSSLine1_PortReg = 1;
                            FIFOSPI2_DeviceSSLine2_PortReg = 1;
                            break;
                        case 1:
                             FIFOSPI2_DeviceSSLine1_PortReg = 1; //Hi to deselect
                             break;
                        case 2:
                             FIFOSPI2_DeviceSSLine2_PortReg = 1; //Hi to deselect
                             break;
                }
            }

            //If their are bytes to send
            if (TxBuffer_Index > TxBuffer_TxIndex)
            {
                //Set the TX Interupt flag so that it can send them
                INTSetFlag(INT_SPI2TX);
                INTEnable(INT_SPI2TX, INT_ENABLED);
            }
            else
            {
                //Clear and disable the TX interupt
                INTEnable(INT_SPI2TX, INT_DISABLED);
                INTClearFlag(INT_SPI2TX);
                
                
                //update the flag that it's not running anymore.
                FIFOSPI2_isRunnning = 0;
                //Clear the Send Buffer indecies
                TxBuffer_TxIndex = 0;
                TxBuffer_Index = 0;
            }

        }
        
    }

    //Transmit interrupt and it is enabled.
    if (INTGetFlag(INT_SPI2TX) && INTGetEnable(INT_SPI2TX))
    {
        //Clear Interrupt flag
        //INTClearFlag(INT_SPI2TX);
        INTEnable(INT_SPI2TX, INT_DISABLED);

        //If it's TX's turn
        if (isTransmitsTurn == 1)
        {
            //Set the flag so it's RX's turn next
            isTransmitsTurn = 0;

//            //Select the current device
//            FIFOSPI2_DeviceSSLine1 = 0;
            //Select the current device
            switch (TxBufferFlags[TxBuffer_TxIndex])
            {
                    case 1:
                         FIFOSPI2_DeviceSSLine1_PortReg = 0; //Low to select
                         break;
                    case 2:
                         FIFOSPI2_DeviceSSLine2_PortReg = 0; //Low to select
                         break;
            }

            //Send the next byte
            SPI2BUF = TxBuffer[TxBuffer_TxIndex++];
        }
    }
}
예제 #9
0
//=============================================
// Configure the I2C4 interrupt handler
//=============================================
void __ISR(_I2C_4_VECTOR, I2C4_INT_PRIORITY) I2c4InterruptHandler(void)
{
  sI2cCmdBuffer_t masterData;
  
  if (INTGetFlag(INT_I2C4B))  //Bus Collision interrupt
  {
    INTClearFlag(INT_I2C4B);
  }
  
  if (INTGetFlag(INT_I2C4M))  // Master interrupt
  {
    INTClearFlag(INT_I2C4M);

    if (I2c.Var.oReadDataInNextInterrupt[I2C4])   // If a read was started last interrupt
    {
      masterData.data  = I2C4RCV;   // Read from I2C buffer
      masterData.state = I2C_MASTER_RECEIVE_DATA;
      I2cFifoWrite((void *) &I2c.Var.i2cUserFifo[I2C4], &masterData);
      I2c.Var.oRxDataAvailable[I2C4] = 1;
      I2c.Var.oReadDataInNextInterrupt[I2C4] = 0;
    }
    
    if (I2c.Var.oI2cWriteIsRunning[I2C4])
    {
      I2cFifoRead((void *) &I2c.Var.i2cWriteQueue[I2C4], &masterData);
      switch (masterData.state)
      {
      //======================================================  
        case I2C_MASTER_RECEIVE_DATA : 
          I2C4CONbits.RCEN = 1;                         //Receive byte sequence
          I2c.Var.oReadDataInNextInterrupt[I2C4] = 1;   // Flag for the next interrupt to read the rx buffer
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_START_CONDITION : 
          I2C4CONbits.SEN = 1;                          //start condition sequence
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_STOP_CONDITION : 
          I2C4CONbits.PEN = 1;
          
          if (I2c.Var.oPoolSlaveAcknowledge[I2C4])
          {
            if (!I2c.Var.oSecondStopAfterPooling[I2C4])
            {
              masterData.state = I2C_MASTER_START_CONDITION;
              I2cFifoWrite((void *) &I2c.Var.i2cWriteQueue[I2C4], &masterData);
              
              masterData.state = I2C_MASTER_TRANSMIT_DATA;
              I2cFifoWrite((void *) &I2c.Var.i2cWriteQueue[I2C4], &masterData);
              
              masterData.state = I2C_MASTER_STOP_CONDITION;
              I2cFifoWrite((void *) &I2c.Var.i2cWriteQueue[I2C4], &masterData);
              
              I2c.Var.oSecondStopAfterPooling[I2C4] = 1;
            }
            else
            {
              if (!I2CByteWasAcknowledged(I2C4))
              {
                masterData.state = I2C_MASTER_START_CONDITION;
                I2cFifoWrite((void *) &I2c.Var.i2cWriteQueue[I2C4], &masterData);

                masterData.state = I2C_MASTER_TRANSMIT_DATA;
                I2cFifoWrite((void *) &I2c.Var.i2cWriteQueue[I2C4], &masterData);

                masterData.state = I2C_MASTER_STOP_CONDITION;
                I2cFifoWrite((void *) &I2c.Var.i2cWriteQueue[I2C4], &masterData);
              }
              else
              {
                masterData.state = I2C_MASTER_DONE;
                I2cFifoWrite((void *) &I2c.Var.i2cWriteQueue[I2C4], &masterData);
                I2c.Var.oSecondStopAfterPooling[I2C4] = 0;
              }
            }
          }
          break;
      //====================================================== 

      //======================================================    
        case I2C_MASTER_TRANSMIT_DATA : 
          I2C4TRN = masterData.data;
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_DONE : 
          if (I2c.Var.i2cWriteQueue[I2C4].bufEmpty)   // Nothing more to send
          {
            I2c.Var.oI2cWriteIsRunning[I2C4] = 0;       // Turn off writing process
          }
          else
          {
            INTSetFlag(INT_I2C4M);                    // Start another writing process
          }
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_REPEAT_START : 
          I2C4CONbits.RSEN = 1;   //repeated start condition sequence
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_SLAVE_SENT_STOP :
          LED_ERROR_ON;
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_SEND_ACK : 
          I2C4CONbits.ACKDT = 0;  //ACK
          I2C4CONbits.ACKEN = 1;  //Send ACK sequence
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_SEND_NACK : 
          I2C4CONbits.ACKDT = 1;  //NACK
          I2C4CONbits.ACKEN = 1;  //Send NACK sequence
          break;
      //====================================================== 

      //======================================================  
        case I2C_CMD_ERROR : 
          LED_ERROR_ON;
          break;
      //====================================================== 

      //======================================================  
        default : 
          break;
      //======================================================  
      } // end switch
    } // end if
    
    

    if (I2c.Var.oI2cReadIsRunning[I2C4])
    {
      I2cFifoRead((void *) &I2c.Var.i2cReadQueue[I2C4], &masterData);
      switch (masterData.state)
      {
      //======================================================  
        case I2C_MASTER_RECEIVE_DATA : 
          I2C4CONbits.RCEN = 1;   //Receive byte sequence
          I2c.Var.oReadDataInNextInterrupt[I2C4] = 1;
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_START_CONDITION : 
          I2C4CONbits.SEN = 1;    //start condition sequence
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_REPEAT_START : 
          I2C4CONbits.RSEN = 1;   //repeated start condition sequence
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_STOP_CONDITION : 
          I2C4CONbits.PEN = 1;
          break;
      //====================================================== 

      //======================================================    
        case I2C_MASTER_TRANSMIT_DATA : 
          I2C4TRN = masterData.data;
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_DONE : 
          if (I2c.Var.i2cReadQueue[I2C4].bufEmpty)            // Nothing more to send
          {
            I2c.Var.oI2cReadIsRunning[I2C4] = 0;              // Turn off reading process
          }
          else
          {
            INTSetFlag(INT_I2C4M);                    // Start another reading process
          }
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_SLAVE_SENT_STOP :
          LED_ERROR_ON;
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_SEND_ACK : 
          I2C4CONbits.ACKDT = 0;  //ACK
          I2C4CONbits.ACKEN = 1;  //Send ACK sequence
          break;
      //====================================================== 

      //======================================================  
        case I2C_MASTER_SEND_NACK : 
          I2C4CONbits.ACKDT = 1;  //NACK
          I2C4CONbits.ACKEN = 1;  //Send NACK sequence
          break;
      //====================================================== 

      //======================================================  
        case I2C_CMD_ERROR : 
          LED_ERROR_ON;
          break;
      //======================================================

      //======================================================  
        default : 
          break;
      //======================================================  
      } // end switch
    } // end if
  }  // end if
}   // end if