/** * @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; } } }
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); } } }
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 ); }
/** * @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; }
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; } }
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; }
//****************************************************************************** //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++; } }
//****************************************************************************** //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++]; } } }
//============================================= // 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