I'm trying to use above mentioned function for scrooling displaycontent. (lets say that function DRAW_Putc uses this function). but when it comes to read data from the lcd, primer2 "crashs" at
// First read byte is dummy! LCD_ReadLCDData();"
it's even not possible to pause debugging...
Code:
/*******************************************************************************
*
* LIST_LCD_RectRead
*
*******************************************************************************/
/**
*
* Save the pixels of a rectangle part of the LCD into a RAM variable.
* Use of DMA tranfer.
*
* @param[in] x The horizontal coordinate of the rectangle low left corner.
* @param[in] y The vertical coordinate of the rectangle low left corner.
* @param[in] width The rectangle width in pixels.
* @param[in] height The rectangle height in pixels.
*
* @warning One pixel weights 2 bytes.
* @warning The (0x0) point in on the low left corner.
* @warning The transfer is made by DMA
* @warning The transfer should be done in 16 bits format due to the 4 bits shift of the bus
*
**/
/******************************************************************************/
void LIST_LCD_RectRead( u16 x, u16 y, u16 width, u16 height )
{
/* Select LCD screen area. */
LCD_SetRect_For_Cmd( x, y, width, height );
/* Restore 18 bit color mode */
LCD_SendLCDCmd( ST7732_COLMOD );
LCD_SendLCDData( 0x66 );
/* Send LCD RAM read command. */
LCD_SendLCDCmd( ST7732_RAMRD );
// First read byte is dummy!
LCD_ReadLCDData();
// Read pixels from LCD screen to memory by DMA
DMA_Cmd( DMA1_Channel2, ENABLE );
// Wait end of transfer
while (!DMA_GetFlagStatus(DMA1_FLAG_TC2))
{};
DMA_ClearFlag(DMA1_FLAG_TC2);
DMA_Cmd( DMA1_Channel2, DISABLE );
DMA_Init( DMA1_Channel2, &DMA_InitStructureRead );
/* Restore 16 bit color mode */
LCD_SendLCDCmd( ST7732_COLMOD );
LCD_SendLCDData( 0x55 );
}
Code:
/***********************************************************************************
*
* LCD_ReadLCDData
*
************************************************************************************/
/**
*
* Read one data byte from the LCD.
*
* @return An unsigned 32 bit word containing the data returned by a LCD command.
* @pre An LCD_SendLCDCmd was done with a command returning data.
*
**/
/********************************************************************************/
u32 LCD_ReadLCDData( void )
{
/* Transfer data from the memory */
return ( ( *(u16 volatile*) (LCD_DATA_MODE_ADDR) ) >>4) ;
}
when i change the function to
Code:
return ((LCD_DATA_MODE_ADDR)>>4);
it works, but then function
// Read pixels from LCD screen to memory by DMA DMA_Cmd( DMA1_Channel2, ENABLE );
At list it works when you list the applications... We wanted to provide the 'scroll' function as a standard function of the API, but it has not been finalized (next version of CircleOS). I guess that the call to 'InitListDMA()' is missing in your case.
this is the function i'm using - as you can see, InitListDMA() is called
Code:
/*******************************************************************************
*
* DRAW_Putc
*
*******************************************************************************/
/**
*
* Display at current coordinates the provided ASCII character with the current
* text and background colors and with the current magnify coefficient.
*
* @param[in] Ascii The ASCII code of the character to display.
* @n Ascii must be higher than 31 and lower than 255.
* '\n' managed as CRLF.
*
* @note If the low Y margin is reached, the text is scrolled into
* the window defined by the X and Y margins
* @see DRAW_SetCursorMargin
**/
/******************************************************************************/
void DRAW_Putc( u8 Ascii )
{
int y, i, Nblines, width;
int Char_Y = CHAR_HEIGHT * CharMagniCoeff;
/* CRLF ? */
if ( (Ascii == '\n') )
{
PosCurX = LeftMarginX;
if (PosCurY >= LowMarginY)
{
PosCurY -= (CHAR_HEIGHT * CharMagniCoeff);
}
return;
}
// Line change, if end of line reached
if ((PosCurX + (CHAR_WIDTH * CharMagniCoeff)) > RightMarginX )
{
PosCurX = LeftMarginX;
PosCurY -= Char_Y;
}
// Normal print if end of screen not reached
if (PosCurY >= LowMarginY)
{
// Display the selected bitmap according to the provided ASCII character.
LCD_DisplayChar( PosCurX, PosCurY, Ascii, TextColor, BGndColor, CharMagniCoeff );
}
else
{
// Else, scroll the screen each line to the top
InitListDMA();
Nblines = (LowMarginY - PosCurY) / DELTA_Y;
width = RightMarginX - LeftMarginX;
for (i=0; i<Nblines ; i++)
{
for( y = HighMarginY - DELTA_Y; y >= LowMarginY, y >= DELTA_Y; y -= DELTA_Y)
{
LIST_LCD_RectRead( LeftMarginX, y - DELTA_Y, width, DELTA_Y );
LIST_DRAW_SetImage( LeftMarginX, y, width, DELTA_Y );
}
}
PosCurY = LowMarginY;
// Display the selected bitmap according to the provided ASCII character.
LCD_DisplayChar( PosCurX, PosCurY, Ascii, TextColor, BGndColor, CharMagniCoeff );
}
PosCurX += (CHAR_WIDTH * CharMagniCoeff);
}
We wanted to provide the 'scroll' function as a standard function of the API, but it has not been finalized (next version of CircleOS).
well, the problem is not the scroll function but rather the problem that it is not possible to me to read data from the LCD because when i do so, primer2 hangs or crashs...
scroll functionality is an easy. just drop first top line to have on free bottom line. i don't need a special scroll function with other functionality...
$1
sending data at least is no problem, because i can write something on the LCD or can do some other basics like lines...
Note that if you call LCD_ReadLCDData( void ), you don't need the DMA... This function just returns the value read on the bus. Of course: return ((LCD_DATA_MODE_ADDR)>>4); returns the address divided by 16... and does not make sense. You need to shift the data read on the FSMC bus because the LSB are used for CAN.
To read the LCD data, I suggest first that you don't use the DMA (as for the pointer management). It will work without doubt. In your case, I guess that the issue is within the DMA, but you don't have to mix both DMA read and direct accesses.
Note that if you call LCD_ReadLCDData( void ), you don't need the DMA... This function just returns the value read on the bus. Of course: return ((LCD_DATA_MODE_ADDR)>>4); returns the address divided by 16... and does not make sense. You need to shift the data read on the FSMC bus because the LSB are used for CAN.
oh, damn, you're right, my fault shifting data is clear for me...
Francis :
To read the LCD data, I suggest first that you don't use the DMA (as for the pointer management). It will work without doubt. In your case, I guess that the issue is within the DMA, but you don't have to mix both DMA read and direct accesses.
i've just commented out the DMA-functions, but it's still not possible to get it work, because it hangs on LCD_ReadLCDData();
This line is quite simple: it reads on the FSMC bus a 16-bit word at the address LCD_DATA_MODE_ADDR. It is used for different purposes, for example when reading the area covered by the pointer (the small blue ball on the welcome page). Does this ball works ? If Yes, it means that the line should work in your application (or you have either the FSMC or the DMA misconfigured ...). Are you debugging within CircleOS? If not, it could be that you don't have the correct value for LCD_DATA_MODE_ADDR... (or again the FSMC misconfigured).
i don't use circleOS but i tried. i tried to use function DRAW_Puts() with a string that is longer to be displays one by one on the display, so it should be scrolled, but it didn't worked...
but to come back to my function: i included draw.c, list.c and lcd.c from the circleOS folder so that i can use those functions... when compileing i dont get any errors, so compileing is working. writeing data on the LCD is also no problem, so LCD_DATA_MODE_ADDR have to be the right and FSMC cofig is done by LCD_init() which calls FSMC_init() which i took from the circleOS lcd.c file - thats why i'm wondering it's not working :confuesd:
Ok... I understand the context now, but I don't see why it does not work. I never got any crash when reading thru the FSMC. Using FSMC + DMA could be more difficult (if, for example, you write out of the valid RAM), but reading simply the address is supposed to be quite simple and quite secure. A suggestion: open the disassembly view, and execute the assembly lines step-by-step to check that the crash occures when reading the external data. Moreover, you could also check the address at the same time...
I don't have my Primer2 here, but I checked the sequence and I have, in simulation, a similar sequence of instructions. I say 'similar' because it's not the same (I am in 'size Optimization', but R3 is loaded with the same address. Obviously, if reading this value generates an exception, it is probably because the FSMC (GPIOS?) is misconfigured, or because the DMA is also working in the same range.
i've tried "size optimization", but than the damn hole thing hangs on LCD initialization - WriteCOM(ST7732_SLPIN)
while debugging step by step it jumps to were it wants to but not in a straight way from lower to higher addresses :confused: and why it hangs on writeing to the LCD (sleep in), nobody knows... it's the same behavor like when it hangs on reading from LCD - i can't do anythink except stop debugging and restart...
maybe i can send you the project ziped and you may take a look at it?
well, thats what i've done - i've removed every part i don't need from CircleOS, but the same problem. by the way, i do have the same problem with size optimization now, but thats not the point...
now i use lcd_readlcddate() but it doesn't work, because it hangs. when i have a look at the memory view, there is nothing to read at address 68020000 after sending the ST7732_RAMRD command to the lcd
as i mentioned in post nr 9, the same problem occours running CircleOS