Project Objective: Develop an open source AIS Alarm that alerts sailors that a new marine vessel with AIS is within range
The prototype is now receiving AIS messages from the dAISy module. In this post a method for storing the messages in a persistent FRAM ring buffer will be described. This is important to the project because persistent storage means the messages will not be lost when the device is unplugged from power.
The screen shot below taken from the CCS debug view shows that 1) the ring buffer is being updated with AIS messages, and 2) that FRAM usage is 3372 bytes which gives confidence that the MSP430FR2111 will have enough memory for the job at hand.
The highlighted values show the variables that have changed since the debug window was last paused. It indicates that 3 messages were received.
Here is how the ring buffer was defined and set up:
// Global ring buffer variable declarations #define MBUF_SIZE 16 // buffer size must be power of 2 #define MSG_LEN 120 // maximum length of a NMEA message #define FRAM_enableWrite() SYSCFG0=FRWPPW // macro for FRAM writing #define FRAM_disableWrite() SYSCFG0=FRWPPW|PFWP // macro for disabling FRAM writing #pragma PERSISTENT(nmea) // put nmea in FRAM struct msg_s{ // struct for messages in circular buffer char msg[MSG_LEN]; } nmea[MBUF_SIZE] = { // initialize nmea circular buffer - must be done explicitly // ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+....0....+....1....+....2 " ", // 0 " ", // 1 " ", // 2 " ", // 3 " ", // 4 " ", // 5 " ", // 6 " ", // 7 " ", // 8 " ", // 9 " ", // 10 " ", // 11 " ", // 12 " ", // 13 " ", // 14 " " // 15 }; char incoming[MSG_LEN]; // temporary buffer to build incoming NMEA sentences unsigned int msgBufHead = 0; // circular FIFO buffer head pointer unsigned int msgBufTail = 0; // circular FIFO buffer tail pointer
I am using a ring buffer algorithm that I have not fully tested so will leave that for a future post. The interesting thing here (at least to me) is the way variables are designated to be placed in FRAM and made persistent (i.e. won't be lost between powering and repowering after the initial upload). I made a previous post that went into more detail on persistent FRAM here. But let's take the code above line by line.
- Line 2 defines the buffer length to be 16 - it must be a power of 2 for the ring buffer that is being used.
- Line 3 sets the message size to be 120 - AIS messages would not normally exceed a length of 100 but this provides some headroom
- Lines 4 and 5 turn the cryptic FRAM write enable and disable register into a macro more human readable
- Line 6 specifies that the "nmea" shall be put into FRAM and made persistent
- Lines 7 through 9 initialize nmea as 16 messages of length 120 characters in the form of a struct
- Lines 10 through 27 then explicitly initialize the values - this must be done or the buffer will not be placed in FRAM
- Line 28 is the same temporary buffer used previously to build the NMEA sentences as they come in over UART
- Lines 29 and 30 are used in the yet to be described ring buffer algorithm
The coding took longer to write than normal because the compiler had to barf all over my attempts to explicitly initialize nmea. In the end is clear what is going on but it seems unwieldy and specifying this way prone to error. I will investigate further because my C skills aren't that great, particularly with character manipulation. Of course C is not exactly know for easy character manipulation. If you have a better way, please outline in the comments.
Let's check and make sure it did what was wanted with a screen shot of the .map file.
The output section titled .TI.persistent shows the origin and length of anything placed in FRAM and made persistent. In this case it shows nmea was made persistent at starts at
0000f100 and is of length 00000780. Using my trusty Windows calculator in programming mode I calculate the length to be 1,920 in decimal which is equal to the desired 16 messages x 120 characters.
In upcoming posts the ring buffer will be described and tested. It is also time to start thinking about the hardware and what enclosure will be used. As always, thanks for reading - comments and suggestions for improvement are very welcome.
Past Posts from this Project:
AIS Alarm - Prototype Hardware
AIS Alarm - Prototype Code Outline
AIS Alarm - First AIS Messages
References and Links:
WEGMATT LLC - dAISy AIS Receiver - low cost AIS receiver
Texas Instruments MSP430FR2xx FRAM Microcontrollers - Post No. 4