This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Declaration of a vector in memory and accessing to it's elements with MSP430-F2013 device

 

Hi,

I need to acquire digital data from a PIN and store them into a shift register of 256 elements.

I need also to access to those values for computational purposes.

 

Someone may help me in the declaration of this array and tell me how to acces to it's elements?????

I need to do this in assembler.

 

Thanks,

Pietro

 

  • Pietro Tripodi said:
    I need to do this in assembler.

    Are you sure? Assembly language is more difficult to handle than C. And if you have to ask this question, then you're most likely not very experienced with it, as it is a rather basic task.
    It is, however, dependent on the assembler you use (the toolchain). Syntax and segments are different for CCS, IAR or mspgcc..

    Basically, you reserve a memory location in the data segment adn set a global label on its start. This is the assembler-specific part. See assembler documentation for the correct syntax. Basically, it makes no difference whether you define a single word variable or an array.
    That's all.
    How you then make access to it depends on your program. Normally, you would use the indexed addressign modes of the MSP. Assuming your name for the array was 'data' and it is an INT array, you can perform a data read from data[10] into R15 register by the following sequence:

    MOV #10, R14 ; index 10 (0-based)
    RLA R14 ; multiply index by 2, as each element is 2 bytes long
    MOV data(R14), R15

    R15 now contains the 11th element (index is 0-based) of the array.

  • I will just "allocate" 16 words (16*16 = 256 bits) of memory from 0x0200 for this vector.

    To shift the Input from Port1 BIT2 into this vector, I can use:

      mov   #16*2,R4
      bit.b #BIT2,&P1IN
    loop:
      rlc   0x200-2(R4)
      sub   #2,R4
      jnz   loop


    The oldest bit is the msb of the word @ 0x0200. The newest bit is the lsb of the word @ 0x021E

  • Thank you both for your prompt response.

    @ Jens-Michael Gross:
    You're right, I am a beginner with the assembler. I'm using the IAR assemblerHowever I have to work in assembly because I have very tight deadlines in my application.

    I did not understand your answer when you write: "RLA R14, multiply by 2 index, as Eachelement is 2 bytes long." You mean you can only work with bytes, not bits? Why multiply it by 2?

    Sorry for the probably obvious questions.

    @ old_cow_yellow
    I saw  the code, however I understood little of what it says. :) Could you please explain?

    How can I allocate space in memory for 16 * 16 word?Thanks


    thanks,

    Pietro

  • Pietro Tripodi said:
    I have to work in assembly because I have very tight deadlines in my application.

    C is not necessarily slower than assembly, if you stay away from using objects and float variables and such. And coding in C is faster (affects your overall project timeline). However, it's your choice. :)

    Pietro Tripodi said:
    RLA R14 ; multiply by 2 index, as each element is 2 bytes long.

    My example was for an array of word (2 byte size) values.

    For byte values, the RLA is not necessary.
    And for less than one byte, you need to shift the index right by 3 bits (divide by 8) and keep the lower 3 bits of the index to identify the bit inside the resulting byte. It's definitely much slower and complex. But of course it saves some space (7/8 of the array size), if your array only has booleans.

  • Pietro Tripodi said:

    How can I allocate space in memory for 16 * 16 word?

    In IAR, you use the DS directive or its variants to allocate space for data.  For example:

            RSEG    DATA16_Z  ; Next allocations for relocatable segment "DATA16_Z"

    BVECT   DS      32        ; Declare with DS because we plan to store bytes here

    WVECT   DS16    16        ; Declare with DS16 because we plan to store words here

    This creates two vectors of the same size.  (You need only one of them.)  Your code can store whatever data it wants here, but the directives DS and DS16 are somewhat self documenting.

    You said in your first post you might need to do some computational work on the vector.  That computational work should help you decide how to implement your shift register.  If the computation is bitwise and if the data have no meaning reassembled as bytes or words, then you can implement the shift register however you like.  However, if the computation is byte-wise or word-wise OR if the data has meaning to your application as bytes or words, then your shift register implementation must put the bits in the right place.

    For example, OCY's suggestion above works for word data arriving most-significant bit first.  It also works for raw bit data that has no meaning as bytes or words.  However, you would want to use a different implementation for byte data of any bit order or for word data arriving least-significant bit first.

    I'm not clear on your need for assembly language here - is it for speed of runtime execution or for speed of software development?

    Jeff

  • When I said: I will just "allocate" 16 words (16*16 = 256 bits) of memory from 0x0200 for this vector, what I meant was, I will do that myself without telling the assembler. Thus I had instructions such as: rlc 0x200-2(R4) and I made sure that R4 is between 32 and 2 and is always even.

    I do not want to worry about the syntax and scimitars of how to allocate memory with the assembler nor the risk of any misunderstanding of the rules. I just take care of RAM access myself. I know this is very “unprofessional” and very crude. But it works for me.

  •  

    Hello everyone and thanks again for the answers.

    Perhaps it's better to explain my application.

    Suppose you have an analog signal S of duration T seconds. I have to read the signal S on an input pin of microcontroller and store within a 256-bit shift register, such as boolean values​​. The bits are not correlated with each other and have no meaning as a byte or word, but all of the 256-bit is the sign of the entire input signal. To run my application, the "sampling" and the signal processing must be done in 5 micro seconds.

    After updating the shift register, I have to perform a convolution with a binary vector of 256 bits S1 previously declared.

    Finally, the resulting vector, I apply an algorithm for the maximun search.

     

    I know that in assembler is not the easiest thing, but I need to control the timing because everything works (must be 5 micro seconds).

    I understand that I can declare the memory as:

    DS BVECT 32, as written by Jeff

    I read the input a PIN through education BIT.B and then I write the value read as the first element of the shift register. This is what (I think) the code of OCY, but I do not understand how. That is, if I want to shift all bits right run cycle:

    loop:

       rlc 0x200-2 (R4)

       Sub # 2, R4

       jnz loop

     

    as OCY wrote, but how I've to do to write the new bit as first element of the Shift register?

    And after how can I acces to each bit of S and S1 arrays to implement the convolution?

     

    In C is something like:

    for (i=0;i<256;i++)

        Somma=Somma+(S(i) && S1(i));

    end

    but in assembler? I don't know how to do something like S(i)... :)

     

    Thank you all for the answers,

    Pietro Tripodi

     

  • That description is really helpful.  After reading it, I have some advice:

    1. With your lack of experience with MSP430 assembly language, don't use it.  Use C.
    2. With your difficult timing requirements, don't use a shift register.  Use a "circular buffer".
    3. Declare your arrays as 256 bytes each.  By "wasting" memory in this case, you gain execution speed.
    4. Use a timer to decide when to read the next sample.  Ideally, let a Timer A actually take the sample for you (SCCI bit).
    5. Run your CPU clock at the maximum (16MHz I think).  You'll need the horsepower.

    Jeff

  • Jeff, you're again typing almost exactly what I had written :)

    For 1+2+3:

    unsigned char data[256]; // 256 byte buffer for 256 values
    volatile unsigned char start=0; // points to the beginning of the buffer

    data[start++]=newData; // writes new data to the end of the buffer, by writing it to the start and move the start position. Since start is a char, it auto-wraps from 255 to 0. The old start index is the new end index.

    For processing the data:

    unsigned char index = start;  // another char that auto-wraps around from 255 to 0.
    for (int i=0; i<256;i++, index++){ // precess the loop 256 times, and increase index after each loop, so index goes from start to start-1
      do_something with value(data[index]);
    }

    4) indeed. The timer is your friend if it comes to timing :)

    5) definitely. Gathering the data isn't the problem, but processign it... A new value each 5µs means 80 clock cycles per value for data gathering and processing.This isn't much. I hope there are no doubles needed, or divisions :)
    If I remember correct, a formula with just 2 multiplications and 1 division took 147µs on an 8MHz system. Most of it being the division.

  • Pietro Tripodi said:
      ... Suppose you have an analog signal S of duration T seconds. I have to read the signal S on an input pin of microcontroller and store within a 256-bit shift register, such as boolean values​ ...​. To run my application, the "sampling" and the signal processing must be done in 5 micro seconds...

    Are you saying that your analog signal S is converted to a single bit boolean value? Are you also saying that the duration T seconds is shorter than 5 micro seconds? I have no idea about what you have in mind now.

    I was assuming that your input signal S was digital (boolean) and was connected to BIT2 of Port1. Thus the following code will shift the current sample S1 into the 16 words of memory I allocated to store it.
      bit.b #BIT2,&P1IN
      rlc &0x021E
      rlc &0x021C
      rlc &0x021A
      rlc &0x0218
      rlc &0x0216
      rlc &0x0214
      rlc &0x0212
      rlc &0x0210
      rlc &0x020E
      rlc &0x020C
      rlc &0x020A
      rlc &0x0208
      rlc &0x0206
      rlc &0x0204
      rlc &0x0202
      rlc &0x0210

    The most recent S1 is now stored at the “right-most” bit of memory 0x021E. The second most recent S1 is stored at the second “right-most” bit of memory 0x021E. The 17th most recent S1 is stored at the “right-most” bit of memory 0x021C. etc.  The 256th most recent S1 is stored at the “left-most” bit of memory 0x0200.

    You can retrieve one bit of them with:
      bit #BITn,&0x2yy
    where BITn is any bit from BIT0 to BIT15 and &0x2yy is any word from 0x0200 to 0x021E. The retrieved bit will be in the carry bit.

     

     

     

  • Thanks to all.

    I did everything but the processor is not fast enough even at 16MHz.

    See you soon.

    Pietro Tripodi

  • Pietro Tripodi said:
    I did everything but the processor is not fast enough even at 16MHz.

    What calculation/processing do you need to do?

    If it is a 'moving average' or something of that sort, there might be no need to process all 256 values each time. Just keep the last result, and when a new value comes, subtract the oldes value from the old result and add the newest, before shifting it by 8 bit. Only a subtraction and an additon instead of 256 adds. Other simple linear algorithms can be optimized in a similar way.

    For more complex algorithms, you may be able to store the single results and use them instead of doing all the calculation on the original values.
    However, this completely depends on the algorithm you want to use. The straight way is usually the slowest.

    Also, the storage of bits in a byte is very time-consuming. Wasting space and store each bit in a byte, using a byte variable as ring counter, is by magnitudes faster.

  • Pietro Tripodi said:

    I did everything but the processor is not fast enough even at 16MHz.

    I guess that's not too surprising.  You have a very difficult requirement.  Even the most basic convolutional encoding and decoding is serious work for an MSP430.

    Jeff

**Attention** This is a public forum