Files
TI_C2000_F28377S_FreeRTOS/C2000Ware/utilities/spifsi/spifsi.c
T
2026-08-30 23:04:35 -07:00

451 lines
12 KiB
C

//#############################################################################
//
// FILE: spifsi.c
//
// TITLE: SPI to FSI communication
//
//! \addtogroup spifsi_communication
//
//
//#############################################################################
//
//
//
// C2000Ware v5.04.00.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Includes
//
#include "spifsi.h"
//*****************************************************************************
//
// SPIFSI_readFrame(uint32_t base, SPIFSI_FrameInfo *frameInfo)
// SPIFSI_DID_R_04
//
//*****************************************************************************
SPIFSI_Error SPIFSI_readFrame(uint32_t base, SPIFSI_FrameInfo *frameInfo)
{
//
// Frame sections.
//
uint16_t sof = 0U;
uint16_t frameType = 0U;
uint16_t userData = 0U;
uint16_t crc8 = 0U;
uint16_t frameTag = 0U;
uint16_t eof = 0U;
uint16_t dataLength = 0U;
//
// Temp variables.
//
uint16_t word = 0U;
uint16_t userDataCRC8 = 0U;
uint16_t finalCRC8 = 0U;
uint16_t i;
//
// Error flag.
//
uint16_t readError = SPIFSI_PASS;
//
// Read first word (16 bits) and extract sof and frameType.
//
readError = SPI_read16Bits(base, &word);
//
// Return readError if error occurs from reading.
//
if(readError) {
return(SPIFSI_READ_ERROR);
}
//
// Extract sof and frameType, then populate frameType.
//
sof = (word & SPIFSI_FIRST_BIT_MASK) >> SPIFSI_SHIFT_12;
frameType = (word & SPIFSI_SECOND_BIT_MASK) >> SPIFSI_SHIFT_8;
frameInfo->frameType = (SPIFSI_FrameType) frameType;
//
// Verify sof.
// SPIFSI_DID_R_05
//
if(sof != SPIFSI_START_OF_FRAME)
{
return(SPIFSI_SOF_ERROR);
}
//
// Check frameType.
//
switch(frameType)
{
case SPIFSI_FRAME_TYPE_NWORD_DATA:
//
// If NWORD frame type, given paramenter, nLength,
// is the length of data.
//
//
// Verify nLength
// SPIFSI_DID_R_06
//
if((frameInfo->nLength < SPIFSI_MIN_DATA_WORDS) ||
(frameInfo->nLength > SPIFSI_MAX_DATA_WORDS))
{
return(SPIFSI_N_RANGE_ERROR);
}
dataLength = frameInfo->nLength;
break;
case SPIFSI_FRAME_TYPE_1WORD_DATA:
//
// Initialize dataLength.
//
dataLength = 1U;
break;
case SPIFSI_FRAME_TYPE_2WORD_DATA:
dataLength = 2U;
break;
case SPIFSI_FRAME_TYPE_4WORD_DATA:
dataLength = 4U;
break;
case SPIFSI_FRAME_TYPE_6WORD_DATA:
dataLength = 6U;
break;
case SPIFSI_FRAME_TYPE_ERROR:
case SPIFSI_FRAME_TYPE_PING:
//
// In case of ERROR or PING, check eof, then populate tag.
// SPIFSI_DID_R_07
//
eof = (word & SPIFSI_FOURTH_BIT_MASK);
if(eof != SPIFSI_END_OF_FRAME)
{
return(SPIFSI_EOF_ERROR);
}
//
// Different structure of word for ERROR and PING.
// SPIFSI_DID_R_08
//
frameInfo->frameTag = (SPIFSI_FrameTag)
(word & SPIFSI_THIRD_BIT_MASK) >> SPIFSI_SHIFT_4;
return(SPIFSI_NO_ERROR);
default:
//
// Return frame type error.
// SPIFSI_DID_R_09
//
return(SPIFSI_F_TYPE_ERROR);
}
//
// Extract userData and populate.
// SPIFSI_DID_R_11
//
userData = (word & SPIFSI_LAST_TWO_BITS_MASK);
frameInfo->userData = userData;
//
// Read as many words as data length determined by frameType and nLength.
// SPIFSI_DID_R_14
//
for(i = 0U; i < dataLength; i++)
{
//
// Read and check for error.
//
readError = SPI_read16Bits(base, (frameInfo->data+i));
if(readError)
{
return(SPIFSI_READ_ERROR);
}
}
//
// Read the last word and extract crc, frameTag, and eof.
// SPIFSI_DID_R_15
//
readError = SPI_read16Bits(base, &word);
if(readError)
{
return(SPIFSI_READ_ERROR);
}
crc8 = (word & SPIFSI_FIRST_TWO_BITS_MASK) >> SPIFSI_SHIFT_8;
frameInfo->crc8 = crc8;
frameTag = (word & SPIFSI_THIRD_BIT_MASK) >> SPIFSI_SHIFT_4;
frameInfo->frameTag = (SPIFSI_FrameTag) frameTag;
eof = (word & SPIFSI_FOURTH_BIT_MASK);
//
// Verify eof.
// SPIFSI_DID_R_13
//
if(eof != SPIFSI_END_OF_FRAME)
{
return(SPIFSI_EOF_ERROR);
}
//
// Verify CRC8. First, crc8 check on user data.
// SPIFSI_DID_R_16
//
userDataCRC8 = (uint16_t) SPIFSI_calcCRC8(SPIFSI_CRC8_SEED_0,
&(frameInfo->userData),
SPIFSI_CRC8_DEFAULT_PARITY,
1U);
//
// Second, crc8 check on user data + dataLength * 2
// because number of byte (1 word = 2 bytes).
// SPIFSI_DID_R_17
//
finalCRC8 = (uint16_t) SPIFSI_calcCRC8(userDataCRC8,
(frameInfo->data),
SPIFSI_CRC8_DEFAULT_PARITY,
dataLength * 2U);
//
// Compare crc8
// SPIFSI_DID_R_18
//
if(crc8 != (finalCRC8 & SPIFSI_LAST_TWO_BITS_MASK))
{
return(SPIFSI_CRC_ERROR);
}
//
// No error.
// SPIFSI_DID_R_20
//
return(SPIFSI_NO_ERROR);
}
//*****************************************************************************
//
// SPIFSI_writeFrame(uint32_t base, SPIFSI_frameInfo *frameInfo)
// SPIFSI_DID_W_04
//
//*****************************************************************************
SPIFSI_Error SPIFSI_writeFrame(uint32_t base, SPIFSI_FrameInfo *frameInfo)
{
//
// Initialize temp variables.
//
uint16_t dataLength = 0U;
uint16_t word = 0U;
uint16_t i;
uint16_t userDataCRC8 = 0U;
uint16_t finalCRC8 = 0U;
//
// Error flag.
//
uint16_t writeError = SPIFSI_PASS;
//
// Build a first part of the first ward.
// SPIFSI_DID_W_06
//
word |= SPIFSI_START_OF_FRAME << SPIFSI_SHIFT_12;
word |= (frameInfo->frameType & SPIFSI_FOURTH_BIT_MASK) << SPIFSI_SHIFT_8;
//
// Check frameType.
//
switch(frameInfo->frameType)
{
case SPIFSI_FRAME_TYPE_NWORD_DATA:
//
// Verify nLength
// SPIFSI_DID_W_05
//
if((frameInfo->nLength < SPIFSI_MIN_DATA_WORDS) ||
(frameInfo->nLength > SPIFSI_MAX_DATA_WORDS))
{
return(SPIFSI_N_RANGE_ERROR);
}
//
// If NWORD frame type, given parameter, nLength, is
// the length of data.
//
dataLength = frameInfo->nLength;
break;
case SPIFSI_FRAME_TYPE_1WORD_DATA:
//
// Save dataLength
//
dataLength = 1U;
break;
case SPIFSI_FRAME_TYPE_2WORD_DATA:
dataLength = 2U;
break;
case SPIFSI_FRAME_TYPE_4WORD_DATA:
dataLength = 4U;
break;
case SPIFSI_FRAME_TYPE_6WORD_DATA:
dataLength = 6U;
break;
case SPIFSI_FRAME_TYPE_ERROR:
case SPIFSI_FRAME_TYPE_PING:
//
// For ERROR and PING, build a 16-bit word consisting of sof, frameType,
// frameTag, and eof.
// SPIFSI_DID_W_08
//
word |= (frameInfo->frameTag & SPIFSI_FOURTH_BIT_MASK) << SPIFSI_SHIFT_4;
word |= SPIFSI_END_OF_FRAME;
//
// Send the word and check for error.
// SPIFSI_DID_W_08
//
writeError = SPI_write16Bits(base, &word);
if(writeError)
{
return(SPIFSI_WRITE_ERROR);
}
return(SPIFSI_NO_ERROR);
default:
//
// Return frame type error.
// SPIFSI_DID_W_07
//
return(SPIFSI_F_TYPE_ERROR);
}
//
// Fill in the rest of the first word.
// SPIFSI_DID_W_09
//
word |= (frameInfo->userData & SPIFSI_LAST_TWO_BITS_MASK);
//
// Send/write the first word (sof, frameType, and userData)
// SPIFSI_DID_W_09
//
writeError = SPI_write16Bits(base, &word);
if(writeError)
{
return(SPIFSI_WRITE_ERROR);
}
//
// Send/write data.
// SPIFSI_DID_W_10
//
for(i = 0U; i < dataLength; i++)
{
writeError = SPI_write16Bits(base, (frameInfo->data + i));
if(writeError)
{
return(SPIFSI_WRITE_ERROR);
}
}
//
// Crc8 generation. first, on user data.
// SPIFSI_DID_W_11
//
userDataCRC8 = (uint16_t) SPIFSI_calcCRC8(SPIFSI_CRC8_SEED_0,
&(frameInfo->userData),
SPIFSI_CRC8_DEFAULT_PARITY,
1U);
//
// Second, crc8 check on user data + dataLength * 2
// because number of byte (1 word = 2 bytes).
// SPIFSI_DID_W_12
//
finalCRC8 = (uint16_t) SPIFSI_calcCRC8(userDataCRC8,
(frameInfo->data),
SPIFSI_CRC8_DEFAULT_PARITY,
dataLength * 2U);
//
// Mask finalCRC8.
//
finalCRC8 &= SPIFSI_LAST_TWO_BITS_MASK;
//
// Populate crc8 field of frameInfo.
//
frameInfo->crc8 = finalCRC8;
//
// Construct the last word consisted of crc, tag, and eof.
// SPIFSI_DID_W_13
//
word = 0U;
word |= finalCRC8 << SPIFSI_SHIFT_8;
word |= (frameInfo->frameTag & SPIFSI_FOURTH_BIT_MASK) << SPIFSI_SHIFT_4;
word |= SPIFSI_END_OF_FRAME;
//
// Write/send the last word then check for write error.
// SPIFSI_DID_W_13
//
writeError = SPI_write16Bits(base, &word);
if(writeError)
{
return(SPIFSI_WRITE_ERROR);
}
//
// Return no error.
// SPIFSI_DID_W_14
//
return(SPIFSI_NO_ERROR);
}
//
// End of File
//