Jump to content
Gareeeesh

Sending Image as RGB Array to G2553

Recommended Posts

That does sound pretty complicated :? ..... I'm not sure I'm well-versed enough in MSP430 C programming to be able to attempt something like that.

I just wanted to check if something that would be possible . The "splitting the display into two" idea might be a good shout, again I'll try my best to make something work :-P

Thanks again, you the man!

Share this post


Link to post
Share on other sites

You mean you want to use another msp as an eeprom? TI has both spi and i2c sample code for that. You could even have the salve use write to empty info blocks or code space, for even more memory, but it won't be fast. It would allow you to detach the setup from a computer. But we are also only talking about at best 12k of extra space (between the salve code, and ram usage.) Plenty for a led display or matrix, but for a rgb 756 byte per image setup like yours? That's only 14 or so frames.

Share this post


Link to post
Share on other sites

Yeah that was the initial plan, but I've just been informed that I may get my hands on the F5438 board which has 16kB of RAM which would solve all of my problems. Could've done with that about a year ago... :-P

Thanks for your help though cde!

Share this post


Link to post
Share on other sites

The MSP430G2x55 (2755/2855/2955) have 4kB of RAM, not much either, but enough for your application. If you want to store animations you need to store them in flash anyway, in that case you can either use the internal flash (resp 32, 48, 56 kB for the former called)  or use a serial flash externally (1 MB is available, maybe even more). Though both will require some extra complexity in the form of either a flash writing routine (reading is peanuts) or a serial flash driver that buffers whole frames for you.

Share this post


Link to post
Share on other sites

@@roadrunner84, that's me got the MSP430F5438 board!

It has a ridiculous number of pins compared to the G2553.

Anyways, as usual I'm running into problems :P It'll probably be a trivial task for you.

I thought since I now have enough pins to use H/W SPI for the shift register (drives the columns), i'd try and give it a go. But I'm not sure I'm doing it right.

Since the TXBuffer is only 8-bits in length, would I need to split the desired output "data" into two, like upper byte and lower byte?

Something like this:

// In main
hsv2rgb(......);
SPI_shift(0x8001); // so the first and last columns would be lit.

void SPI_shift(u_long data)
{
P4OUT &= ~LATCH; // set latch low
low_byte = data & 0x80;  // so that lowbyte is only 8 bits, or should the mask be "0xFF"?
high_byte = data & 0x8000; // highbyte is upper byte, or should mask be 0xFF00?
                           // or high_byte = (data >> 8) & 0x80?
UCB1TXBUF =low_byte;
while!((UCB1IFG & UCTXIFG));
UCB1TXBUF =high_byte << 8; // am i along the right lines? it makes sense in my head
while!((UCB1IFG & UCTXIFG));
P4OUT |=  LATCH; // set latch high
P4OUT &= ~LATCH; // set latch low
}

Share this post


Link to post
Share on other sites

Nice, the F5 series are much more powerful, you wouldn't need to split the display in two, since you have plenty of RAM.

 

Your code is going towards the right:

void SPI_shift(unsigned short data) /* If you're intending to write 16 bits of information, go for a short instead of a long */
{
unsigned char low_byte, high_byte; /* let's declare the variables to store the two bytes */
P4OUT &= ~LATCH; // set latch low
low_byte = data & 0xFF;
high_byte = (data & 0xFF00) >> 8;
                           /* or high_byte = (data >> 8) & 0xFF; */
UCB1TXBUF =low_byte;
while!((UCB1IFG & UCTXIFG));
UCB1TXBUF =high_byte; /* since we shifted this byte already, we shouldn't shift it here; we want to send a 8-bit byte */
while!((UCB1IFG & UCTXIFG));
P4OUT |=  LATCH; // set latch high
P4OUT &= ~LATCH; // set latch low
}

Share this post


Link to post
Share on other sites

@@roadrunner84, I thought I was on the right track.

Anyways, I made the adjustments that you suggested but to no avail.

For some reason the correct columns are lighting up, as well as random columns popping up but at different brightness levels. I'm thinking this could be because of a timing issue?

I might just revert back to the shiftOut function that I've been using, since its so easy to do.

 

void SPI_shift(u_short data) /* If you're intending to write 16 bits of information, go for a short instead of a long */
{
	u_char low_byte, high_byte; /* let's declare the variables to store the two bytes */
	P4OUT &= ~LATCH; // set latch low
	low_byte = data & 0xFF;
	high_byte = (data & 0xFF00) >> 8;
	/* or high_byte = (data >> 8) & 0xFF; */
	UCB1TXBUF =low_byte;
	while(!(UCB1IFG & UCTXIFG));
	UCB1TXBUF =high_byte; /* since we shifted this byte already,*/
                              /*we shouldn't shift it here; we want to send a 8-bit byte */
	while(!(UCB1IFG & UCTXIFG));
	P4OUT |=  LATCH; // set latch high
	P4OUT &= ~LATCH; // set latch low
}

Share this post


Link to post
Share on other sites

@roadrunner84: I just decided to leave the h/w SPI for the shift register because the shiftOut function works absolutely fine as it is. I didnt realise how difficult it would be to map the G2553 code over to the F5438A device! That's me got my previous code working now though.

I looked back at this to try and continue with the final part of the project and I'm still not quite sure about hwo to extract the R,G and B values from the long string.

 

The first pixel is at position [0], the second at position [3], the third at position [6]. In a general sense pixel N is at position [N*GIMP_IMAGE_BYTES_PER_PIXEL].

Since the second line starts after the first line, and we know the (first) line is a known number of pixels wide, we can calculate the position of the first pixel of the second line by determining the number of pixels in a line and use that as the number of pixels. In this case, the first pixel of the second line (lines are 16 pixels wide) is the 17th pixel or pixel index [16]. In a more general sense, the first pixel of any row M is [M*GIMP_IMAGE_BYTES_PER_PIXEL*GIMP_IMAGE_WIDTH].

If we combine these two formulas. Then the Nth pixel of the Mth line becomes [N*GIMP_IMAGE_BYTES_PER_PIXEL + M*GIMP_IMAGE_BYTES_PER_PIXEL*GIMP_IMAGE_WIDTH], or a bit simpler [(N + (M*GIMP_IMAGE_WIDTH))*M*GIMP_IMAGE_BYTES_PER_PIXEL].

If you want to know the value of pixel (7,2) as tripwire used, the value becomes [(7 + (2*GIMP_IMAGE_WIDTH))*M*GIMP_IMAGE_BYTES_PER_PIXEL]. You see the formula is identical (with tripwire hardcoding 3 for GIMP_IMAGE_BYTES_PER_PIXEL).

Say I wanted the data for pixel(7,2). Then the equation above would be: [ (7 + (2 * 16) ) * 3 ] = 117? But how would you find the RGB values from that.

Also, if I wanted pixel(15,15) then eq = [ ( 15 + ( 15 * 16) ) * 3 ] = 765? I could be adding it up wrong though?

Share this post


Link to post
Share on other sites

@@tripwire

The red component of the pixel at (7, 2) should be at bytes_to_send[(7+(2*GIMP_IMAGE_WIDTH))*3]. There's one null-terminator at the end of the big string, which is why the character array length is ((Width*Height*BPP)+1).

 

Does this mean that the green component would be at [ ( 7+ ( 2 * gimp_image_width )) *2] ? 

and the blue at [ ( 7+ ( 2 * gimp_image_width )) *1]

Share this post


Link to post
Share on other sites

Does this mean that the green component would be at [ ( 7+ ( 2 * gimp_image_width )) *2] ? 

and the blue at [ ( 7+ ( 2 * gimp_image_width )) *1]

 

 

No, the array is arranged like this:

GIMP array layout for a 4x4 pixel image. Pixel coordinates are shown as (X,Y).

0 1 2 3 4 5 ...
R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B 0
|      \_/   \_/      | |      \_/   \_/      | |                     | |                     | |
|       |     |       | |       |     |       | |                     | |                     |  \_ Null terminator
|     (1,0) (2,0)     | |     (1,1) (2,1)     | |                     | |                     |    
|                     | |                     | |                     | |                     |
 \___________________/   \___________________/   \___________________/   \___________________/
           |                       |                       |                       |
         Row 0                   Row 1                   Row 2                   Row 3

 

The red, green and blue components of each pixel are stored as three consecutive elements of the array. The pixel at (X, Y) begins at index ((Y * WIDTH) + X) * 3) - that's the red component. Then green is at (((Y * WIDTH) + X) * 3) + 1) and blue is at (((Y * WIDTH) + X) * 3) + 2).

 

For the example you quoted, that would mean:

Pixel (7,2) red   is at bytes_to_send[  (( 2 * gimp_image_width ) + 7) * 3]
Pixel (7,2) green is at bytes_to_send[ ((( 2 * gimp_image_width ) + 7) * 3) + 1]
Pixel (7,2) blue  is at bytes_to_send[ ((( 2 * gimp_image_width ) + 7) * 3) + 2]

 

Hope that helps :smile:

Share this post


Link to post
Share on other sites

 

Say I wanted the data for pixel(7,2). Then the equation above would be: [ (7 + (2 * 16) ) * 3 ] = 117? But how would you find the RGB values from that.

Also, if I wanted pixel(15,15) then eq = [ ( 15 + ( 15 * 16) ) * 3 ] = 765? I could be adding it up wrong though?

The red component would be at 117, the green component . would be at 117+1=118 and the blue component would be at 117+2=119.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...