Hanna
Sourcecode Batteriemanagementsystem
ili9341.c
gehe zur Dokumentation dieser Datei
1 
45 #include "ili9341.h"
46 #include "ili9341_regs.h"
47 #include <util/delay.h>
48 
54 {
56 }
57 
63 {
65 }
66 
72 {
74 }
75 
81 {
83 }
84 
90 {
91 #if defined(CONF_ILI9341_USART_SPI)
92  while (!usart_tx_is_complete(CONF_ILI9341_USART_SPI))
93  {
94  /* Do nothing */
95  }
96  usart_clear_tx_complete(CONF_ILI9341_USART_SPI);
97 #elif defined(CONF_ILI9341_SPI)
98  /* Wait for TX to complete */
99  while ( !spi_is_tx_empty ( CONF_ILI9341_SPI ) )
100  {
101  /* Do nothing */
102  }
103 #endif
104 }
105 
116 __always_inline static void ili9341_send_byte ( uint8_t data )
117 {
118 #if defined(CONF_ILI9341_USART_SPI)
119  while (!usart_data_register_is_empty(CONF_ILI9341_USART_SPI))
120  {
121  /* Do nothing */
122  }
123 
124  irqflags_t flags = cpu_irq_save();
125  usart_clear_tx_complete(CONF_ILI9341_USART_SPI);
126  usart_put(CONF_ILI9341_USART_SPI, data);
127  cpu_irq_restore(flags);
128 #elif defined(CONF_ILI9341_SPI)
129  /* Wait for any previously running send data */
131 
132  spi_write_single ( CONF_ILI9341_SPI, data );
133 #endif
134 }
135 
146 __always_inline static uint8_t ili9341_read_byte ( void )
147 {
148  uint8_t data;
149 
150 #if defined(CONF_ILI9341_USART_SPI)
151  /* Workaround for clearing the RXCIF for XMEGA */
152  usart_rx_enable(CONF_ILI9341_USART_SPI);
153 
154  usart_put(CONF_ILI9341_USART_SPI, 0xFF);
155  while (!usart_rx_is_complete(CONF_ILI9341_USART_SPI))
156  {
157  /* Do nothing */
158  }
159  data = usart_get(CONF_ILI9341_USART_SPI);
160 
161  /* Workaround for clearing the RXCIF for XMEGA */
162  usart_rx_disable(CONF_ILI9341_USART_SPI);
163 #elif defined(CONF_ILI9341_SPI)
164  spi_write_single ( CONF_ILI9341_SPI, 0xFF );
165 
167 
168  /* Wait for RX to complete */
169  while ( !spi_is_rx_full ( CONF_ILI9341_SPI ) )
170  {
171  /* Do nothing */
172  }
173 
174  spi_read_single ( CONF_ILI9341_SPI, &data );
175 #endif
176 
177  return data;
178 }
179 
190 static void ili9341_send_command ( uint8_t command )
191 {
194  ili9341_send_byte ( command );
197 }
198 
199 static ili9341_coord_t limit_start_x, limit_start_y;
200 static ili9341_coord_t limit_end_x, limit_end_y;
201 
211 static void ili9341_send_draw_limits ( const bool send_end_limits )
212 {
213  ili9341_send_command ( ILI9341_CMD_COLUMN_ADDRESS_SET );
214  ili9341_send_byte ( limit_start_x >> 8 );
215  ili9341_send_byte ( limit_start_x & 0xFF );
216  if ( send_end_limits )
217  {
218  ili9341_send_byte ( limit_end_x >> 8 );
219  ili9341_send_byte ( limit_end_x & 0xFF );
220  }
223 
224  ili9341_send_command ( ILI9341_CMD_PAGE_ADDRESS_SET );
225  ili9341_send_byte ( limit_start_y >> 8 );
226  ili9341_send_byte ( limit_start_y & 0xFF );
227  if ( send_end_limits )
228  {
229  ili9341_send_byte ( limit_end_y >> 8 );
230  ili9341_send_byte ( limit_end_y & 0xFF );
231  }
234 }
235 
245 {
246  limit_start_x = x;
247  limit_start_y = y;
248 
249  ili9341_send_draw_limits ( false );
250 }
251 
261 {
262  limit_end_x = x;
263  limit_end_y = y;
264 
265  ili9341_send_draw_limits ( true );
266 }
267 
279 {
280  limit_start_x = start_x;
281  limit_start_y = start_y;
282  limit_end_x = end_x;
283  limit_end_y = end_y;
284 
285  ili9341_send_draw_limits ( true );
286 }
287 
304 {
305  uint8_t red, green, blue;
306 
307  ili9341_send_command ( ILI9341_CMD_MEMORY_READ );
308 
309  /* No interesting data in the first byte, hence read and discard */
310  red = ili9341_read_byte ();
311 
312  red = ili9341_read_byte ();
313  green = ili9341_read_byte ();
314  blue = ili9341_read_byte ();
315 
317 
318  return ILI9341_COLOR( red, green, blue );
319 }
320 
336 {
337  /* Only 16-bit color supported */
338  Assert( sizeof(color) == 2 );
339 
340  ili9341_send_command ( ILI9341_CMD_MEMORY_WRITE );
341  ili9341_send_byte ( color );
342  ili9341_send_byte ( color >> 8 );
345 }
346 
362 void ili9341_copy_pixels_to_screen ( const ili9341_color_t *pixels, uint32_t count )
363 {
364  const ili9341_color_t *pixel = pixels;
365 
366  /* Sanity check to make sure that the pixel count is not zero */
367  Assert( count > 0 );
368 
369  ili9341_send_command ( ILI9341_CMD_MEMORY_WRITE );
370 
371 #if defined(ILI9341_DMA_ENABLED)
372  ili9341_color_t chunk_buf[ILI9341_DMA_CHUNK_SIZE];
373  uint32_t chunk_len;
374 
375  while (count)
376  {
377  /* We need to copy out the data to send in chunks into RAM, as the PDC
378  * does not allow FLASH->Peripheral transfers */
379  chunk_len = min(ILI9341_DMA_CHUNK_SIZE, count);
380 
381  /* Wait for pending transfer to complete */
383 
384  for (uint32_t i = 0; i < chunk_len; i++)
385  {
386  chunk_buf[i] = le16_to_cpu(pixel[i]);
387  }
388 
389  pixel += chunk_len;
390  count -= chunk_len;
391  }
392 
395 
396 #else
397  while ( count-- )
398  {
399  ili9341_send_byte ( *pixel );
400  ili9341_send_byte ( *pixel >> 8 );
401 
402  pixel++;
403  }
404 
407 #endif
408 }
409 
426 void ili9341_copy_progmem_pixels_to_screen ( ili9341_color_t PROGMEM_PTR_T pixels, uint32_t count, uint8_t swap)
427 {
428  ili9341_color_t color;
429 
430  /* Sanity check to make sure that the pixel count is not zero */
431  Assert(count > 0);
432 
433  ili9341_send_command(ILI9341_CMD_MEMORY_WRITE);
434 
435  while (count--)
436  {
437  color = PROGMEM_READ_WORD(pixels);
438 
439  if(swap)
440  {
441  ili9341_send_byte(color);
442  ili9341_send_byte(color >> 8);}
443  else
444  {
445  ili9341_send_byte(color >> 8);
446  ili9341_send_byte(color);}
447 
448  pixels++;
449  }
450 
453 }
454 
471 void ili9341_duplicate_pixel ( const ili9341_color_t color, uint32_t count )
472 {
473  /* Sanity check to make sure that the pixel count is not zero */
474  Assert( count > 0 );
475 
476  ili9341_send_command ( ILI9341_CMD_MEMORY_WRITE );
477 
478  while ( count-- )
479  {
480  ili9341_send_byte ( color );
481  ili9341_send_byte ( color >> 8 );
482  }
483 
486 }
487 
503 void ili9341_copy_pixels_from_screen ( ili9341_color_t *pixels, uint32_t count )
504 {
505  uint8_t red, green, blue;
506 
507  /* Sanity check to make sure that the pixel count is not zero */
508  Assert( count > 0 );
509 
510  ili9341_send_command ( ILI9341_CMD_MEMORY_READ );
511 
512  /* No interesting data in the first byte, hence read and discard */
513  red = ili9341_read_byte ();
514 
515  while ( count-- )
516  {
517  red = ili9341_read_byte ();
518  green = ili9341_read_byte ();
519  blue = ili9341_read_byte ();
520 
521  *pixels = ILI9341_COLOR( red, green, blue );
522  pixels++;
523  }
524 
526 }
527 
538 static void ili9341_interface_init ( void )
539 {
540 #if defined(CONF_ILI9341_USART_SPI) || defined(CONF_ILI9341_SPI)
541  spi_flags_t spi_flags = SPI_MODE_0;
542  board_spi_select_id_t spi_select_id = 0;
543 #else
544 #error Interface for ILI9341 has not been selected or interface not supported, please configure component driver using the ili9341.h file!
545 #endif
546 
547 #if defined(CONF_ILI9341_USART_SPI)
548  struct usart_spi_device device =
549  {
550  .id = 0,
551  };
552 
553  usart_spi_init(CONF_ILI9341_USART_SPI);
554  usart_spi_setup_device(CONF_ILI9341_USART_SPI, &device, spi_flags, CONF_ILI9341_CLOCK_SPEED, spi_select_id);
555 
556 #elif defined(CONF_ILI9341_SPI)
557  struct spi_device device = { .id = 0, };
558 
559  spi_master_init ( CONF_ILI9341_SPI );
560  spi_master_setup_device ( CONF_ILI9341_SPI, &device, spi_flags,
561  CONF_ILI9341_CLOCK_SPEED, spi_select_id );
562  spi_enable ( CONF_ILI9341_SPI );
563 
564  /* Send one dummy byte for the spi_is_tx_ok() to work as expected */
565  spi_write_single ( CONF_ILI9341_SPI, 0 );
566 #endif
567 }
568 
577 {
578  ili9341_send_command ( ILI9341_CMD_POWER_CONTROL_A );
579  ili9341_send_byte ( 0x39 );
580  ili9341_send_byte ( 0x2C );
581  ili9341_send_byte ( 0x00 );
582  ili9341_send_byte ( 0x34 );
583  ili9341_send_byte ( 0x02 );
586 
587  ili9341_send_command ( ILI9341_CMD_POWER_CONTROL_B );
588  ili9341_send_byte ( 0x00 );
589  ili9341_send_byte ( 0xAA );
590  ili9341_send_byte ( 0XB0 );
593 
594  ili9341_send_command ( ILI9341_CMD_PUMP_RATIO_CONTROL );
595  ili9341_send_byte ( 0x30 );
598 
599  ili9341_send_command ( ILI9341_CMD_POWER_CONTROL_1 );
600  ili9341_send_byte ( 0x25 );
603 
604  ili9341_send_command ( ILI9341_CMD_POWER_CONTROL_2 );
605  ili9341_send_byte ( 0x11 );
608 
609  ili9341_send_command ( ILI9341_CMD_VCOM_CONTROL_1 );
610  ili9341_send_byte ( 0x5C );
611  ili9341_send_byte ( 0x4C );
614 
615  ili9341_send_command ( ILI9341_CMD_VCOM_CONTROL_2 );
616  ili9341_send_byte ( 0x94 );
619 
620  ili9341_send_command ( ILI9341_CMD_DRIVER_TIMING_CONTROL_A );
621  ili9341_send_byte ( 0x85 );
622  ili9341_send_byte ( 0x01 );
623  ili9341_send_byte ( 0x78 );
626 
627  ili9341_send_command ( ILI9341_CMD_DRIVER_TIMING_CONTROL_B );
628  ili9341_send_byte ( 0x00 );
629  ili9341_send_byte ( 0x00 );
632 
633  ili9341_send_command ( ILI9341_CMD_COLMOD_PIXEL_FORMAT_SET );
634  ili9341_send_byte ( 0x05 );
637 
641 }
642 
650 static void ili9341_exit_standby ( void )
651 {
652  ili9341_send_command ( ILI9341_CMD_SLEEP_OUT );
654  _delay_ms ( 150 );
655  ili9341_send_command ( ILI9341_CMD_DISPLAY_ON );
657 }
658 
665 static void ili9341_reset_display ( void )
666 {
668  _delay_ms ( 10 );
670  _delay_ms ( 10 );
672  _delay_ms ( 150 );
673 }
674 
683 void ili9341_init ( void )
684 {
685  /* Initialise the communication interface */
687 
688  /* Reset the display */
690 
691  /* Send commands to exit standby mode */
693 
694  /* Write all the controller registers with correct values */
696 }
697 
707 void ili9341_set_orientation ( uint8_t flags )
708 {
709  uint8_t madctl = 0x48;
710 
711  /* Pretend the display is in landscape mode by default to match other display drivers */
713 
714  if ( flags & ILI9341_FLIP_X )
715  {
716  madctl &= ~(1 << 6);
717  }
718 
719  if ( flags & ILI9341_FLIP_Y )
720  {
721  madctl |= 1 << 7;
722  }
723 
724  if ( flags & ILI9341_SWITCH_XY )
725  {
726  madctl |= 1 << 5;
727  }
728 
729  ili9341_send_command ( ILI9341_CMD_MEMORY_ACCESS_CONTROL );
730  ili9341_send_byte ( madctl );
733 }
static __always_inline void ili9341_select_chip(void)
Helper function to select the CS of the controller on the bus.
Definition: ili9341.c:53
static bool spi_is_rx_full(SPI_t *spi)
Tests if the SPI contains a received character.
Definition: spi_master.h:409
#define ILI9341_FLIP_Y
Definition: ili9341.h:157
static void ili9341_reset_display(void)
Reset the display using the digital control interface.
Definition: ili9341.c:665
void ili9341_write_gram(ili9341_color_t color)
Write the graphical memory with a single color pixel.
Definition: ili9341.c:335
static __always_inline void ili9341_send_byte(uint8_t data)
Helper function to send a byte over an arbitrary interface.
Definition: ili9341.c:116
static __always_inline void ili9341_select_data_mode(void)
Helper function to select data byte transmission mode.
Definition: ili9341.c:80
Polled SPI device definition.
Definition: spi_master.h:250
#define CONF_ILI9341_CS_PIN
Define what MCU pin the ILI9341 chip select pin is connected to.
Definition: ili9341.h:77
#define ILI9341_SWITCH_XY
Definition: ili9341.h:159
port_pin_t id
Board specific select id.
Definition: spi_master.h:252
#define Assert(expr)
This macro is used to test fatal errors.
Definition: compiler.h:46
static void spi_read_single(SPI_t *spi, uint8_t *data)
Receive one byte from a SPI device.
Definition: spi_master.h:359
void ili9341_set_orientation(uint8_t flags)
Sets the orientation of the display data.
Definition: ili9341.c:707
void spi_master_setup_device(SPI_t *spi, struct spi_device *device, spi_flags_t flags, uint32_t baud_rate, board_spi_select_id_t sel_id)
Setup a SPI device.
Definition: spi_master.c:175
void spi_master_init(SPI_t *spi)
Initializes the SPI in master mode.
Definition: spi_master.c:126
void ili9341_init(void)
Initialise the controller.
Definition: ili9341.c:683
static __always_inline void ili9341_select_command_mode(void)
Helper function to select command byte transmission mode.
Definition: ili9341.c:71
void ili9341_set_limits(ili9341_coord_t start_x, ili9341_coord_t start_y, ili9341_coord_t end_x, ili9341_coord_t end_y)
Set the full display drawing limits.
Definition: ili9341.c:278
#define SPI_MODE_0
SPI mode 0.
Definition: spi_master.h:232
int16_t ili9341_coord_t
Definition: ili9341.h:147
void IO_SetPinHigh(PORT_t *port, uint8_t pinMask)
This function sets a bit in the OUT register of an I/O port or virtual port.
Definition: port_driver.c:108
#define ILI9341_DEFAULT_HEIGHT
Definition: ili9341.h:164
static void ili9341_interface_init(void)
Initialize the hardware interface to the controller.
Definition: ili9341.c:538
IL9341 Display Controller Register und Bitfield Definitionen aus dem ASF 3.26.0.
static void spi_enable(SPI_t *spi)
Enables the SPI.
Definition: spi_master.h:112
void ili9341_copy_progmem_pixels_to_screen(ili9341_color_t PROGMEM_PTR_T pixels, uint32_t count, uint8_t swap)
Copy pixels from progmem to the screen.
Definition: ili9341.c:426
#define ILI9341_FLIP_X
Definition: ili9341.h:155
static __always_inline uint8_t ili9341_read_byte(void)
Helper function to read a byte from an arbitrary interface.
Definition: ili9341.c:146
void IO_SetPinLow(PORT_t *port, uint8_t pinMask)
This function clears a bit in the OUT register of an I/O port or virtual port.
Definition: port_driver.c:121
#define ILI9341_DEFAULT_WIDTH
Definition: ili9341.h:167
static __always_inline void ili9341_wait_for_send_done(void)
Helper function to wait for the last send operation to complete.
Definition: ili9341.c:89
static __always_inline void ili9341_deselect_chip(void)
Helper function to de-select the CS of the controller on the bus.
Definition: ili9341.c:62
void ili9341_set_top_left_limit(ili9341_coord_t x, ili9341_coord_t y)
Set the display top left drawing limit.
Definition: ili9341.c:244
void ili9341_copy_pixels_to_screen(const ili9341_color_t *pixels, uint32_t count)
Copy pixels from SRAM to the screen.
Definition: ili9341.c:362
static void ili9341_send_command(uint8_t command)
Sends a command to the controller, and prepares for parameter transfer.
Definition: ili9341.c:190
#define CONF_ILI9341_CLOCK_SPEED
Select the correct hardware interface.
Definition: ili9341.h:74
static __always_inline void spi_write_single(SPI_t *spi, uint8_t data)
Write one byte to a SPI device.
Definition: spi_master.h:334
#define CONF_ILI9341_RESET_PIN
Define what MCU pin the ILI9341 back light pin is connected to.
Definition: ili9341.h:86
ILI9341 Display Controller Component Driver aus dem ASF 3.26.0.
uint16_t ili9341_color_t
Definition: ili9341.h:143
#define ILI9341_COLOR(r, g, b)
Definition: ili9341.h:140
void ili9341_duplicate_pixel(const ili9341_color_t color, uint32_t count)
Set a given number of pixels to the same color.
Definition: ili9341.c:471
ili9341_color_t ili9341_read_gram(void)
Read a single color from the graphical memory.
Definition: ili9341.c:303
static void ili9341_controller_init_registers(void)
Initialize all the display registers.
Definition: ili9341.c:576
static void ili9341_exit_standby(void)
Send display commands to exit standby mode.
Definition: ili9341.c:650
static bool spi_is_tx_empty(SPI_t *spi)
Checks if all transmissions are complete.
Definition: spi_master.h:385
static void ili9341_send_draw_limits(const bool send_end_limits)
Helper function to send the drawing limits (boundaries) to the display.
Definition: ili9341.c:211
void ili9341_copy_pixels_from_screen(ili9341_color_t *pixels, uint32_t count)
Copy pixels from the screen to a pixel buffer.
Definition: ili9341.c:503
#define CONF_ILI9341_DC_PIN
Define what MCU pin the ILI9341 DC pin is connected to.
Definition: ili9341.h:80
void ili9341_set_bottom_right_limit(ili9341_coord_t x, ili9341_coord_t y)
Set the display bottom right drawing limit.
Definition: ili9341.c:260
#define __always_inline
The function should always be inlined.
Definition: compiler.h:127