initial release
Components/Display/Display.h
- Committer:
- mapellil
- Date:
- 2017-12-18
- Revision:
- 21:99c367e8a402
- Parent:
- 17:f8187a3fa36e
File content as of revision 21:99c367e8a402:
/** ****************************************************************************** * @file Display.h * @author AST / EST * @version V0.0.1 * @date 14-April-2015 * @brief Header file for display ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ #ifndef __DISPLAY_H #define __DISPLAY_H /* Includes ------------------------------------------------------------------*/ #include "mbed.h" #include "Stmpe1600.h" #include "DevI2C.h" #ifdef __cplusplus extern "C" { #endif /** * GPIO monitor pin state register * 16 bit register LSB at lowest offset (little endian) */ #define GPMR 0x10 /** * STMPE1600 GPIO set pin state register * 16 bit register LSB at lowest offset (little endian) */ #define GPSR 0x12 /** * STMPE1600 GPIO set pin direction register * 16 bit register LSB at lowest offset */ #define GPDR 0x14 /** * cache the full set of expanded GPIO values to avoid i2c reading */ static union CurIOVal_u { uint8_t bytes[4]; /*!< 4 bytes array i/o view */ uint32_t u32; /*!< single dword i/o view */ } /** cache the extended IO values */ cur_io_val; /** * lookup table for digit to bit position */ static int display_bit_posn[4] = {0, 7, 16, 16 + 7}; /** * @defgroup XNUCLEO53L0A1_7Segment 7 segment display * * macro use for human readable segment building * @code * --s0-- * s s * 5 1 * --s6-- * s s * 4 2 * --s3-- . s7 (dp) * @endcode * * @{ */ /** decimal point bit mapping* */ #define DP (1 << 7) /** sgement s0 bit mapping*/ #define S0 (1 << 3) /** sgement s1 bit mapping*/ #define S1 (1 << 5) /** sgement s2 bit mapping*/ #define S2 (1 << 6) /** sgement s3 bit mapping*/ #define S3 (1 << 4) /** sgement s4 bit mapping*/ #define S4 (1 << 0) /** sgement s5 bit mapping*/ #define S5 (1 << 1) /** sgement s6 bit mapping*/ #define S6 (1 << 2) /** * build a character by defining the non lighted segment (not one and no DP) * * @param ... literal sum and or combine of any macro to define any segment #S0 .. #S6 * * example '9' is all segment on but S4 * @code * ['9']= NOT_7_NO_DP(S4), * @endcode */ #define NOT_7_NO_DP( ... ) (uint8_t) ~( __VA_ARGS__ + DP ) /** * Ascii to 7 segment lookup table * * Most common character are supported and follow http://www.twyman.org.uk/Fonts/ * few extra special \@ ^~ ... etc are present for specific demo purpose */ #ifndef __cpluplus /* refer to http://www.twyman.org.uk/Fonts/ */ static const uint8_t ascii_to_display_lut[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, [32] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, [42] = NOT_7_NO_DP(), 0, 0, [45] = S6, 0, 0, [48] = NOT_7_NO_DP(S6), [49] = S1 + S2, [50] = S0 + S1 + S6 + S4 + S3, [51] = NOT_7_NO_DP(S4 + S5), [52] = S5 + S1 + S6 + S2, [53] = NOT_7_NO_DP(S1 + S4), [54] = NOT_7_NO_DP(S1), [55] = S0 + S1 + S2, [56] = NOT_7_NO_DP(0), [57] = NOT_7_NO_DP(S4), 0, 0, 0, [61] = S3 + S6, 0, [63] = NOT_7_NO_DP(S5 + S3 + S2), [64] = S0 + S3, [65] = NOT_7_NO_DP(S3), [66] = NOT_7_NO_DP(S0 + S1), /* as b */ [67] = S0 + S3 + S4 + S5, // same as [ [68] = S0 + S3 + S4 + S5, // same as [ DUMMY [69] = NOT_7_NO_DP(S1 + S2), [70] = S6 + S5 + S4 + S0, [71] = NOT_7_NO_DP(S4), /* same as 9 */ [72] = NOT_7_NO_DP(S0 + S3), [73] = S1 + S2, [74] = S1 + S2 + S3 + S4, [75] = NOT_7_NO_DP(S0 + S3), /* same as H */ [76] = S3 + S4 + S5, [77] = S0 + S4 + S2, /* same as m*/ [78] = S2 + S4 + S6, /* same as n*/ [79] = NOT_7_NO_DP(S6), [80] = S0 + S1 + S2 + S5 + S6, // sames as 'q' [81] = NOT_7_NO_DP(S3 + S2), [82] = S4 + S6, [83] = NOT_7_NO_DP(S1 + S4), /* sasme as 5 */ [84] = NOT_7_NO_DP(S0 + S1 + S2), /* sasme as t */ [85] = NOT_7_NO_DP(S6 + S0), [86] = S4 + S3 + S2, // is u but u use U [87] = S1 + S3 + S5, [88] = NOT_7_NO_DP(S0 + S3), // similar to H [89] = NOT_7_NO_DP(S0 + S4), [90] = S0 + S1 + S6 + S4 + S3, // same as 2 [91] = S0 + S3 + S4 + S5, 0, [93] = S0 + S3 + S2 + S1, [94] = S0, /* use as top bar */ [95] = S3, 0, [97] = S2 + S3 + S4 + S6, [98] = NOT_7_NO_DP(S0 + S1), [99] = S6 + S4 + S3, [100] = NOT_7_NO_DP(S0 + S5), [101] = NOT_7_NO_DP(S2), [102] = S6 + S5 + S4 + S0, /* same as F */ [103] = NOT_7_NO_DP(S4), /* same as 9 */ [104] = S6 + S5 + S4 + S2, [105] = S4, [106] = S1 + S2 + S3 + S4, [107] = S6 + S5 + S4 + S2, /* a h */ [108] = S3 + S4, [109] = S0 + S4 + S2, /* same as */ [110] = S2 + S4 + S6, [111] = S6 + S4 + S3 + S2, [112] = NOT_7_NO_DP(S3 + S2), // same as P [113] = S0 + S1 + S2 + S5 + S6, [114] = S4 + S6, [115] = NOT_7_NO_DP(S1 + S4), [116] = NOT_7_NO_DP(S0 + S1 + S2), [117] = S4 + S3 + S2 + S5 + S1, // U [118] = S4 + S3 + S2, // is u but u use U [119] = S1 + S3 + S5, [120] = NOT_7_NO_DP(S0 + S3), // similar to H [121] = NOT_7_NO_DP(S0 + S4), [122] = S0 + S1 + S6 + S4 + S3, // same as 2 0, 0, 0, [126] = S0 + S3 + S6 /* 3 h bar */ }; #else /* refer to http://www.twyman.org.uk/Fonts/ */ static const uint8_t ascii_to_display_lut[256] = { [' '] = 0, ['-'] = S6, ['_'] = S3, ['='] = S3 + S6, ['~'] = S0 + S3 + S6, /* 3 h bar */ ['^'] = S0, /* use as top bar */ ['?'] = NOT_7_NO_DP(S5 + S3 + S2), ['*'] = NOT_7_NO_DP(), ['['] = S0 + S3 + S4 + S5, [']'] = S0 + S3 + S2 + S1, ['@'] = S0 + S3, ['0'] = NOT_7_NO_DP(S6), ['1'] = S1 + S2, ['2'] = S0 + S1 + S6 + S4 + S3, ['3'] = NOT_7_NO_DP(S4 + S5), ['4'] = S5 + S1 + S6 + S2, ['5'] = NOT_7_NO_DP(S1 + S4), ['6'] = NOT_7_NO_DP(S1), ['7'] = S0 + S1 + S2, ['8'] = NOT_7_NO_DP(0), ['9'] = NOT_7_NO_DP(S4), ['a'] = S2 + S3 + S4 + S6, ['b'] = NOT_7_NO_DP(S0 + S1), ['c'] = S6 + S4 + S3, ['d'] = NOT_7_NO_DP(S0 + S5), ['e'] = NOT_7_NO_DP(S2), ['f'] = S6 + S5 + S4 + S0, /* same as F */ ['g'] = NOT_7_NO_DP(S4), /* same as 9 */ ['h'] = S6 + S5 + S4 + S2, ['i'] = S4, ['j'] = S1 + S2 + S3 + S4, ['k'] = S6 + S5 + S4 + S2, /* a h */ ['l'] = S3 + S4, ['m'] = S0 + S4 + S2, /* same as */ ['n'] = S2 + S4 + S6, ['o'] = S6 + S4 + S3 + S2, ['p'] = NOT_7_NO_DP(S3 + S2), // same as P ['q'] = S0 + S1 + S2 + S5 + S6, ['r'] = S4 + S6, ['s'] = NOT_7_NO_DP(S1 + S4), ['t'] = NOT_7_NO_DP(S0 + S1 + S2), ['u'] = S4 + S3 + S2 + S5 + S1, // U ['v'] = S4 + S3 + S2, // is u but u use U ['w'] = S1 + S3 + S5, ['x'] = NOT_7_NO_DP(S0 + S3), // similar to H ['y'] = NOT_7_NO_DP(S0 + S4), ['z'] = S0 + S1 + S6 + S4 + S3, // same as 2 ['A'] = NOT_7_NO_DP(S3), ['B'] = NOT_7_NO_DP(S0 + S1), /* as b */ ['C'] = S0 + S3 + S4 + S5, // same as [ ['E'] = NOT_7_NO_DP(S1 + S2), ['F'] = S6 + S5 + S4 + S0, ['G'] = NOT_7_NO_DP(S4), /* same as 9 */ ['H'] = NOT_7_NO_DP(S0 + S3), ['I'] = S1 + S2, ['J'] = S1 + S2 + S3 + S4, ['K'] = NOT_7_NO_DP(S0 + S3), /* same as H */ ['L'] = S3 + S4 + S5, ['M'] = S0 + S4 + S2, /* same as m*/ ['N'] = S2 + S4 + S6, /* same as n*/ ['O'] = NOT_7_NO_DP(S6), ['P'] = S0 + S1 + S2 + S5 + S6, // sames as 'q' ['Q'] = NOT_7_NO_DP(S3 + S2), ['R'] = S4 + S6, ['S'] = NOT_7_NO_DP(S1 + S4), /* sasme as 5 */ ['T'] = NOT_7_NO_DP(S0 + S1 + S2), /* sasme as t */ ['U'] = NOT_7_NO_DP(S6 + S0), ['V'] = S4 + S3 + S2, // is u but u use U ['W'] = S1 + S3 + S5, ['X'] = NOT_7_NO_DP(S0 + S3), // similar to H ['Y'] = NOT_7_NO_DP(S0 + S4), ['Z'] = S0 + S1 + S6 + S4 + S3 // same as 2 }; #endif #undef S0 #undef S1 #undef S2 #undef S3 #undef S4 #undef S5 #undef S6 #undef DP /** @} */ //#define DISPLAY_DELAY 1 // in mSec /* Classes -------------------------------------------------------------------*/ /** Class representing Display */ class Display { private: Stmpe1600 *stmpe1600_exp0; Stmpe1600 *stmpe1600_exp1; public: /** Constructor * @param[in] &stmpe_1600 device handler to be used for display control */ //<<<<<<< local Display(Stmpe1600 *stmpe_1600_exp0, Stmpe1600 *stmpe_1600_exp1) : stmpe1600_exp0(stmpe_1600_exp0), stmpe1600_exp1(stmpe_1600_exp1) //======= // Display(Stmpe1600 &stmpe_1600_exp0, Stmpe1600 &stmpe_1600_exp1) : stmpe1600_exp0(&stmpe_1600_exp0), // stmpe1600_exp1(&stmpe_1600_exp1) //>>>>>>> other { uint16_t expander_data; // detect the extenders stmpe1600_exp0->read_16bit_reg(0x00, &expander_data); // if (ExpanderData != 0x1600) {/* log - failed to find expander exp0 */ } stmpe1600_exp1->read_16bit_reg(0x00, &expander_data); // if (ExpanderData != 0x1600) {/* log - failed to find expander exp1 */ } // configure all necessary GPIO pins as outputs expander_data = 0xFFFF; stmpe1600_exp0->write_16bit_reg(GPDR, &expander_data); expander_data = 0xBFFF; // leave bit 14 as an input, for the pushbutton, PB1. stmpe1600_exp1->write_16bit_reg(GPDR, &expander_data); // shut down all segment and all device expander_data = 0x7F + (0x7F << 7); stmpe1600_exp0->write_16bit_reg(GPSR, &expander_data); stmpe1600_exp1->write_16bit_reg(GPSR, &expander_data); } /*** Interface Methods ***/ /** * @brief Print the string on display * @param[in] String to be printed * @param[in] String lenght [min 1, max 4] * @return void */ void display_string(const char *str) { uint16_t expander_data; uint32_t segments; int bit_posn; int i; for (i = 0; (i < 4 && str[i] != 0); i++) { segments = (uint32_t) ascii_to_display_lut[(uint8_t) str[i]]; segments = (~segments) & 0x7F; bit_posn = display_bit_posn[i]; cur_io_val.u32 &= ~(0x7F << bit_posn); cur_io_val.u32 |= segments << bit_posn; } /* clear unused digit */ for (; i < 4; i++) { bit_posn = display_bit_posn[i]; cur_io_val.u32 |= 0x7F << bit_posn; } // stmpe1600_exp0.write16bitReg(GPSR, (uint16_t *)&CurIOVal.bytes[0]); // stmpe1600_exp1.write16bitReg(GPSR, (uint16_t *)&CurIOVal.bytes[2]); // ordered low-byte/high-byte! cur_io_val.bytes[1] |= 0xC0; // ensure highest bits are high, as these are xshutdown pins for left & right sensors! expander_data = (cur_io_val.bytes[1] << 8) + cur_io_val.bytes[0]; stmpe1600_exp0->write_16bit_reg(GPSR, &expander_data); cur_io_val.bytes[3] |= 0x80; // ensure highest bit is high, as this is xshutdown pin on central sensor! expander_data = (cur_io_val.bytes[3] << 8) + cur_io_val.bytes[2]; stmpe1600_exp1->write_16bit_reg(GPSR, &expander_data); } void clear_display(void) { uint16_t expander_data; expander_data = 0x7F + (0x7F << 7); stmpe1600_exp0->write_16bit_reg(GPSR, &expander_data); stmpe1600_exp1->write_16bit_reg(GPSR, &expander_data); } }; #ifdef __cplusplus } #endif #endif // __DISPLAY_H