Using the BB_SramStack Library to access the Serial SRAM of the BlueberryE Uno335

The BlueberryE Uno335 has a 512Kbit Serial SRAM on board. BlueberryE provides an Arduino compatible library which uses a Stack data structure to store data into and read data from the SRAM. This tutoral will focus on the usage of this library BB_SramStack. To get more information about the Serial Sram on the Uno335, read our Introduction for the SRAM on the BlueberryE Uno335 tutorial. There, you will also find information about the required jumper settings.

Download the library from GitHub: BB_SramStack

Copy this library in your Arduino/library folder and restart your Arduino IDE.

Content

The BB_SramStack Library

Overview

The well known data structure Stack is implemented in the BB_SramStack library. The library provides typical stack functions like push(), pop(), clear(), peek(), isEmpty(), isFull() and several constructors. Additionally, it provides a BB_StackIterator class. Objects of this class can be used to iterate over the content of a stack defined by a BB_SramStack object. The following list summarizes the constructors and functions of BB_SramStack and BB_StackIterator.

  1. BB_SramStack
  2. Constructors Functions
    BB_SramStack BB_SramStack::begin()
    BB_SramStack(char mode) boolean isEmpty()
    BB_SramStack(word startAddress, unsigned long size) boolean isFull()
    BB_SramStack(char mode, word startAddress, unsigned long size) boolean clear()
    byte push(byte data)
    byte push(word inData)
    word pop()
    word peek()
    BB_StackIterator iterator()

  3. BB_StackIterator
  4. Constructors Functions
    BB_StackIterator(BB_SramStack *stack) boolean hasNext()
    word next()

Details

  1. BB_SramStack
  2. BB_SramStack objects allow the usage of (parts of) the Serial SRAM as stack. The stack has to be defined either as "byte mode stack" or as "word mode stack". In byte mode, each cell of the stack contains one byte (8bit) of data. The maximum stack capacity is 64K bytes. In word mode, each cell of the stack contains one word (16bit) of data. The maximum stack capacity is 32K words.
    1. Constructors
    2. BB_SramStack
      Parameters:
      None
      Return value:
      A BB_SramStack object
      Description:
      Initiates a SramStack object which uses the total capacity (64K bytes) of the serial SRAM. Each stack cell contains one byte (8bit) off data ("byte mode").
      Example:
      BB_SramStack totalSramByteMode;

      BB_SramStack(char mode)
      Parameters:
      mode defines the capacity (byte or word) of the stack cells.
      Return value:
      A BB_SramStack object
      Description:
      Initiates a SramStack object which uses the total capacity (64K bytes) of the serial SRAM. The parameter mode defines the capacity (byte or word) of the stack cells.
      mode = 'b': each stack cell contains one byte (8 bit) of data. The capacity of the stack is 64K bytes.
      mode = 'w': each stack cell contains one word (16bit) of data. The capacity of the stack is 32K words
      Example:
      BB_SramStack totalSramByteMode('b'); // stack with total sram capacity with 8bit cells
      BB_SramStack totalSramByteMode('w'); // stack with total sram capacity with 16bit cells

      BB_SramStack(word startAddress, unsigned long size)
      Parameters:
      startAddress: the 16bit address of the first memory cell of the stack.
      size: the amount of stack cells.
      Return value:
      A BB_SramStack object
      Description:
      Initiates a SramStack object which uses the defined capacity starting at a defined SRAM address.
      Each stack cell contains one byte of data (byte mode).
      If (startAddress + size) > physical SRAM capacity , the stack object will be flagged as full, i.e. it cannot be used.
      Example:
      BB_SramStack partSramByteMode(0x8000, 1024);
      // stack with 1024 (i.e. 0x400) 8bit cells
      // address of the first cell = 0x8000
      // address of the last cell = 0x83FF

      BB_SramStack(char mode, word startAddress, unsigned long size)
      Parameters:
      mode: see BB_SramStack(char mode)
      startAddress: see BB_SramStack(word startAddress, unsigned long size)
      size: see BB_SramStack(word startAddress, unsigned long size)
      Return value:
      A BB_SramStack object
      Description:
      Initiates a SramStack object which uses the defined capacity starting at a defined SRAM address.
      Each stack cell contains one byte (byte mode) or one word (word mode) of data.
      If (startAddress + size) > physical SRAM capacity , the stack object will be flagged as full, i.e. it cannot be used.
      Example:
      BB_SramStack partSramByteMode('b', 0x8000, 1024);
      // stack with 1024 (i.e. 0x400) 8bit cells
      // address of the first cell = 0x8000
      // address of the last cell = 0x83FF
      
      BB_SramStack partSramWordMode('w', 0xF000, 1024);
      // stack with 1024 (i.e. 0x400) 16bit cells
      // address of the first cell = 0xF000
      // address of the last cell = 0xF7FE (0xF000 + (2 * 0x400 - 2))
    3. Functions
    4. BB_SramStack::begin()
      Parameters:
      None
      Return value:
      None
      Description:
      Initializes the settings for the SPI communication with the Serial SRAM. In particular, the SPI pins SS (pin 10), MOSI (pin 11), MISO (pin 12), SCK (pin 13) and the _CS (pin A3) for the SRAM are configured accordingly. Do not change these pin modes in your sketch!. This static method needs to be called in the setup() of the sketch.
      Example:
      void setup(){
          BB_SramStack::begin();
      }

      boolean isEmpty()
      Parameters:
      None
      Return value:
      boolean
      Description:
      Checks if the stack is empty.
      returns true if the stack has no elements.
      returns false else
      Example:
      byte data;
      if (!totalSramByteMode.isEmpty()) data = totalSramByteMode.pop();
      

      boolean isFull()
      Parameters:
      None
      Return value:
      boolean
      Description:
      Checks if the stack is full.
      returns true if all cells of the stack are filled with data.
      returns false else
      Example:
      byte data = 0xBE;
      if (!totalSramByteMode.isFull()) totalSramByteMode.push(data);
      

      clear()
      Parameters:
      None
      Return value:
      None
      Description:
      Resets the stack, i.e. isEmpty() will return true after this operation.
      Example:
      totalSramByteMode.clear();

      byte push(byte data)
      Parameters:
      data: the 8bit bit pattern which will be put on top of the stack.
      Return value:
      0 if the data could be written onto the stack
      > 0 else
      Description:
      Puts one byte of data on top of the stack. In word mode, data will be extended to a word with leading 0s.
      Example:
      byte data = 0xBE;
      totalSramByteMode.push(data);

      byte push(word data)
      Parameters:
      data: the 16bit bit pattern which will be put on top of the stack.
      Return value:
      0 if the data could be written onto the stack
      > 0 else
      Description:
      Puts one word of data on top of the stack. In byte mode, only the last 8bit of data will be stored.
      Example:
      word data = 0xBE27;
      totalSramWordMode.push(data);

      word pop()
      Parameters:
      None
      Return value:
      the content of the top stack cell
      Description:
      returns the content of the last data which was written to the stack and removes this data from the stack. In byte mode, the first 8 bits are not valid.
      Example:
      word data = totalSramWordMode.pop();

      word peek()
      Parameters:
      None
      Return value:
      the content of the top stack cell
      Description:
      returns the content of the last data which was written to the stack. In byte mode, the first 8 bits are not valid.
      Example:
      word data = totalSramWordMode.peek();

      BB_StackIterator iterator()
      Parameters:
      None
      Return value:
      an iterator pointing to the first stack element
      Description:
      creates and returns a BB_StackIterator which can be used to iterate from the first to the last element of the the stack.
      Example:
      BB_StackIterator iter = totalSramByteMode.iterator();

  3. BB_StackIterator
  4. A BB_SramIterator object can be used to iterate over the elements of one BB_SramStack object without changing it.
    1. Constructors
    2. BB_StackIterator(BB_SramStack stack)
      Parameters:
      stack:a reference to the stack over which the iterator will iterate.
      Return value:
      A BB_StackIterator object
      Description:
      Initiates a BB_StackIterator object which can be used to iterate over all elements of a BB_SramStack object. After instantiation, the BB_StackIterator object refers to the first element of the stack.
      Note: Do not use this constructor!! Use the iterator() method of a BB_SramStack object instead!!
      Example:
      NA
    3. Functions
    4. boolean hasNext()
      Parameters:
      None
      Return value:
      true if the stack has an element which can be received by next().
      Description:
      Checks if the stack has an element which can be received by next().
      Example:
      BB_StackIterator iter = totalSramByteMode.iterator();
      while (iter.hasNext()){
          Serial.println(iter.next());
      }

      word next()
      Parameters:
      None
      Return value:
      the current element on the stack to which the iterator is pointing to.
      Description:
      Provides the data which is stored in the stack cell to which the iterator is currently pointing to. If the stack is in byte mode, the first 8 bits are not valid.
      Example:
      BB_StackIterator iter = totalSramByteMode.iterator();
      if (iter.hasNext()){
          Serial.println(iter.next());
      }

Example sketches

The following examples will show how the BB_SramStack library can be used.

  • A basic example (Euler's number)

  • In this example, a single stack is defined. Four digits of Euler's number (the E in BlueberryE) e = 2.71828 18284 59045 23536 02874 71352 66249 77572 47093 69995... are stored in the stack. Afterwards, we show how to iterate over the content of the stack using pop() or a BB_StackIterator.

    Here is the code: download on GitHub

    
    /*
      Store 4 digits of Eulers number e in the Uno335 Serial Sram.
      This sketch uses the BB_SramStack library
    
      created 10 Aug. 2016
      by Engelbert Mittermeier (BlueberryE GmbH)
    */
    
    1:   #include <BB_SramStack.h> // include the library
    2:
    3:   // Instantiate a stack object
    4:   // the stack will be in byte mode and will use the total SRAM capacity
    5:   BB_SramStack stack8_1;
    6:   
    7:   void setup() {
    8:       Serial.begin(9600);
    9:       BB_SramStack::begin();
    10:  }
    11:  
    12:  void loop() {
    13:      // Check the status of the stack
    14:      Serial.print("Stack is empty = ");
    15:      Serial.println(stack8_1.isEmpty());
    16:      Serial.print("Stack is full = ");
    17:      Serial.println(stack8_1.isFull());
    18:      Serial.println();
    19:  
    20:      Serial.println("Writing 2.718 to the sram\n");
    21:      stack8_1.push((byte) '2');
    22:      stack8_1.push((byte) '.');
    23:      stack8_1.push((byte) '7');
    24:      stack8_1.push((byte) '1');
    25:      stack8_1.push((byte) '8');
    26:
    27:      // Check the status of the stack
    28:      Serial.print("Stack is empty = ");
    29:      Serial.println(stack8_1.isEmpty());
    30:      Serial.print("Stack is full = ");
    31:      Serial.println(stack8_1.isFull());
    32:      Serial.println();
    33:
    34:      // Reading the content of the top cell of the stack using peek()
    35:      Serial.print("Content of the last cell of the Stack = ");
    36:      Serial.println((char) stack8_1.peek());
    37:      Serial.println();
    38:
    39:      // Read the content of the stack using an iterator
    40:      Serial.println("Reading the content of the stack using an iterator")
    41:      Serial.println("Sequence is: from first element to the last element");
    42:      BB_StackIterator iterStack8_1 = stack8_1.iterator();
    43:      Serial.print("e = ");
    44:      while (iterStack8_1.hasNext()){
    45:          Serial.print((char) iterStack8_1.next());
    46:      }
    47:      Serial.println();
    48:
    49:      // Check the status of the stack
    50:      Serial.print("Stack is empty = ");
    51:      Serial.println(stack8_1.isEmpty());
    52:      Serial.println();
    53:
    54:      // Read the content of the stack using pop()
    55:      Serial.println("Reading the content of the stack using pop()");
    56:      Serial.println("Sequence is: from last element to the first element");
    57:      while(!stack8_1.isEmpty()) Serial.println((char) stack8_1.pop());
    58:      
    59:      // Check the status of the stack
    60:      Serial.print("Stack is empty = ");
    61:      Serial.println(stack8_1.isEmpty());
    62:      Serial.println();
    63:
    64:      Serial.println("-------------------------------");
    65:      delay(3000);
    66:  }
    

    This sketch will produce the following output

    
    Stack is empty = 1
    Stack is full = 0

    Writing 2.718 to the sram

    Stack is empty = 0 Stack is full = 0

    Content of the last cell of the Stack = 8

    Reading the content of the stack using an iterator Sequence is: from first element to the last element e = 2.718 Stack is empty = 0

    Reading the content of the stack using pop() Sequence is: from last element to the first element 8 1 7 . 2 Stack is empty = 1


  • An example using multiple stacks (ASCII art)

  • In this example, 6 stacks are used to define some letters of an ASCII art alphabet. We will used this alphabet to display BLUEBERRYE in the Serial Monitor. This example shows how to "segment" the Serial Sram into several stacks. And it shows how to use several iterators for one stack, e.g there are 3 iterators for the letter E.

    Here is the code: download on GitHub

    
    /*
      Draw "BLUEBERRYE" with ASCII art.
      Pixels for the letters are stored in several stacks on the Uno335 Serial Sram.
      Multiple iterators are used for reading the pixels from the stacks.
      This sketch uses the BB_SramStack library
    
      created 10 Aug. 2016
      by Engelbert Mittermeier (BlueberryE GmbH)
    */
    
    1:   #include <BB_SramStack.h> // include the library
    2:
    3:   // define some useful constants
    4:   const char fill = '#';    // pattern used to draw a pixel
    5:   const char space = '.';   // pattern used to draw a space
    6:   const byte letWidth = 6;  // width of one letter
    7:   const byte letHeight = 7; // height of one letter
    8:   // pixels needed for one letter:
    9:   const unsigned long pixCount =(unsigned long) (letWidth * letHeight);
    10:  
    11:  // define the stacks for the letters
    12:  BB_SramStack letB(0x0000, pixCount); // stack for letter "B"
    13:  BB_SramStack letL(0x0100, pixCount); // stack for letter "L"
    14:  BB_SramStack letU(0x0200, pixCount); // stack for letter "U"
    15:  BB_SramStack letE(0x0300, pixCount); // stack for letter "E"
    16:  BB_SramStack letR(0x0400, pixCount); // stack for letter "R"
    17:  BB_SramStack letY(0x0500, pixCount); // stack for letter "Y"
    18:  
    19:  void setup(){
    20:      Serial.begin(9600);
    21:      BB_SramStack::begin();
    22:      initLetterB(); // write the "pixels" into the stack for B
    23:      initLetterL(); // write the "pixels" into the stack for L
    24:      initLetterU(); // write the "pixels" into the stack for U
    25:      initLetterE(); // write the "pixels" into the stack for E
    26:      initLetterR(); // write the "pixels" into the stack for R
    27:      initLetterY(); // write the "pixels" into the stack for Y
    28:  }
    29:
    30:  void loop(){
    31:      // One line consists of 9 columns. Each columns will contain one letter.
    32:      // We use one iterator for each column
    33:      BB_StackIterator pos0 = letB.iterator();
    34:      BB_StackIterator pos1 = letL.iterator();
    35:      BB_StackIterator pos2 = letU.iterator();
    36:      BB_StackIterator pos3 = letE.iterator();
    37:      BB_StackIterator pos4 = letB.iterator();
    38:      BB_StackIterator pos5 = letE.iterator();
    39:      BB_StackIterator pos6 = letR.iterator();
    40:      BB_StackIterator pos7 = letR.iterator();
    41:      BB_StackIterator pos8 = letY.iterator();
    42:      BB_StackIterator pos9 = letE.iterator();
    43:
    44:      // print the line
    45:      for (byte j = 0; j < letHeight; j++){
    46:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos0.next());
    47:          Serial.print(space);
    48:          Serial.print(space);
    49:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos1.next());
    50:          Serial.print(space);
    51:          Serial.print(space);
    52:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos2.next());
    53:          Serial.print(space);
    54:          Serial.print(space);
    55:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos3.next());
    56:          Serial.print(space);
    57:          Serial.print(space);
    58:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos4.next());
    59:          Serial.print(space);
    60:          Serial.print(space);
    61:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos5.next());
    62:          Serial.print(space);
    63:          Serial.print(space);
    64:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos6.next());
    65:          Serial.print(space);
    66:          Serial.print(space);
    67:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos7.next());
    68:          Serial.print(space);
    69:          Serial.print(space);
    70:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos8.next());
    71:          Serial.print(space);
    72:          Serial.print(space);
    73:          for (byte i = 0; i < letWidth; i++) Serial.print((char) pos9.next());
    74:          Serial.println();
    75:      }
    76:      Serial.println("-------------------------------------------------------------------------------");
    77:      delay(3000);
    78:  }
    79:  
    80:  // The functions which write the pixels for the letters into the stacks:
    81:
    82:  void initLetterB(){
    83:      for (byte i = 0; i < 5; i++) letB.push((byte) fill);
    84:      letB.push((byte) space);
    85:      letB.push((byte) fill);
    86:      for (byte i = 0; i < 4; i++) letB.push((byte) space);
    87:      for (byte i = 0; i < 2; i++) letB.push((byte) fill);
    88:      for (byte i = 0; i < 4; i++) letB.push((byte) space);
    89:      letB.push((byte) fill);
    90:      for (byte i = 0; i < 5; i++) letB.push((byte) fill);
    91:      letB.push((byte) space);
    92:      letB.push((byte) fill);
    93:      for (byte i = 0; i < 4; i++) letB.push((byte) space);
    94:      for (byte i = 0; i < 2; i++) letB.push((byte) fill);
    95:      for (byte i = 0; i < 4; i++) letB.push((byte) space);
    96:      letB.push((byte) fill);
    97:      for (byte i = 0; i < 5; i++) letB.push((byte) fill);
    98:      letB.push((byte) space);
    99:  }
    100: 
    101: void initLetterL(){
    102:     for (byte i = 0; i < 6; i++){
    102:         letL.push((byte) fill);
    103:         for (byte j = 0; j < 5; j++) letL.push((byte) space);
    104:     }
    105:     for (byte i = 0; i < 6; i++) letL.push((byte) fill);
    106: }
    107:
    108: void initLetterU(){
    109:     for (byte i = 0; i < 6; i++){
    110:         letU.push((byte) fill);
    111:         for (byte j = 0; j < 4; j++) letU.push((byte) space);
    112:         letU.push((byte) fill);
    113:     }
    114:     for (byte i = 0; i < 6; i++) letU.push((byte) fill);
    115: }
    116:
    117: void initLetterE(){
    118:     for (byte i = 0; i < 6; i++) letE.push((byte) fill);
    119:     for (byte i = 0; i < 2; i++){
    120:         letE.push((byte) fill);
    121:         for (byte j = 0; j < 5; j++) letE.push((byte) space);
    122:     }
    123:     for (byte i = 0; i < 4; i++) letE.push((byte) fill);
    124:     for (byte i = 0; i < 2; i++) letE.push((byte) space);
    125:     for (byte i = 0; i < 2; i++){
    126:         letE.push((byte) fill);
    127:         for (byte j = 0; j < 5; j++) letE.push((byte) space);
    128:     }
    129:     for (byte i = 0; i < 6; i++) letE.push((byte) fill);
    130: }
    131:
    132: void initLetterR(){
    133:     for (byte i = 0; i < 5; i++) letR.push((byte) fill);
    134:     letR.push((byte) space);
    135:     for (byte i = 0; i < 2; i++){
    136:         letR.push((byte) fill);
    137:         for (byte j = 0; j < 4; j++) letR.push((byte) space);
    138:         letR.push((byte) fill);
    139:     }
    140:     for (byte i = 0; i < 6; i++) letR.push((byte) fill);
    141:     for (byte i = 0; i < 2; i++){
    142:         letR.push((byte) fill);
    143:         for (byte j = 0; j < 2; j++)letR.push((byte) space);
    144:     }
    145:     letR.push((byte) fill);
    146:     for (byte i = 0; i < 3; i++) letR.push((byte) space);
    147:     letR.push((byte) fill);
    148:     letR.push((byte) space);
    149:     letR.push((byte) fill);
    150:     for (byte i = 0; i < 4; i++) letR.push((byte) space);
    151:     letR.push((byte) fill);
    152: }
    153:
    154: void initLetterY(){
    155:     letY.push((byte) fill);
    156:     for (byte i = 0; i < 4; i++) letY.push((byte) space);
    157:     letY.push((byte) fill);
    158:     letY.push((byte) space);
    159:     letY.push((byte) fill);
    160:     for (byte i = 0; i < 2; i++) letY.push((byte) space);
    161:     letY.push((byte) fill);
    162:     letY.push((byte) space);
    163:     for (byte i = 0; i < 5; i++){
    164:         for (byte j = 0; j < 2; j++) letY.push((byte) space);
    165:         letY.push((byte) fill);
    166:         for (byte j = 0; j < 3; j++) letY.push((byte) space);
    167:     }
    168: }

    This sketch will produce the following output (Please, use a browser window which is large enough to see the beautiful ASCII art).

     
    #####...#.......#....#..######..#####...######..#####...#####...#....#..######
    #....#..#.......#....#..#.......#....#..#.......#....#..#....#...#..#...#.....
    #....#..#.......#....#..#.......#....#..#.......#....#..#....#....#.....#.....
    #####...#.......#....#..####....#####...####....######..######....#.....####..
    #....#..#.......#....#..#.......#....#..#.......#..#....#..#......#.....#.....
    #....#..#.......#....#..#.......#....#..#.......#...#...#...#.....#.....#.....
    #####...######..######..######..#####...######..#....#..#....#....#.....######
    -------------------------------------------------------------------------------