File content as of revision 5:6020b7ced569:
/**
******************************************************************************
* @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