0
\$\begingroup\$

i successfully used a HAL code i found on Github for driving an ili9341 TFT LCD with SPI then I rewrote the code with registers. Part of my code works and i am able to fill pixels with color but when i try to use a function named ILI9341_Draw_Colour_Burst the code doesn't work. I tried to use the Keil debugger to see what happens and it showed a hard fault occurred. The function code is shown below

void ILI9341_Draw_Colour_Burst(uint16_t Colour, uint32_t Size)
{
//SENDS COLOUR
uint32_t Buffer_Size = 0;
if((Size*2) < BURST_MAX_SIZE)
{
    Buffer_Size = Size;
}
else
{
    Buffer_Size = BURST_MAX_SIZE;
}
    
LCD_DC_PORT->BSRR |= LCD_DC_PIN;
LCD_CS_PORT->BRR |= LCD_CS_PIN;

unsigned char chifted =     Colour>>8;;
unsigned char burst_buffer[Buffer_Size];
for(uint32_t j = 0; j < Buffer_Size; j+=2)
    {
        burst_buffer[j] =   chifted;
        burst_buffer[j+1] = Colour;
    }

uint32_t Sending_Size = Size*2;
uint32_t Sending_in_Block = Sending_Size/Buffer_Size;
uint32_t Remainder_from_block = Sending_Size%Buffer_Size;

if(Sending_in_Block != 0)
{
    for(uint32_t j = 0; j < (Sending_in_Block); j++)
        {
        write_buffer32((unsigned char *)burst_buffer,Buffer_Size)   ;
        }
}

//REMAINDER!
    
write_buffer32((unsigned char *)burst_buffer,Remainder_from_block)  ;
    
LCD_CS_PORT->BSRR |= LCD_CS_PIN;
}

and the code i wrote for SPI is as follows:

    #define RXNE    0x01
#define TXE     0x02
#define BSY     0x80


void  SPIInit(void)
{ 
     
   RCC->APB2ENR |=  (1<<12);      /* Enable SPI1 clock   */
     GPIOA->CRL&=~0xFFF00000;
   GPIOA->CRL |=0xB4B00000;
     
  
  /* Enable SPI in Master Mode, CPOL=0, CPHA=0. */
  /* Clock speed = fPCLK1 / 256 = 280 kHz at 72 MHz PCLK1 clk. */
    SPI1->CR1  = (0 << 0) | // Clock phase
                 (0 << 1) | // Clock polarity 
               (1 << 2) | // Master selection
             (1 << 3) | // Baud rate control clock/2
                             (1 << 6) | // SPI enable
                             (0 << 7) | // Frame format : 0: MSB transmitted first
                             (1 << 8) | // Internal slave select
                             (1 << 9) | // Software slave management enabled
                             (0 << 11); // Data frame format :  0: 8-bit
  SPI1->CR2  = 0x0000;  
}

u8 SPI1_WriteByte(uint8_t TxData)
{       
  /* Loop while DR register in not emplty , 1: Tx buffer empty*/
   while ((SPI1->SR & TXE) == 0);
   /* Send byte through the SPI2 peripheral */
   SPI1->DR = TxData;
   /* Wait to receive a byte ,1: Rx buffer not empty*/
   while ((SPI1->SR & RXNE) == 0);
   /* Return the byte read from the SPI bus */
   return SPI1->DR;             
 
                
}

void write_buffer(unsigned char *data,u8 size)
{
  u8 i;
 
  for(i=0;i<size;i++) 
  SPI1_WriteByte(data[i]);
 
}

void write_buffer32(unsigned char *data,int size)
{
  int i;
 
  for(i=0;i<size;i++) 
  SPI1_WriteByte(data[i]);
 
}
\$\endgroup\$
4
  • 1
    \$\begingroup\$ How much is BURST_MAX_SIZE and with which parametets for size you call the function? Where exactly does the hard fault occur? Could it simply be that you dynamically allocate the array and you run out of stack space? Or is it only because the code allocates size amount of bytes, but if size is odd, you need size+1 bytes as you use the buffer as pairs of bytes? \$\endgroup\$
    – Justme
    Commented Feb 28, 2021 at 7:30
  • 1
    \$\begingroup\$ BURST_MAX_SIZE is 500 and the hard fault occurs at burst_buffer[j] = shifted; And the function call code is void ILI9341_Fill_Screen(uint16_t Colour) { ILI9341_Set_Address(0,0,LCD_WIDTH,LCD_HEIGHT); ILI9341_Draw_Colour_Burst(Colour, LCD_WIDTH*LCD_HEIGHT); } \$\endgroup\$
    – salar1991
    Commented Feb 28, 2021 at 9:42
  • 1
    \$\begingroup\$ Okay, what is j variable value when problem happens? What are LCD_WIDTH and LCD_HEIGHT? If they are macros, expand them too. Or just tell me what number it amounts to when calling the function? And are you sure you have the necessary bytes left in the stack to do that? \$\endgroup\$
    – Justme
    Commented Feb 28, 2021 at 10:21
  • \$\begingroup\$ j is 0 when the problem happens. the LCD_WIDTH and LCD_HEIGHT are 320 and 240. but I tried decreasing these numbers to 1 but the result is still the same. \$\endgroup\$
    – salar1991
    Commented Feb 28, 2021 at 13:55

1 Answer 1

0
\$\begingroup\$

my problem is solved now I changed the value of BURST_MAX_SIZE from 500 to 100 and the function works now. I'm still curious about why the hard fault happened in the debugger

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.