Integrator Resources

The official home for NAI Support

Not sure where to start? Try Quick Start Guide or ask a question below!

Toggle Components with Visual Button
JavaScript Form Processing

SER SCM Recv

SER SCM Recv Sample Application (SSK 2.x)

Overview

The SER SCM Recv sample application demonstrates how to receive Manchester-encoded packets via the SCM module’s channel 1 using the NAI Software Support Kit (SSK 2.x). The application enables the channel and receiver, then enters a loop that reads packets from the receive FIFO on demand. Each packet consists of a header word (containing the data word count), a variable number of data words, a CTW (Command/Time Word), and an OVPW (Overhead/Protocol Word).

This sample is exclusive to the SCM module. It is designed to work as the receiving half of a two-application pair — run the SER SCM Xmit sample to transmit packets that this application will receive.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with an SCM module installed.

  • SSK 2.x installed on your development host.

  • The sample applications built. Refer to the SSK 2.x Software Development Guide for platform-specific build instructions.

  • A Manchester-encoded link between the transmitter and receiver (or use the companion SER SCM Xmit sample on the same board).

How to Run

Launch the ser_scm_recv executable from your build output directory. On startup the application looks for a configuration file (default_SerSCM_recv.txt). Once connected and the module is verified as SCM, the application enables channel 1 and enters a receive loop.

Board Connection and Module Selection

Note
This startup sequence is common to all NAI sample applications.

The main() function follows a standard SSK 2.x startup flow. After connecting to the board and selecting a module, the application verifies that the module ID is NAIBRD_MODULE_ID_SCM. If not, it prints an error and returns to the menu.

check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
if ((moduleID == NAIBRD_MODULE_ID_SCM))
{
   Run_SER_SCM_Recv(cardIndex, module);
}
else
{
   naiif_printf("\r\nThis sample app can only be run on SCM\r\n");
}
Important
  • Module not SCM — this application only supports the SCM module.

  • No board found — verify that the board is powered on and physically connected.

Program Structure

Entry Point

The entry point is main() on most platforms, or SER_SCM_Recv_Sample() on VxWorks.

Application Flow

  1. Reset channel 1 and clear both FIFOs.

  2. Enable the channel and receiver.

  3. Enter a receive loop that reads packets on user command.

Channel Setup

The application uses a fixed channel (channel 1) and enables it for reception:

const int32_t CHAN = 1;

naibrd_SER_ChannelReset(cardIndex, module, CHAN);
naibrd_SER_ClearRxFifo(cardIndex, module, CHAN);
naibrd_SER_ClearTxFifo(cardIndex, module, CHAN);

check_status(naibrd_SER_SetChannelEnable(cardIndex, module, CHAN, 1));
check_status(naibrd_SER_SetReceiverEnable(cardIndex, module, CHAN, NAI_TRUE));

Packet Reception

Each time the user presses Enter, the application checks the receive FIFO count and reads a packet in two steps:

  1. Read the first word (header) to determine the packet size.

  2. Read the remaining words based on the header value.

naibrd_SER_GetRxBufferCnt(cardIndex, module, CHAN, (uint32_t*)&numWordsToRead);

if(numWordsToRead == 0)
{
   naiif_printf("\r\nNo data received\r\n");
   continue;
}

naibrd_SER_ReceiveBufferWithTimeOut32(cardIndex, module, CHAN, RecvPacket, MAX_PACKET_SIZE, 1,
   NAIBRD_FIFO_TIMEOUT_NONE, &numWordsToRead);

packetSize = RecvPacket[0] + 3;

status = naibrd_SER_ReceiveBufferWithTimeOut32(cardIndex, module, CHAN, RecvPacket + 1, MAX_PACKET_SIZE - 1, packetSize - 1,
   NAIBRD_FIFO_TIMEOUT_NONE, &numWordsToRead);

The header word (RecvPacket[0]) contains the number of data words. The total packet size is data_words + 3 (header + data words + CTW + OVPW).

Packet Display

The Print_Packet() function displays the packet contents:

void Print_Packet(uint32_t *packet, uint32_t size)
{
   uint32_t i;
   uint32_t numDataWords = size - 3;

   naiif_printf("\r\nHeader: 0x%02X\r\n", packet[0] & 0x1F);
   for(i = 0; i < numDataWords; i++)
   {
      naiif_printf("Data[%u]: 0x%08X\r\n", i, packet[1 + i]);
   }
   naiif_printf("CTW: 0x%08X\r\n", packet[size - 2]);
   naiif_printf("OVPW: 0x%08X\r\n", packet[size - 1]);
}
  • Header — the lower 5 bits contain the data word count (max 29).

  • Data words — the payload, up to 29 words.

  • CTW — Command/Time Word.

  • OVPW — Overhead/Protocol Word.

Troubleshooting Reference

Error / Symptom Possible Causes Suggested Resolution

Module not SCM

A non-SCM module is installed

This application only supports the SCM module.

No data received

Transmitter not running, cable not connected

Ensure the SER SCM Xmit sample is running and transmitting.

Partial packet received

Packet not fully received, FIFO read too early

Press Enter again to read remaining data.

Error receiving packet

FIFO underflow or packet corruption

Check the status returned by naibrd_SER_ReceiveBufferWithTimeOut32().

No board found or connection timeout

Board not powered, incorrect configuration file

Verify hardware is powered and connected.

Full Source

The complete source for this sample is provided below for reference.

Full Source — ser_scm_recv.c (SSK 2.x)
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"

/* naibrd include files */
#include "nai_libs/naibrd/include/naibrd.h"
#include "nai_libs/naibrd/include/functions/naibrd_ser.h"

/* naiif include files */
#include "nai_libs/naiif/include/naiif_stdio.h"

/* Common Sample Program include files */
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_menu.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_query.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_access.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_display.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_utils.h"

static const int8_t *CONFIG_FILE = (const int8_t *)"default_SerSCM_recv.txt";

#define MAX_NUM_DATA_WORDS 29  /* Maximum number of data words in a packet */
#define MAX_PACKET_SIZE    (MAX_NUM_DATA_WORDS + 3)

/* Function prototypes */
void Run_SER_SCM_Recv(int32_t cardIndex, int32_t module);

/**************************************************************************************************************/
/** \defgroup SERSCMRecv
 * Receives packets via SCM's channel 1 Manchester-encoded packet link.
 *
 * Only works on SCM.
*/
/**************************************************************************************************************/
#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t SER_SCM_Recv_Sample(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = NAI_FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         /* Query the user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Query the user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               if ((moduleID == NAIBRD_MODULE_ID_SCM))
               {
                  Run_SER_SCM_Recv(cardIndex, module);
               }
               else
               {
                  naiif_printf("\r\nThis sample app can only be run on SCM\r\n");
               }
            }
         }

         naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   naiif_printf("\r\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();

   return 0;
}

static void Print_Packet(uint32_t *packet, uint32_t size);

/**************************************************************************************************************/
/** \ingroup SERSCMRecv
\param cardIndex (Input) Logical Card Index assigned to connection with the NAI_BOARD (0 - NAI_MAX_CARDS-1).
\param module    (Input) Module Number of the module to access (1 - [max modules for board]).
*/
/**************************************************************************************************************/
void Run_SER_SCM_Recv(int32_t cardIndex, int32_t module)
{
   const int32_t CHAN = 1;
   int32_t i;
   uint32_t RecvPacket[MAX_PACKET_SIZE];
   int32_t numWordsToRead = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   uint32_t packetSize;
   nai_status_t status;

   naibrd_SER_ChannelReset(cardIndex, module, CHAN);
   naibrd_SER_ClearRxFifo(cardIndex, module, CHAN);
   naibrd_SER_ClearTxFifo(cardIndex, module, CHAN);

   naiif_printf("\r\nSerial Channel # %d\r\n", CHAN);

   check_status(naibrd_SER_SetChannelEnable(cardIndex, module, CHAN, 1));
   check_status(naibrd_SER_SetReceiverEnable(cardIndex, module, CHAN, NAI_TRUE));

   while ( NAI_TRUE )
   {
      naiif_printf("\r\nPress ENTER to receive a packet, or '%c' to exit program : ", NAI_QUIT_CHAR);
      if (naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt))
      {
         break;
      }

      naibrd_SER_GetRxBufferCnt(cardIndex, module, CHAN, (uint32_t*)&numWordsToRead);

      if(numWordsToRead == 0)
      {
         naiif_printf("\r\nNo data received\r\n");
         continue;
      }

      naibrd_SER_ReceiveBufferWithTimeOut32(cardIndex, module, CHAN, RecvPacket, MAX_PACKET_SIZE, 1,
         NAIBRD_FIFO_TIMEOUT_NONE, &numWordsToRead);

      packetSize = RecvPacket[0] + 3;

      status = naibrd_SER_ReceiveBufferWithTimeOut32(cardIndex, module, CHAN, RecvPacket + 1, MAX_PACKET_SIZE - 1, packetSize - 1,
         NAIBRD_FIFO_TIMEOUT_NONE, &numWordsToRead);

      if(status == NAI_SUCCESS || status == NAI_ERROR_MORE_DATA)
      {
         naiif_printf("\r\nReceived the following packet:");
         Print_Packet(RecvPacket, packetSize);
      }
      else
      {
         naiif_printf("\r\nError receiving packet: %s\r\n", naiif_GetStatusString(status));
      }
   }

   return;
}

void Print_Packet(uint32_t *packet, uint32_t size)
{
   uint32_t i;
   uint32_t numDataWords = size - 3;

   naiif_printf("\r\nHeader: 0x%02X\r\n", packet[0] & 0x1F);
   for(i = 0; i < numDataWords; i++)
   {
      naiif_printf("Data[%u]: 0x%08X\r\n", i, packet[1 + i]);
   }
   naiif_printf("CTW: 0x%08X\r\n", packet[size - 2]);
   naiif_printf("OVPW: 0x%08X\r\n", packet[size - 1]);
}

Help Bot

X