SER SCM Xmit Sample Application (SSK 2.x)
Overview
The SER SCM Xmit sample application demonstrates how to transmit Manchester-encoded packets via the SCM module’s channel 1 using the NAI Software Support Kit (SSK 2.x). The application enables the channel, queries the user for the number of data words to send, builds a packet with a header, data words, and a CTW (Command/Time Word), loads it into the transmit FIFO, and initiates transmission.
This sample is exclusive to the SCM module. It is designed to work as the transmitting half of a two-application pair — run the SER SCM Recv sample to receive the packets transmitted by this application.
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.
How to Run
Launch the ser_scm_xmit executable from your build output directory. On startup the application looks for a configuration file (default_SerSCM_xmit.txt). Once connected and the module is verified as SCM, the application enters a transmit loop where the user specifies how many data words to send.
Board Connection and Module Selection
Note
This startup sequence is common to all NAI sample applications.
The main() function verifies the module ID is NAIBRD_MODULE_ID_SCM before proceeding. If the module is not an SCM, the application prints an error and returns to the menu.
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_Xmit_Sample() on VxWorks.
Application Flow
- Reset channel 1 and clear both FIFOs.
- Enable the channel and receiver.
- Enter a transmit loop: query for data word count, build packet, load FIFO, transmit.
Channel Setup
The application uses a fixed channel (channel 1):
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 Building and Transmission
The user enters the number of data words (maximum 29). The application builds a packet with the following structure:
packet[0]— header containing the data word count.packet[1..n]— data words with incremental values starting atBASE_VAL(0x10000000).packet[size-1]— CTW (Command/Time Word), set to 0xAAAAAAAA.
void Fill_Packet(uint32_t* packet, uint32_t size, uint32_t baseVal, uint32_t ctw)
{
uint32_t i;
uint32_t numDataWords = size - 2;
packet[0] = numDataWords;
for (i = 0; i < numDataWords; i++)
{
packet[1 + i] = i + baseVal;
}
packet[size - 1] = ctw;
}The packet is then loaded into the FIFO and transmitted:
check_status(naibrd_SER_LoadBufferWithTimeOut32(cardIndex, module, CHAN, SendPacket, packetSize, MAX_PACKET_SIZE,
NAIBRD_FIFO_TIMEOUT_NONE, &numWordSent));
naibrd_msDelay(100);
check_status(naibrd_SER_TransmitInitiate(cardIndex, module, CHAN));Troubleshooting Reference
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
| Module not SCM | A non-SCM module is installed | This application only supports the SCM module. |
| Max number of data words exceeded | User entered more than 29 | The maximum number of data words per packet is 29. |
| Data sits in FIFO, never transmits | naibrd_SER_TransmitInitiate() not called | Ensure transmit is initiated after loading the FIFO. |
| No board found or connection timeout | Board not powered, incorrect configuration file | Verify hardware is powered and connected. |
| Receiver does not see transmitted data | Cable not connected, receiver not running | Ensure the SER SCM Recv sample is running. |
Full Source
The complete source for this sample is provided below for reference.
Full Source -- ser_scm_xmit.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_xmit.txt";
#define MAX_NUM_DATA_WORDS 29 /* Maximum number of data words in a packet */
#define MAX_PACKET_SIZE (MAX_NUM_DATA_WORDS + 2)
/* Function prototypes */
void Run_SER_SCM_Xmit(int32_t cardIndex, int32_t module);
/**************************************************************************************************************/
/** \defgroup SERSCMXmit
* Transmits packets via SCM's channel 1 Manchester-encoded packet link.
*
* Only works on SCM.
*/
/**************************************************************************************************************/
#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t SER_SCM_Xmit_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_Xmit(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 Fill_Packet(uint32_t* packet, uint32_t size, uint32_t baseVal, uint32_t ctw);
static void Print_Packet(uint32_t *packet, uint32_t size);
/**************************************************************************************************************/
/** \ingroup SERSCMXmit
\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_Xmit(int32_t cardIndex, int32_t module)
{
const int32_t CHAN = 1;
const uint32_t CTW = 0xAAAAAAAA;
const uint32_t BASE_VAL = 0x10000000;
uint32_t SendPacket[MAX_PACKET_SIZE];
int32_t numWordSent = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
bool_t bQuit = NAI_FALSE;
uint32_t numDataWords, packetSize;
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("Enter number of data words to send, or '%c' to exit program : ", NAI_QUIT_CHAR);
if (naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt))
{
break;
}
naiapp_query_NumberFromResponse(&numDataWords, inputBuffer, inputResponseCnt);
if(numDataWords > 29)
{
naiif_printf("\r\nMax number of data word is 29\r\n");
continue;
}
packetSize = numDataWords + 2;
Fill_Packet(SendPacket, packetSize, BASE_VAL, CTW);
naiif_printf("\r\nSending packet:");
Print_Packet(SendPacket, packetSize);
check_status(naibrd_SER_LoadBufferWithTimeOut32(cardIndex, module, CHAN, SendPacket, packetSize, MAX_PACKET_SIZE,
NAIBRD_FIFO_TIMEOUT_NONE, &numWordSent));
naibrd_msDelay(100);
check_status(naibrd_SER_TransmitInitiate(cardIndex, module, CHAN));
naiif_printf ("\r\n%d words sent\r\n", numWordSent);
}
return;
}
void Fill_Packet(uint32_t* packet, uint32_t size, uint32_t baseVal, uint32_t ctw)
{
uint32_t i;
uint32_t numDataWords = size - 2;
packet[0] = numDataWords;
for (i = 0; i < numDataWords; i++)
{
packet[1 + i] = i + baseVal;
}
packet[size - 1] = ctw;
}
void Print_Packet(uint32_t *packet, uint32_t size)
{
uint32_t i;
uint32_t numDataWords = size - 2;
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 - 1]);
}