MAX7219/MAX7221 dirver + example
This commit is contained in:
		
							parent
							
								
									c21f70366f
								
							
						
					
					
						commit
						87b4befd87
					
				
					 6 changed files with 383 additions and 0 deletions
				
			
		
							
								
								
									
										3
									
								
								examples/max7219_7seg/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								examples/max7219_7seg/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| PROGRAM = max7219_7seg | ||||
| EXTRA_COMPONENTS = extras/max7219 | ||||
| include ../../common.mk | ||||
							
								
								
									
										52
									
								
								examples/max7219_7seg/main.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								examples/max7219_7seg/main.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,52 @@ | |||
| /*
 | ||||
|  * Example of using MAX7219 driver with 7 segment displays | ||||
|  * | ||||
|  * Part of esp-open-rtos | ||||
|  * Copyright (C) 2017 Ruslan V. Uss <unclerus@gmail.com> | ||||
|  * BSD Licensed as described in the file LICENSE | ||||
|  */ | ||||
| #include <esp/uart.h> | ||||
| #include <espressif/esp_common.h> | ||||
| #include <stdio.h> | ||||
| #include <max7219/max7219.h> | ||||
| #include <FreeRTOS.h> | ||||
| #include <task.h> | ||||
| #include <stdio.h> | ||||
| #include <esp/hwrand.h> | ||||
| 
 | ||||
| #define CS_PIN 5 | ||||
| #define DELAY 2000 | ||||
| 
 | ||||
| static max7219_display_t disp = { | ||||
|     .cs_pin       = CS_PIN, | ||||
|     .digits       = 8, | ||||
|     .cascade_size = 1, | ||||
|     .mirrored     = true | ||||
| }; | ||||
| 
 | ||||
| void user_init(void) | ||||
| { | ||||
|     uart_set_baud(0, 115200); | ||||
|     printf("SDK version:%s\n", sdk_system_get_sdk_version()); | ||||
| 
 | ||||
|     max7219_init(&disp); | ||||
|     //max7219_set_decode_mode(&disp, true);
 | ||||
| 
 | ||||
|     char buf[9]; | ||||
|     while (true) | ||||
|     { | ||||
|         max7219_clear(&disp); | ||||
|         max7219_draw_text(&disp, 0, "7219LEDS"); | ||||
|         vTaskDelay(DELAY / portTICK_PERIOD_MS); | ||||
| 
 | ||||
|         max7219_clear(&disp); | ||||
|         sprintf(buf, "%2.4f A", 34.6782); | ||||
|         max7219_draw_text(&disp, 0, buf); | ||||
|         vTaskDelay(DELAY / portTICK_PERIOD_MS); | ||||
| 
 | ||||
|         max7219_clear(&disp); | ||||
|         sprintf(buf, "%08x", hwrand()); | ||||
|         max7219_draw_text(&disp, 0, buf); | ||||
|         vTaskDelay(DELAY / portTICK_PERIOD_MS); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										7
									
								
								extras/max7219/component.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								extras/max7219/component.mk
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| # include it as 'max7219/max7219.h'
 | ||||
| INC_DIRS += $(max7219_ROOT).. | ||||
| 
 | ||||
| # args for passing into compile rule generation
 | ||||
| max7219_SRC_DIR = $(max7219_ROOT) | ||||
| 
 | ||||
| $(eval $(call component_compile_rules,max7219)) | ||||
							
								
								
									
										189
									
								
								extras/max7219/max7219.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								extras/max7219/max7219.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,189 @@ | |||
| /*
 | ||||
|  * Driver for MAX7219/MAX7221 | ||||
|  * Serially Interfaced, 8-Digit LED Display Drivers | ||||
|  * | ||||
|  * Part of esp-open-rtos | ||||
|  * Copyright (C) 2017 Ruslan V. Uss <unclerus@gmail.com> | ||||
|  * BSD Licensed as described in the file LICENSE | ||||
|  */ | ||||
| #include "max7219.h" | ||||
| #include <esp/spi.h> | ||||
| #include <esp/gpio.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| #include "max7219_priv.h" | ||||
| 
 | ||||
| #define SPI_BUS 1 | ||||
| 
 | ||||
| //#define MAX7219_DEBUG
 | ||||
| 
 | ||||
| #ifdef MAX7219_DEBUG | ||||
| #include <stdio.h> | ||||
| #define debug(fmt, ...) printf("%s: " fmt "\n", "MAX7219", ## __VA_ARGS__) | ||||
| #else | ||||
| #define debug(fmt, ...) | ||||
| #endif | ||||
| 
 | ||||
| #define ALL_CHIPS 0xff | ||||
| #define ALL_DIGITS 8 | ||||
| 
 | ||||
| #define REG_DIGIT_0      (1 << 8) | ||||
| #define REG_DECODE_MODE  (9 << 8) | ||||
| #define REG_INTENSITY    (10 << 8) | ||||
| #define REG_SCAN_LIMIT   (11 << 8) | ||||
| #define REG_SHUTDOWN     (12 << 8) | ||||
| #define REG_DISPLAY_TEST (15 << 8) | ||||
| 
 | ||||
| #define VAL_CLEAR_BCD    0x0f | ||||
| #define VAL_CLEAR_NORMAL 0x00 | ||||
| 
 | ||||
| static const spi_settings_t bus_settings = { | ||||
|     .mode         = SPI_MODE0, | ||||
|     .freq_divider = SPI_FREQ_DIV_10M, | ||||
|     .msb          = true, | ||||
|     .minimal_pins = true, | ||||
|     .endianness   = SPI_BIG_ENDIAN | ||||
| }; | ||||
| 
 | ||||
| static void send(const max7219_display_t *disp, uint8_t chip, uint16_t value) | ||||
| { | ||||
|     uint16_t buf[MAX7219_MAX_CASCADE_SIZE] = { 0 }; | ||||
|     if (chip == ALL_CHIPS) | ||||
|     { | ||||
|         for (uint8_t i = 0; i < disp->cascade_size; i++) | ||||
|             buf[i] = value; | ||||
|     } | ||||
|     else buf[chip] = value; | ||||
| 
 | ||||
|     spi_settings_t old_settings; | ||||
|     spi_get_settings(SPI_BUS, &old_settings); | ||||
|     spi_set_settings(SPI_BUS, &bus_settings); | ||||
|     gpio_write(disp->cs_pin, false); | ||||
| 
 | ||||
|     spi_transfer(SPI_BUS, buf, NULL, disp->cascade_size, SPI_16BIT); | ||||
| 
 | ||||
|     gpio_write(disp->cs_pin, true); | ||||
|     spi_set_settings(SPI_BUS, &old_settings); | ||||
| } | ||||
| 
 | ||||
| bool max7219_init(max7219_display_t *disp) | ||||
| { | ||||
|     if (!disp->cascade_size || disp->cascade_size > MAX7219_MAX_CASCADE_SIZE) | ||||
|     { | ||||
|         debug("Invalid cascade size %d", disp->cascade_size); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     uint8_t max_digits = disp->cascade_size * ALL_DIGITS; | ||||
|     if (!disp->digits || disp->digits > max_digits) | ||||
|     { | ||||
|         debug("Invalid digits count %d, max %d", disp->cascade_size, max_digits); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     gpio_enable(disp->cs_pin, GPIO_OUTPUT); | ||||
|     gpio_write(disp->cs_pin, true); | ||||
| 
 | ||||
|     // Shutdown all chips
 | ||||
|     max7219_set_shutdown_mode(disp, true); | ||||
|     // Disable test
 | ||||
|     send(disp, ALL_CHIPS, REG_DISPLAY_TEST); | ||||
|     // Set max scan limit
 | ||||
|     send(disp, ALL_CHIPS, REG_SCAN_LIMIT | (ALL_DIGITS - 1)); | ||||
|     // Set normal decode mode & clear display
 | ||||
|     max7219_set_decode_mode(disp, false); | ||||
|     // Set minimal brightness
 | ||||
|     max7219_set_brightness(disp, 0); | ||||
|     // Wake up
 | ||||
|     max7219_set_shutdown_mode(disp, false); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void max7219_set_decode_mode(max7219_display_t *disp, bool bcd) | ||||
| { | ||||
|     disp->bcd = bcd; | ||||
|     send(disp, ALL_CHIPS, REG_DECODE_MODE | (bcd ? 0xff : 0)); | ||||
|     max7219_clear(disp); | ||||
| } | ||||
| 
 | ||||
| void max7219_set_brightness(const max7219_display_t *disp, uint8_t value) | ||||
| { | ||||
|     send(disp, ALL_CHIPS, REG_INTENSITY | (value > MAX7219_MAX_BRIGHTNESS ? MAX7219_MAX_BRIGHTNESS : value)); | ||||
| } | ||||
| 
 | ||||
| void max7219_set_shutdown_mode(const max7219_display_t *disp, bool shutdown) | ||||
| { | ||||
|     send(disp, ALL_CHIPS, REG_SHUTDOWN | !shutdown); | ||||
| } | ||||
| 
 | ||||
| bool max7219_set_digit(const max7219_display_t *disp, uint8_t digit, uint8_t val) | ||||
| { | ||||
|     if (digit >= disp->digits) | ||||
|     { | ||||
|         debug("Invalid digit: %d", digit); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     if (disp->mirrored) | ||||
|         digit = disp->digits - digit - 1; | ||||
| 
 | ||||
|     uint8_t c = digit / ALL_DIGITS; | ||||
|     uint8_t d = digit % ALL_DIGITS; | ||||
| 
 | ||||
|     send(disp, c, (REG_DIGIT_0 + ((uint16_t)d << 8)) | val); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void max7219_clear(const max7219_display_t *disp) | ||||
| { | ||||
|     uint8_t val = disp->bcd ? VAL_CLEAR_BCD : VAL_CLEAR_NORMAL; | ||||
|     for (uint8_t i = 0; i < ALL_DIGITS; i++) | ||||
|         send(disp, ALL_CHIPS, (REG_DIGIT_0 + ((uint16_t)i << 8)) | val); | ||||
| } | ||||
| 
 | ||||
| inline static uint8_t get_char(const max7219_display_t *disp, char c) | ||||
| { | ||||
|     if (disp->bcd) | ||||
|     { | ||||
|         if (c >= '0' && c <= '9') | ||||
|             return c - '0'; | ||||
|         switch (c) | ||||
|         { | ||||
|             case '-': | ||||
|                 return 0x0a; | ||||
|             case 'E': | ||||
|             case 'e': | ||||
|                 return 0x0b; | ||||
|             case 'H': | ||||
|             case 'h': | ||||
|                 return 0x0c; | ||||
|             case 'L': | ||||
|             case 'l': | ||||
|                 return 0x0d; | ||||
|             case 'P': | ||||
|             case 'p': | ||||
|                 return 0x0e; | ||||
|         } | ||||
|         return VAL_CLEAR_BCD; | ||||
|     } | ||||
| 
 | ||||
|     return font_7seg[(c - 0x20) & 0x7f]; | ||||
| } | ||||
| 
 | ||||
| void max7219_draw_text(const max7219_display_t *disp, uint8_t pos, const char *s) | ||||
| { | ||||
|     while (s && pos < disp->digits) | ||||
|     { | ||||
|         uint8_t c = get_char(disp, *s); | ||||
|         if (*(s + 1) == '.') | ||||
|         { | ||||
|             c |= 0x80; | ||||
|             s++; | ||||
|         } | ||||
|         max7219_set_digit(disp, pos, c); | ||||
|         pos++; | ||||
|         s++; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										96
									
								
								extras/max7219/max7219.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								extras/max7219/max7219.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,96 @@ | |||
| /*
 | ||||
|  * Driver for MAX7219/MAX7221 | ||||
|  * Serially Interfaced, 8-Digit LED Display Drivers | ||||
|  * | ||||
|  * Part of esp-open-rtos | ||||
|  * Copyright (C) 2017 Ruslan V. Uss <unclerus@gmail.com> | ||||
|  * BSD Licensed as described in the file LICENSE | ||||
|  */ | ||||
| #ifndef EXTRAS_MAX7219_H_ | ||||
| #define EXTRAS_MAX7219_H_ | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" | ||||
| { | ||||
| #endif | ||||
| 
 | ||||
| #define MAX7219_MAX_CASCADE_SIZE 8 | ||||
| #define MAX7219_MAX_BRIGHTNESS   31 | ||||
| 
 | ||||
| /**
 | ||||
|  * Display descriptor | ||||
|  */ | ||||
| typedef struct | ||||
| { | ||||
|     uint8_t cs_pin;              //!< GPIO connected to CS/LOAD pin
 | ||||
| 
 | ||||
|     uint8_t digits;              //!< Accessible digits in 7seg. Up to cascade_size * 8
 | ||||
| 
 | ||||
|     uint8_t cascade_size;        //!< Up to 8 MAX721xx cascaded
 | ||||
|     bool mirrored;               //!< true for horizontally mirrored displays
 | ||||
| 
 | ||||
|     bool bcd; | ||||
| } max7219_display_t; | ||||
| 
 | ||||
| /**
 | ||||
|  * Initialize display: switch it to normal operation from shutdown mode, | ||||
|  * set scan limit to the max and clear | ||||
|  * @param disp Pointer to display descriptor | ||||
|  * @return false if error occured | ||||
|  */ | ||||
| bool max7219_init(max7219_display_t *disp); | ||||
| 
 | ||||
| /**
 | ||||
|  * Set decode mode and clear display | ||||
|  * @param disp Pointer to display descriptor | ||||
|  * @param bcd true to set BCD decode mode, false to normal | ||||
|  */ | ||||
| void max7219_set_decode_mode(max7219_display_t *disp, bool bcd); | ||||
| 
 | ||||
| /**
 | ||||
|  * Set display brightness | ||||
|  * @param disp Pointer to display descriptor | ||||
|  * @param value Brightness value, 0..MAX7219_MAX_BRIGHTNESS | ||||
|  */ | ||||
| void max7219_set_brightness(const max7219_display_t *disp, uint8_t value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Shutdown display or set it to normal mode | ||||
|  * @param disp Pointer to display descriptor | ||||
|  * @param shutdown Shutdown display if true | ||||
|  */ | ||||
| void max7219_set_shutdown_mode(const max7219_display_t *disp, bool shutdown); | ||||
| 
 | ||||
| /**
 | ||||
|  * Write data to display digit | ||||
|  * @param disp Pointer to display descriptor | ||||
|  * @param digit Digit index, 0..disp->digits - 1 | ||||
|  * @param val Data | ||||
|  * @return false if error occured | ||||
|  */ | ||||
| bool max7219_set_digit(const max7219_display_t *disp, uint8_t digit, uint8_t val); | ||||
| 
 | ||||
| /**
 | ||||
|  * Clear display | ||||
|  * @param disp Pointer to display descriptor | ||||
|  */ | ||||
| void max7219_clear(const max7219_display_t *disp); | ||||
| 
 | ||||
| /**
 | ||||
|  * Draw text. | ||||
|  * Currently only 7-segment displays supported | ||||
|  * @param disp Pointer to display descriptor | ||||
|  * @param pos Start digit | ||||
|  * @param s Text | ||||
|  */ | ||||
| void max7219_draw_text(const max7219_display_t *disp, uint8_t pos, const char *s); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif /* EXTRAS_MAX7219_H_ */ | ||||
							
								
								
									
										36
									
								
								extras/max7219/max7219_priv.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								extras/max7219/max7219_priv.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| /*
 | ||||
|  * Driver for MAX7219/MAX7221 | ||||
|  * Serially Interfaced, 8-Digit LED Display Drivers | ||||
|  * | ||||
|  * Part of esp-open-rtos | ||||
|  * Copyright (C) 2017 Ruslan V. Uss <unclerus@gmail.com> | ||||
|  * BSD Licensed as described in the file LICENSE | ||||
|  */ | ||||
| #ifndef EXTRAS_MAX7219_PRIV_H_ | ||||
| #define EXTRAS_MAX7219_PRIV_H_ | ||||
| 
 | ||||
| static const uint8_t font_7seg[] = { | ||||
|     /*  ' '   !     "     #     $     %     &     '     (     )     */ | ||||
|         0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x02, 0x4e, 0x78, | ||||
|     /*  *     +     ,     -     .     /     0     1     2     3     */ | ||||
|         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x30, 0x6d, 0x79, | ||||
|     /*  4     5     6     7     8     9     :     ;     <     =     */ | ||||
|         0x33, 0x5b, 0x5f, 0x70, 0x7f, 0x7b, 0x00, 0x00, 0x0d, 0x09, | ||||
|     /*  >     ?     @     A     B     C     D     E     F     G     */ | ||||
|         0x19, 0x65, 0x00, 0x77, 0x1f, 0x4e, 0x3d, 0x4f, 0x47, 0x5e, | ||||
|     /*  H     I     J     K     L     M     N     O     P     Q     */ | ||||
|         0x37, 0x06, 0x38, 0x57, 0x0e, 0x76, 0x15, 0x1d, 0x67, 0x73, | ||||
|     /*  R     S     T     U     V     W     X     Y     Z     [     */ | ||||
|         0x05, 0x5b, 0x0f, 0x1c, 0x3e, 0x2a, 0x49, 0x3b, 0x6d, 0x4e, | ||||
|     /*  \     ]     ^     _     `     a     b     c     d     e     */ | ||||
|         0x00, 0x78, 0x00, 0x08, 0x02, 0x77, 0x1f, 0x4e, 0x3d, 0x4f, | ||||
|     /*  f     g     h     i     j     k     l     m     n     o     */ | ||||
|         0x47, 0x5e, 0x37, 0x06, 0x38, 0x57, 0x0e, 0x76, 0x15, 0x1d, | ||||
|     /*  p     q     r     s     t     u     v     w     x     y     */ | ||||
|         0x67, 0x73, 0x05, 0x5b, 0x0f, 0x1c, 0x3e, 0x2a, 0x49, 0x3b, | ||||
|     /*  z     {     |     }     ~     */ | ||||
|         0x6d, 0x4e, 0x06, 0x78, 0x00 | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| #endif /* EXTRAS_MAX7219_PRIV_H_ */ | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue