Inputbuffer is referenced later in that function, in the memcpy (which copies 8 bytes)
/**
* Write formatted datablock to STLED316S
*
* *** this is the only function which accesses the display ***
*
* @param DisplayData_t data Array of STLED316S_DISPLAY_MEM (6) bytes (starting at address 0)
*
* The data is ASCII characters. All 6 get written to the chip but the number which appears obviously depends
* on how many 7-seg LEDs are installed. The 655 board has an option for 5, if the light sensor position is used.
*
* There are two ways to display a decimal point:
*
* 1) if bit 7 = 1 then DP will be illuminated for that character
*
* 2) if a (non-first) char is '.' then the previous char's bit 7 is set, and remaining bytes are shuffled left, until 0x00
* Only 1 decimal point is supported within the display string, and it must not be the 1st char (e.g .1234)
*
* Note that sprintf puts a 0x00 at the end, so one needs the source buffer to be longer than the
* 6 max digits of the STLED316. This function gets an address of the buffer only, so it doesn't care if the
* source buffer has been overrun :) If printing decimal points, you will need 2 extra bytes (1 for the dp and 1 for the 0x00
* which sprintf puts in at the end)
*
* @param brightness integer 0-15
* @return none
*/
void display_formatted_string(uint8_t *inputbuffer, uint8_t brightness)
{
int i;
bool dpfound=false;
uint8_t tempbuffer[STLED316S_DISPLAY_MEM+2]; // use local buffer to avoid corrupting the input buffer
static uint8_t dispbuffer[STLED316S_DISPLAY_MEM+3]; // this holds the raw segment format for the STLED316 chip
static const uint8_t brt_translate[16] = { 0,1,2,8,3,9,4,5,6,7,10,11,12,13,14,15 };
brightness &= 0x0F; // limit value 0..15
memcpy(tempbuffer,inputbuffer,STLED316S_DISPLAY_MEM+2); // make a local copy of the display data
if (tempbuffer[0]==0x00) return; // abandon if 1st char is a null
// Handle lone DP char detection and left shuffling
i=1; // skip 1st char
do
{
if ( tempbuffer[i]=='.' ) { dpfound=true; }
i++;
}
while ( ( i < STLED316S_DISPLAY_MEM+2 ) && ( tempbuffer[i] != 0x00 ) && ( dpfound == false ) );
i--; // if a DP was found, i now points at the DP char
if ( dpfound )
{
tempbuffer[i-1]|=0x80; // set the DP on previous digit
while ( ( i < STLED316S_DISPLAY_MEM+2 ) && ( tempbuffer[i] != 0x00 ) )
{
tempbuffer[i]=tempbuffer[i+1]; // shuffle 1 left
i++;
}
}
// Convert ASCII characters via the font table; without regard for any bit 7 set, and replacing < 20h with blank digits
// We fill dispbuffer after 1st byte
for (i = 0; i < STLED316S_DISPLAY_MEM; i++)
{
if ( tempbuffer[i] >= 0x20 )
{
dispbuffer[i+1] = FONT_7S[ ( tempbuffer[i] & 0x7F ) - 0x20];
}
else // invalid char
{
dispbuffer[i+1] = 0x00; // 0x00 to blank the digit
}
if ( tempbuffer[i] & 0x80 )
{
dispbuffer[i+1] |= 0x80; // if bit 7 was set on input byte, set it now in the output
}
}
// re-order brightness values to get a monotonic rise
brightness = brt_translate[brightness];
// Values 0 to 7 select low current (10mA), 8 to 15 high current (40mA)
display_set_current(brightness > 7);
SPI3_Lock();
// If current SPI3 init is not this device, initialise it
if ( g_spi3_current_config != SPI_MODE_STLED316 )
{
spi3_set_mode(SPI_MODE_STLED316);
g_spi3_current_config = SPI_MODE_STLED316;
}
// STLED316S display duty cycle values for brightness are 0 to 7
display_set_global_brightness(brightness % 8);
// This delay (10us just works) is needed after loading the brightness data, before the rest
hang_around_us(20);
dispbuffer[0] = (STLED316S_ADDR_WR_CMD | STLED316S_IDX(STLED316S_DIG_PAGE, 0x00)); // Set Address at 0
// Write all digits in one go
display_cs(0);
hang_around_us(STLED_GEN_WAIT);
SPI3_DMA_TransmitReceive(dispbuffer, NULL, STLED316S_DISPLAY_MEM+1, true, false, RTOS_YIELD);
hang_around_us(STLED_GEN_WAIT);
display_cs(1);
hang_around_us(STLED_GEN_WAIT); // Min CS=1 time
SPI3_Unlock();
}
The compiler probably doesn't like the call to the function
display_formatted_string((uint8_t *) "APP ", 15);
which supplies a null terminated string of 7 bytes total. But we are only reading the source buffer, not writing it. Yes I know it is bad practice to read past the end of a buffer. On the 32F417 it doesn't matter but would do if the said source buffer happened to sit on the very end of physical RAM and then you get a trap.
Re the buffer sizes I think something has been changed in the checking level. GCC v10 was fine with it. And the code runs fine, FWIW.
Doing some digging around compiler options. Nothing has changed
(https://peter-ftp.co.uk/screenshots/202307164117485221.jpg)
(https://peter-ftp.co.uk/screenshots/202307164517495321.jpg)
On the ST forum, some reports of people reverting back to GCC v10 to continue working. And no solution for the "explicit encoding set" - something to do with Java?
See this example how I have silenced specific warnings in the past, successfully:
#define IO_SET_ALTFUNC(port, pin, af) do{ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshift-count-negative\"") _Pragma("GCC diagnostic ignored \"-Wshift-count-overflow\"") \
if((pin)<8) {uint32_t _tmp_ = (port)->AFR[0]; _tmp_ &= ~(0b1111UL<<((pin)*4)); _tmp_ |= af<<((pin)*4); (port)->AFR[0] = _tmp_;} \
else {uint32_t _tmp_ = (port)->AFR[1]; _tmp_ &= ~(0b1111UL<<(((pin)-8)*4)); _tmp_ |= af<<(((pin)-8)*4); (port)->AFR[1] = _tmp_;} _Pragma("GCC diagnostic pop") }while(0)
The hard part is inspecting the code to try to figure out what it is doing ...
As the comment in the Open Watcom source files (https://github.com/open-watcom/open-watcom-v2/blob/master/bld/wdisasm/c/wdismsg.c) says:
* ...
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
* ...