├── BINARY ├── F1-T12+858D_sh1106.hex ├── F1-T12+858D_ssd1305.hex ├── F1-T12+858D_ssd1306.hex ├── F1-T12+858D_ssd1309.hex └── README ├── Drivers └── u8g2 │ ├── Inc │ ├── U8g2lib.h │ ├── U8x8lib.h │ ├── u8g2.h │ └── u8x8.h │ └── Src │ ├── U8x8lib.cpp-disable │ ├── u8g2_bitmap.c │ ├── u8g2_box.c │ ├── u8g2_buffer.c │ ├── u8g2_circle.c │ ├── u8g2_cleardisplay.c │ ├── u8g2_d_memory.c │ ├── u8g2_d_setup.c │ ├── u8g2_font.c │ ├── u8g2_fonts.c │ ├── u8g2_hvline.c │ ├── u8g2_input_value.c │ ├── u8g2_intersection.c │ ├── u8g2_kerning.c │ ├── u8g2_line.c │ ├── u8g2_ll_hvline.c │ ├── u8g2_message.c │ ├── u8g2_polygon.c │ ├── u8g2_selection_list.c │ ├── u8g2_setup.c │ ├── u8log.c │ ├── u8log_u8g2.c │ ├── u8log_u8x8.c │ ├── u8x8_8x8.c │ ├── u8x8_byte.c │ ├── u8x8_cad.c │ ├── u8x8_d_a2printer.c │ ├── u8x8_d_il3820_296x128.c │ ├── u8x8_d_ist3020.c │ ├── u8x8_d_ks0108.c │ ├── u8x8_d_lc7981.c │ ├── u8x8_d_ld7032_60x32.c │ ├── u8x8_d_ls013b7dh03.c │ ├── u8x8_d_max7219.c │ ├── u8x8_d_pcd8544_84x48.c │ ├── u8x8_d_pcf8812.c │ ├── u8x8_d_pcf8814_hx1230.c │ ├── u8x8_d_sbn1661.c │ ├── u8x8_d_sed1330.c │ ├── u8x8_d_sh1106_64x32.c │ ├── u8x8_d_sh1106_72x40.c │ ├── u8x8_d_sh1107.c │ ├── u8x8_d_sh1108.c │ ├── u8x8_d_sh1122.c │ ├── u8x8_d_ssd1305.c │ ├── u8x8_d_ssd1306_128x32.c │ ├── u8x8_d_ssd1306_128x64_noname.c │ ├── u8x8_d_ssd1306_48x64.c │ ├── u8x8_d_ssd1306_64x32.c │ ├── u8x8_d_ssd1306_64x48.c │ ├── u8x8_d_ssd1306_96x16.c │ ├── u8x8_d_ssd1309.c │ ├── u8x8_d_ssd1316.c │ ├── u8x8_d_ssd1317.c │ ├── u8x8_d_ssd1318.c │ ├── u8x8_d_ssd1322.c │ ├── u8x8_d_ssd1325.c │ ├── u8x8_d_ssd1326.c │ ├── u8x8_d_ssd1327.c │ ├── u8x8_d_ssd1329.c │ ├── u8x8_d_ssd1606_172x72.c │ ├── u8x8_d_ssd1607_200x200.c │ ├── u8x8_d_st7511.c │ ├── u8x8_d_st75256.c │ ├── u8x8_d_st75320.c │ ├── u8x8_d_st7565.c │ ├── u8x8_d_st7567.c │ ├── u8x8_d_st7586s_erc240160.c │ ├── u8x8_d_st7586s_s028hn118a.c │ ├── u8x8_d_st7588.c │ ├── u8x8_d_st7920.c │ ├── u8x8_d_stdio.c │ ├── u8x8_d_t6963.c │ ├── u8x8_d_uc1601.c │ ├── u8x8_d_uc1604.c │ ├── u8x8_d_uc1608.c │ ├── u8x8_d_uc1610.c │ ├── u8x8_d_uc1611.c │ ├── u8x8_d_uc1617.c │ ├── u8x8_d_uc1638.c │ ├── u8x8_d_uc1701_dogs102.c │ ├── u8x8_d_uc1701_mini12864.c │ ├── u8x8_debounce.c │ ├── u8x8_display.c │ ├── u8x8_fonts.c │ ├── u8x8_gpio.c │ ├── u8x8_input_value.c │ ├── u8x8_message.c │ ├── u8x8_selection_list.c │ ├── u8x8_setup.c │ ├── u8x8_string.c │ ├── u8x8_u16toa.c │ └── u8x8_u8toa.c ├── F1-T12+858D.ioc ├── Inc ├── buzzer.h ├── cfgtypes.h ├── config.h ├── core.h ├── display.h ├── eeprom.h ├── encoder.h ├── font.h ├── gun.h ├── hw.h ├── iron.h ├── iron_tips.h ├── main.h ├── mode.h ├── myU8g2lib.h ├── oled.h ├── pid.h ├── stat.h ├── stm32f1xx_hal_conf.h ├── stm32f1xx_it.h ├── tools.h ├── unit.h └── vars.h ├── README.md ├── Src ├── buzzer.cpp ├── config.cpp ├── core.cpp ├── display.cpp ├── eeprom.cpp ├── encoder.cpp ├── font.c ├── gun.cpp ├── iron.cpp ├── iron_tips.cpp ├── main.c ├── mode.cpp ├── oled.cpp ├── pid.cpp ├── stat.cpp ├── stm32f1xx_hal_msp.c ├── stm32f1xx_it.c ├── syscalls.c ├── system_stm32f1xx.c ├── tools.cpp ├── unit.cpp └── vars.cpp ├── eagle ├── display_board.brd ├── display_board.sch ├── stm32_T12+858D.sch └── stm32_T12+858D_v4.sch └── Паяльная и ремонтная станция на STM32.pdf /BINARY/README: -------------------------------------------------------------------------------- 1 | Choose the binary version depending on your OLED screen controller 2 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_bitmap.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_bitmap.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | 39 | void u8g2_SetBitmapMode(u8g2_t *u8g2, uint8_t is_transparent) { 40 | u8g2->bitmap_transparency = is_transparent; 41 | } 42 | 43 | /* 44 | x,y Position on the display 45 | len Length of bitmap line in pixel. Note: This differs from u8glib which had a bytecount here. 46 | b Pointer to the bitmap line. 47 | Only draw pixels which are set. 48 | */ 49 | 50 | void u8g2_DrawHorizontalBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b) 51 | { 52 | uint8_t mask; 53 | uint8_t color = u8g2->draw_color; 54 | uint8_t ncolor = (color == 0 ? 1 : 0); 55 | 56 | #ifdef U8G2_WITH_INTERSECTION 57 | if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 ) 58 | return; 59 | #endif /* U8G2_WITH_INTERSECTION */ 60 | 61 | mask = 128; 62 | while(len > 0) 63 | { 64 | if ( *b & mask ) { 65 | u8g2->draw_color = color; 66 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 67 | } else if ( u8g2->bitmap_transparency == 0 ) { 68 | u8g2->draw_color = ncolor; 69 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 70 | } 71 | 72 | x++; 73 | mask >>= 1; 74 | if ( mask == 0 ) 75 | { 76 | mask = 128; 77 | b++; 78 | } 79 | len--; 80 | } 81 | u8g2->draw_color = color; 82 | } 83 | 84 | 85 | /* u8glib compatible bitmap draw function */ 86 | void u8g2_DrawBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t cnt, u8g2_uint_t h, const uint8_t *bitmap) 87 | { 88 | u8g2_uint_t w; 89 | w = cnt; 90 | w *= 8; 91 | #ifdef U8G2_WITH_INTERSECTION 92 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 93 | return; 94 | #endif /* U8G2_WITH_INTERSECTION */ 95 | 96 | while( h > 0 ) 97 | { 98 | u8g2_DrawHorizontalBitmap(u8g2, x, y, w, bitmap); 99 | bitmap += cnt; 100 | y++; 101 | h--; 102 | } 103 | } 104 | 105 | 106 | 107 | void u8g2_DrawHXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b) 108 | { 109 | uint8_t mask; 110 | uint8_t color = u8g2->draw_color; 111 | uint8_t ncolor = (color == 0 ? 1 : 0); 112 | #ifdef U8G2_WITH_INTERSECTION 113 | if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 ) 114 | return; 115 | #endif /* U8G2_WITH_INTERSECTION */ 116 | 117 | mask = 1; 118 | while(len > 0) { 119 | if ( *b & mask ) { 120 | u8g2->draw_color = color; 121 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 122 | } else if ( u8g2->bitmap_transparency == 0 ) { 123 | u8g2->draw_color = ncolor; 124 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 125 | } 126 | x++; 127 | mask <<= 1; 128 | if ( mask == 0 ) 129 | { 130 | mask = 1; 131 | b++; 132 | } 133 | len--; 134 | } 135 | u8g2->draw_color = color; 136 | } 137 | 138 | 139 | void u8g2_DrawXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap) 140 | { 141 | u8g2_uint_t blen; 142 | blen = w; 143 | blen += 7; 144 | blen >>= 3; 145 | #ifdef U8G2_WITH_INTERSECTION 146 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 147 | return; 148 | #endif /* U8G2_WITH_INTERSECTION */ 149 | 150 | while( h > 0 ) 151 | { 152 | u8g2_DrawHXBM(u8g2, x, y, w, bitmap); 153 | bitmap += blen; 154 | y++; 155 | h--; 156 | } 157 | } 158 | 159 | 160 | 161 | 162 | 163 | 164 | void u8g2_DrawHXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b) 165 | { 166 | uint8_t mask; 167 | uint8_t color = u8g2->draw_color; 168 | uint8_t ncolor = (color == 0 ? 1 : 0); 169 | #ifdef U8G2_WITH_INTERSECTION 170 | if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 ) 171 | return; 172 | #endif /* U8G2_WITH_INTERSECTION */ 173 | 174 | mask = 1; 175 | while(len > 0) 176 | { 177 | if( u8x8_pgm_read(b) & mask ) { 178 | u8g2->draw_color = color; 179 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 180 | } else if( u8g2->bitmap_transparency == 0 ) { 181 | u8g2->draw_color = ncolor; 182 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 183 | } 184 | 185 | x++; 186 | mask <<= 1; 187 | if ( mask == 0 ) 188 | { 189 | mask = 1; 190 | b++; 191 | } 192 | len--; 193 | } 194 | u8g2->draw_color = color; 195 | } 196 | 197 | 198 | void u8g2_DrawXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap) 199 | { 200 | u8g2_uint_t blen; 201 | blen = w; 202 | blen += 7; 203 | blen >>= 3; 204 | #ifdef U8G2_WITH_INTERSECTION 205 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 206 | return; 207 | #endif /* U8G2_WITH_INTERSECTION */ 208 | 209 | while( h > 0 ) 210 | { 211 | u8g2_DrawHXBMP(u8g2, x, y, w, bitmap); 212 | bitmap += blen; 213 | y++; 214 | h--; 215 | } 216 | } 217 | 218 | 219 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_box.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_box.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | /* 39 | draw a filled box 40 | restriction: does not work for w = 0 or h = 0 41 | */ 42 | void u8g2_DrawBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) 43 | { 44 | #ifdef U8G2_WITH_INTERSECTION 45 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 46 | return; 47 | #endif /* U8G2_WITH_INTERSECTION */ 48 | while( h != 0 ) 49 | { 50 | u8g2_DrawHVLine(u8g2, x, y, w, 0); 51 | y++; 52 | h--; 53 | } 54 | } 55 | 56 | 57 | /* 58 | draw a frame (empty box) 59 | restriction: does not work for w = 0 or h = 0 60 | ToDo: 61 | pixel in the corners are drawn twice. This could be optimized. 62 | */ 63 | void u8g2_DrawFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) 64 | { 65 | u8g2_uint_t xtmp = x; 66 | 67 | #ifdef U8G2_WITH_INTERSECTION 68 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 69 | return; 70 | #endif /* U8G2_WITH_INTERSECTION */ 71 | 72 | u8g2_DrawHVLine(u8g2, x, y, w, 0); 73 | u8g2_DrawHVLine(u8g2, x, y, h, 1); 74 | x+=w; 75 | x--; 76 | u8g2_DrawHVLine(u8g2, x, y, h, 1); 77 | y+=h; 78 | y--; 79 | u8g2_DrawHVLine(u8g2, xtmp, y, w, 0); 80 | } 81 | 82 | 83 | 84 | 85 | void u8g2_DrawRBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) 86 | { 87 | u8g2_uint_t xl, yu; 88 | u8g2_uint_t yl, xr; 89 | 90 | #ifdef U8G2_WITH_INTERSECTION 91 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 92 | return; 93 | #endif /* U8G2_WITH_INTERSECTION */ 94 | 95 | xl = x; 96 | xl += r; 97 | yu = y; 98 | yu += r; 99 | 100 | xr = x; 101 | xr += w; 102 | xr -= r; 103 | xr -= 1; 104 | 105 | yl = y; 106 | yl += h; 107 | yl -= r; 108 | yl -= 1; 109 | 110 | u8g2_DrawDisc(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT); 111 | u8g2_DrawDisc(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT); 112 | u8g2_DrawDisc(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT); 113 | u8g2_DrawDisc(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT); 114 | 115 | { 116 | u8g2_uint_t ww, hh; 117 | 118 | ww = w; 119 | ww -= r; 120 | ww -= r; 121 | xl++; 122 | yu++; 123 | 124 | if ( ww >= 3 ) 125 | { 126 | ww -= 2; 127 | u8g2_DrawBox(u8g2, xl, y, ww, r+1); 128 | u8g2_DrawBox(u8g2, xl, yl, ww, r+1); 129 | } 130 | 131 | hh = h; 132 | hh -= r; 133 | hh -= r; 134 | //h--; 135 | if ( hh >= 3 ) 136 | { 137 | hh -= 2; 138 | u8g2_DrawBox(u8g2, x, yu, w, hh); 139 | } 140 | } 141 | } 142 | 143 | 144 | void u8g2_DrawRFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) 145 | { 146 | u8g2_uint_t xl, yu; 147 | 148 | #ifdef U8G2_WITH_INTERSECTION 149 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 150 | return; 151 | #endif /* U8G2_WITH_INTERSECTION */ 152 | 153 | xl = x; 154 | xl += r; 155 | yu = y; 156 | yu += r; 157 | 158 | { 159 | u8g2_uint_t yl, xr; 160 | 161 | xr = x; 162 | xr += w; 163 | xr -= r; 164 | xr -= 1; 165 | 166 | yl = y; 167 | yl += h; 168 | yl -= r; 169 | yl -= 1; 170 | 171 | u8g2_DrawCircle(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT); 172 | u8g2_DrawCircle(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT); 173 | u8g2_DrawCircle(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT); 174 | u8g2_DrawCircle(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT); 175 | } 176 | 177 | { 178 | u8g2_uint_t ww, hh; 179 | 180 | ww = w; 181 | ww -= r; 182 | ww -= r; 183 | hh = h; 184 | hh -= r; 185 | hh -= r; 186 | 187 | xl++; 188 | yu++; 189 | 190 | if ( ww >= 3 ) 191 | { 192 | ww -= 2; 193 | h--; 194 | u8g2_DrawHLine(u8g2, xl, y, ww); 195 | u8g2_DrawHLine(u8g2, xl, y+h, ww); 196 | } 197 | 198 | if ( hh >= 3 ) 199 | { 200 | hh -= 2; 201 | w--; 202 | u8g2_DrawVLine(u8g2, x, yu, hh); 203 | u8g2_DrawVLine(u8g2, x+w, yu, hh); 204 | } 205 | } 206 | } 207 | 208 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_buffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_buffer.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | #include 38 | 39 | /*============================================*/ 40 | void u8g2_ClearBuffer(u8g2_t *u8g2) 41 | { 42 | size_t cnt; 43 | cnt = u8g2_GetU8x8(u8g2)->display_info->tile_width; 44 | cnt *= u8g2->tile_buf_height; 45 | cnt *= 8; 46 | memset(u8g2->tile_buf_ptr, 0, cnt); 47 | } 48 | 49 | /*============================================*/ 50 | 51 | static void u8g2_send_tile_row(u8g2_t *u8g2, uint8_t src_tile_row, uint8_t dest_tile_row) 52 | { 53 | uint8_t *ptr; 54 | uint16_t offset; 55 | uint8_t w; 56 | 57 | w = u8g2_GetU8x8(u8g2)->display_info->tile_width; 58 | offset = src_tile_row; 59 | ptr = u8g2->tile_buf_ptr; 60 | offset *= w; 61 | offset *= 8; 62 | ptr += offset; 63 | u8x8_DrawTile(u8g2_GetU8x8(u8g2), 0, dest_tile_row, w, ptr); 64 | } 65 | 66 | /* 67 | write the buffer to the display RAM. 68 | For most displays, this will make the content visible to the user. 69 | Some displays (like the SSD1606) require a u8x8_RefreshDisplay() 70 | */ 71 | static void u8g2_send_buffer(u8g2_t *u8g2) U8X8_NOINLINE; 72 | static void u8g2_send_buffer(u8g2_t *u8g2) 73 | { 74 | uint8_t src_row; 75 | uint8_t src_max; 76 | uint8_t dest_row; 77 | uint8_t dest_max; 78 | 79 | src_row = 0; 80 | src_max = u8g2->tile_buf_height; 81 | dest_row = u8g2->tile_curr_row; 82 | dest_max = u8g2_GetU8x8(u8g2)->display_info->tile_height; 83 | 84 | do 85 | { 86 | u8g2_send_tile_row(u8g2, src_row, dest_row); 87 | src_row++; 88 | dest_row++; 89 | } while( src_row < src_max && dest_row < dest_max ); 90 | } 91 | 92 | /* same as u8g2_send_buffer but also send the DISPLAY_REFRESH message (used by SSD1606) */ 93 | void u8g2_SendBuffer(u8g2_t *u8g2) 94 | { 95 | u8g2_send_buffer(u8g2); 96 | u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) ); 97 | } 98 | 99 | /*============================================*/ 100 | void u8g2_SetBufferCurrTileRow(u8g2_t *u8g2, uint8_t row) 101 | { 102 | u8g2->tile_curr_row = row; 103 | u8g2->cb->update_dimension(u8g2); 104 | u8g2->cb->update_page_win(u8g2); 105 | } 106 | 107 | void u8g2_FirstPage(u8g2_t *u8g2) 108 | { 109 | if ( u8g2->is_auto_page_clear ) 110 | { 111 | u8g2_ClearBuffer(u8g2); 112 | } 113 | u8g2_SetBufferCurrTileRow(u8g2, 0); 114 | } 115 | 116 | uint8_t u8g2_NextPage(u8g2_t *u8g2) 117 | { 118 | uint8_t row; 119 | u8g2_send_buffer(u8g2); 120 | row = u8g2->tile_curr_row; 121 | row += u8g2->tile_buf_height; 122 | if ( row >= u8g2_GetU8x8(u8g2)->display_info->tile_height ) 123 | { 124 | u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) ); 125 | return 0; 126 | } 127 | if ( u8g2->is_auto_page_clear ) 128 | { 129 | u8g2_ClearBuffer(u8g2); 130 | } 131 | u8g2_SetBufferCurrTileRow(u8g2, row); 132 | return 1; 133 | } 134 | 135 | 136 | 137 | /*============================================*/ 138 | /* 139 | Description: 140 | Update a sub area of the display, given by tile position, width and height. 141 | The arguments are "tile" coordinates. Any u8g2 rotation is ignored. 142 | This procedure only checks whether full buffer mode is active. 143 | There is no error checking for the arguments: It is the responsibility of the 144 | user to ensure, that the provided arguments are correct. 145 | 146 | Limitations: 147 | - Only available in full buffer mode (will not do anything in page mode) 148 | - Tile positions and sizes (pixel position divided by 8) 149 | - Any display rotation/mirror is ignored 150 | - Only works with displays, which support U8x8 API 151 | - Will not send the e-paper refresh message (will probably not work with e-paper devices) 152 | */ 153 | void u8g2_UpdateDisplayArea(u8g2_t *u8g2, uint8_t tx, uint8_t ty, uint8_t tw, uint8_t th) 154 | { 155 | uint16_t page_size; 156 | uint8_t *ptr; 157 | 158 | /* check, whether we are in full buffer mode */ 159 | if ( u8g2->tile_buf_height != u8g2_GetU8x8(u8g2)->display_info->tile_height ) 160 | return; /* not in full buffer mode, do nothing */ 161 | 162 | page_size = u8g2->pixel_buf_width; /* 8*u8g2->u8g2_GetU8x8(u8g2)->display_info->tile_width */ 163 | 164 | ptr = u8g2_GetBufferPtr(u8g2); 165 | ptr += tx*8; 166 | ptr += page_size*ty; 167 | 168 | while( th > 0 ) 169 | { 170 | u8x8_DrawTile( u8g2_GetU8x8(u8g2), tx, ty, tw, ptr ); 171 | ptr += page_size; 172 | ty++; 173 | th--; 174 | } 175 | } 176 | 177 | /* same as sendBuffer, but does not send the ePaper refresh message */ 178 | void u8g2_UpdateDisplay(u8g2_t *u8g2) 179 | { 180 | u8g2_send_buffer(u8g2); 181 | } 182 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_cleardisplay.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_cleardisplay.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #include "u8g2.h" 36 | 37 | /* Clear screen buffer & display reliable for all u8g2 displays. */ 38 | /* This is done with u8g2 picture loop, because we can not use the u8x8 function in all cases */ 39 | void u8g2_ClearDisplay(u8g2_t *u8g2) 40 | { 41 | u8g2_FirstPage(u8g2); 42 | do { 43 | } while ( u8g2_NextPage(u8g2) ); 44 | /* 45 | This function is usually called during startup (u8g2.begin()). 46 | However the user might want to use full buffer mode with clear and 47 | send commands. 48 | This will not work because the current tile row is modified by the picture 49 | loop above. To fix this, reset the tile row to 0, issue #370 50 | A workaround would be, that the user sets the current tile row to 0 manually. 51 | */ 52 | u8g2_SetBufferCurrTileRow(u8g2, 0); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_fonts.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Drivers/u8g2/Src/u8g2_fonts.c -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_input_value.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_input_value.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | /* 39 | return: 40 | 0: value is not changed (HOME/Break Button pressed) 41 | 1: value has been updated 42 | */ 43 | 44 | uint8_t u8g2_UserInterfaceInputValue(u8g2_t *u8g2, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post) 45 | { 46 | uint8_t line_height; 47 | uint8_t height; 48 | u8g2_uint_t pixel_height; 49 | u8g2_uint_t y, yy; 50 | u8g2_uint_t pixel_width; 51 | u8g2_uint_t x, xx; 52 | 53 | uint8_t local_value = *value; 54 | //uint8_t r; /* not used ??? */ 55 | uint8_t event; 56 | 57 | /* only horizontal strings are supported, so force this here */ 58 | u8g2_SetFontDirection(u8g2, 0); 59 | 60 | /* force baseline position */ 61 | u8g2_SetFontPosBaseline(u8g2); 62 | 63 | /* calculate line height */ 64 | line_height = u8g2_GetAscent(u8g2); 65 | line_height -= u8g2_GetDescent(u8g2); 66 | 67 | 68 | /* calculate overall height of the input value box */ 69 | height = 1; /* value input line */ 70 | height += u8x8_GetStringLineCnt(title); 71 | 72 | /* calculate the height in pixel */ 73 | pixel_height = height; 74 | pixel_height *= line_height; 75 | 76 | 77 | /* calculate offset from top */ 78 | y = 0; 79 | if ( pixel_height < u8g2_GetDisplayHeight(u8g2) ) 80 | { 81 | y = u8g2_GetDisplayHeight(u8g2); 82 | y -= pixel_height; 83 | y /= 2; 84 | } 85 | 86 | /* calculate offset from left for the label */ 87 | x = 0; 88 | pixel_width = u8g2_GetUTF8Width(u8g2, pre); 89 | pixel_width += u8g2_GetUTF8Width(u8g2, "0") * digits; 90 | pixel_width += u8g2_GetUTF8Width(u8g2, post); 91 | if ( pixel_width < u8g2_GetDisplayWidth(u8g2) ) 92 | { 93 | x = u8g2_GetDisplayWidth(u8g2); 94 | x -= pixel_width; 95 | x /= 2; 96 | } 97 | 98 | /* event loop */ 99 | for(;;) 100 | { 101 | u8g2_FirstPage(u8g2); 102 | do 103 | { 104 | /* render */ 105 | yy = y; 106 | yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title); 107 | xx = x; 108 | xx += u8g2_DrawUTF8(u8g2, xx, yy, pre); 109 | xx += u8g2_DrawUTF8(u8g2, xx, yy, u8x8_u8toa(local_value, digits)); 110 | u8g2_DrawUTF8(u8g2, xx, yy, post); 111 | } while( u8g2_NextPage(u8g2) ); 112 | 113 | #ifdef U8G2_REF_MAN_PIC 114 | return 0; 115 | #endif 116 | 117 | for(;;) 118 | { 119 | event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2)); 120 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 121 | { 122 | *value = local_value; 123 | return 1; 124 | } 125 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 126 | { 127 | return 0; 128 | } 129 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP ) 130 | { 131 | if ( local_value >= hi ) 132 | local_value = lo; 133 | else 134 | local_value++; 135 | break; 136 | } 137 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN ) 138 | { 139 | if ( local_value <= lo ) 140 | local_value = hi; 141 | else 142 | local_value--; 143 | break; 144 | } 145 | } 146 | } 147 | 148 | /* never reached */ 149 | //return r; 150 | } 151 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_intersection.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_intersection.c 4 | 5 | Intersection calculation, code taken from u8g_clip.c 6 | 7 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 8 | 9 | Copyright (c) 2016, olikraus@gmail.com 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, this list 16 | of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright notice, this 19 | list of conditions and the following disclaimer in the documentation and/or other 20 | materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 24 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #include "u8g2.h" 39 | 40 | #ifdef __GNUC__ 41 | #define U8G2_ALWAYS_INLINE __inline__ __attribute__((always_inline)) 42 | #else 43 | #define U8G2_ALWAYS_INLINE 44 | #endif 45 | 46 | 47 | #if defined(U8G2_WITH_INTERSECTION) || defined(U8G2_WITH_CLIP_WINDOW_SUPPORT) 48 | 49 | #ifdef OLD_VERSION_WITH_SYMETRIC_BOUNDARIES 50 | 51 | /* 52 | intersection assumptions: 53 | a1 <= a2 is always true 54 | 55 | minimized version 56 | ---1----0 1 b1 <= a2 && b1 > b2 57 | -----1--0 1 b2 >= a1 && b1 > b2 58 | ---1-1--- 1 b1 <= a2 && b2 >= a1 59 | */ 60 | 61 | 62 | /* 63 | calculate the intersection between a0/a1 and v0/v1 64 | The intersection check returns one if the range of a0/a1 has an intersection with v0/v1. 65 | The intersection check includes the boundary values v1 and a1. 66 | 67 | The following asserts will succeed: 68 | assert( u8g2_is_intersection_decision_tree(4, 6, 7, 9) == 0 ); 69 | assert( u8g2_is_intersection_decision_tree(4, 6, 6, 9) != 0 ); 70 | assert( u8g2_is_intersection_decision_tree(6, 9, 4, 6) != 0 ); 71 | assert( u8g2_is_intersection_decision_tree(7, 9, 4, 6) == 0 ); 72 | */ 73 | 74 | //static uint8_t U8G2_ALWAYS_INLINE u8g2_is_intersection_decision_tree(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1) 75 | static uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1) 76 | { 77 | if ( v0 <= a1 ) 78 | { 79 | if ( v1 >= a0 ) 80 | { 81 | return 1; 82 | } 83 | else 84 | { 85 | if ( v0 > v1 ) 86 | { 87 | return 1; 88 | } 89 | else 90 | { 91 | return 0; 92 | } 93 | } 94 | } 95 | else 96 | { 97 | if ( v1 >= a0 ) 98 | { 99 | if ( v0 > v1 ) 100 | { 101 | return 1; 102 | } 103 | else 104 | { 105 | return 0; 106 | } 107 | } 108 | else 109 | { 110 | return 0; 111 | } 112 | } 113 | } 114 | 115 | #endif /* OLD_VERSION_WITH_SYMETRIC_BOUNDARIES */ 116 | 117 | 118 | /* 119 | version with asymetric boundaries. 120 | a1 and v1 are excluded 121 | v0 == v1 is not support end return 1 122 | */ 123 | uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1) 124 | { 125 | if ( v0 < a1 ) // v0 <= a1 126 | { 127 | if ( v1 > a0 ) // v1 >= a0 128 | { 129 | return 1; 130 | } 131 | else 132 | { 133 | if ( v0 > v1 ) // v0 > v1 134 | { 135 | return 1; 136 | } 137 | else 138 | { 139 | return 0; 140 | } 141 | } 142 | } 143 | else 144 | { 145 | if ( v1 > a0 ) // v1 >= a0 146 | { 147 | if ( v0 > v1 ) // v0 > v1 148 | { 149 | return 1; 150 | } 151 | else 152 | { 153 | return 0; 154 | } 155 | } 156 | else 157 | { 158 | return 0; 159 | } 160 | } 161 | } 162 | 163 | 164 | 165 | /* upper limits are not included (asymetric boundaries) */ 166 | uint8_t u8g2_IsIntersection(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1) 167 | { 168 | if ( u8g2_is_intersection_decision_tree(u8g2->user_y0, u8g2->user_y1, y0, y1) == 0 ) 169 | return 0; 170 | 171 | return u8g2_is_intersection_decision_tree(u8g2->user_x0, u8g2->user_x1, x0, x1); 172 | } 173 | 174 | 175 | #endif /* U8G2_WITH_INTERSECTION */ 176 | 177 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_kerning.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_kerning.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | /* this function is used as "u8g2_get_kerning_cb" */ 39 | /* 40 | uint8_t u8g2_GetNullKerning(u8g2_t *u8g2, uint16_t e1, uint16_t e2) 41 | { 42 | return 0; 43 | } 44 | */ 45 | 46 | /* this function is used as "u8g2_get_kerning_cb" */ 47 | uint8_t u8g2_GetKerning(U8X8_UNUSED u8g2_t *u8g2, u8g2_kerning_t *kerning, uint16_t e1, uint16_t e2) 48 | { 49 | uint16_t i1, i2, cnt, end; 50 | if ( kerning == NULL ) 51 | return 0; 52 | 53 | /* search for the encoding in the first table */ 54 | cnt = kerning->first_table_cnt; 55 | cnt--; /* ignore the last element of the table, which is 0x0ffff */ 56 | for( i1 = 0; i1 < cnt; i1++ ) 57 | { 58 | if ( kerning->first_encoding_table[i1] == e1 ) 59 | break; 60 | } 61 | if ( i1 >= cnt ) 62 | return 0; /* e1 not part of the kerning table, return 0 */ 63 | 64 | /* get the upper index for i2 */ 65 | end = kerning->index_to_second_table[i1+1]; 66 | for( i2 = kerning->index_to_second_table[i1]; i2 < end; i2++ ) 67 | { 68 | if ( kerning->second_encoding_table[i2] == e2 ) 69 | break; 70 | } 71 | 72 | if ( i2 >= end ) 73 | return 0; /* e2 not part of any pair with e1, return 0 */ 74 | 75 | return kerning->kerning_values[i2]; 76 | } 77 | 78 | uint8_t u8g2_GetKerningByTable(U8X8_UNUSED u8g2_t *u8g2, const uint16_t *kt, uint16_t e1, uint16_t e2) 79 | { 80 | uint16_t i; 81 | i = 0; 82 | if ( kt == NULL ) 83 | return 0; 84 | for(;;) 85 | { 86 | if ( kt[i] == 0x0ffff ) 87 | break; 88 | if ( kt[i] == e1 && kt[i+1] == e2 ) 89 | return kt[i+2]; 90 | i+=3; 91 | } 92 | return 0; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_line.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_box.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | 39 | void u8g2_DrawLine(u8g2_t *u8g2, u8g2_uint_t x1, u8g2_uint_t y1, u8g2_uint_t x2, u8g2_uint_t y2) 40 | { 41 | u8g2_uint_t tmp; 42 | u8g2_uint_t x,y; 43 | u8g2_uint_t dx, dy; 44 | u8g2_int_t err; 45 | u8g2_int_t ystep; 46 | 47 | uint8_t swapxy = 0; 48 | 49 | /* no intersection check at the moment, should be added... */ 50 | 51 | if ( x1 > x2 ) dx = x1-x2; else dx = x2-x1; 52 | if ( y1 > y2 ) dy = y1-y2; else dy = y2-y1; 53 | 54 | if ( dy > dx ) 55 | { 56 | swapxy = 1; 57 | tmp = dx; dx =dy; dy = tmp; 58 | tmp = x1; x1 =y1; y1 = tmp; 59 | tmp = x2; x2 =y2; y2 = tmp; 60 | } 61 | if ( x1 > x2 ) 62 | { 63 | tmp = x1; x1 =x2; x2 = tmp; 64 | tmp = y1; y1 =y2; y2 = tmp; 65 | } 66 | err = dx >> 1; 67 | if ( y2 > y1 ) ystep = 1; else ystep = -1; 68 | y = y1; 69 | 70 | #ifndef U8G2_16BIT 71 | if ( x2 == 255 ) 72 | x2--; 73 | #else 74 | if ( x2 == 0xffff ) 75 | x2--; 76 | #endif 77 | 78 | for( x = x1; x <= x2; x++ ) 79 | { 80 | if ( swapxy == 0 ) 81 | u8g2_DrawPixel(u8g2, x, y); 82 | else 83 | u8g2_DrawPixel(u8g2, y, x); 84 | err -= (uint8_t)dy; 85 | if ( err < 0 ) 86 | { 87 | y += (u8g2_uint_t)ystep; 88 | err += (u8g2_uint_t)dx; 89 | } 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8g2_message.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_message.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | #define SPACE_BETWEEN_BUTTONS_IN_PIXEL 6 39 | #define SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL 3 40 | 41 | uint8_t u8g2_draw_button_line(u8g2_t *u8g2, u8g2_uint_t y, u8g2_uint_t w, uint8_t cursor, const char *s) 42 | { 43 | u8g2_uint_t button_line_width; 44 | 45 | uint8_t i; 46 | uint8_t cnt; 47 | uint8_t is_invert; 48 | 49 | u8g2_uint_t d; 50 | u8g2_uint_t x; 51 | 52 | cnt = u8x8_GetStringLineCnt(s); 53 | 54 | 55 | /* calculate the width of the button line */ 56 | button_line_width = 0; 57 | for( i = 0; i < cnt; i++ ) 58 | { 59 | button_line_width += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s)); 60 | } 61 | button_line_width += (cnt-1)*SPACE_BETWEEN_BUTTONS_IN_PIXEL; /* add some space between the buttons */ 62 | 63 | /* calculate the left offset */ 64 | d = 0; 65 | if ( button_line_width < w ) 66 | { 67 | d = w; 68 | d -= button_line_width; 69 | d /= 2; 70 | } 71 | 72 | /* draw the buttons */ 73 | x = d; 74 | for( i = 0; i < cnt; i++ ) 75 | { 76 | is_invert = 0; 77 | if ( i == cursor ) 78 | is_invert = 1; 79 | 80 | u8g2_DrawUTF8Line(u8g2, x, y, 0, u8x8_GetStringLineStart(i, s), 1, is_invert); 81 | x += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s)); 82 | x += SPACE_BETWEEN_BUTTONS_IN_PIXEL; 83 | } 84 | 85 | /* return the number of buttons */ 86 | return cnt; 87 | } 88 | 89 | /* 90 | title1: Multiple lines,separated by '\n' 91 | title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart() 92 | title3: Multiple lines,separated by '\n' 93 | buttons: one more more buttons separated by '\n' and terminated with '\0' 94 | side effects: 95 | u8g2_SetFontDirection(u8g2, 0); 96 | u8g2_SetFontPosBaseline(u8g2); 97 | */ 98 | 99 | uint8_t u8g2_UserInterfaceMessage(u8g2_t *u8g2, const char *title1, const char *title2, const char *title3, const char *buttons) 100 | { 101 | uint8_t height; 102 | uint8_t line_height; 103 | u8g2_uint_t pixel_height; 104 | u8g2_uint_t y, yy; 105 | 106 | uint8_t cursor = 0; 107 | uint8_t button_cnt; 108 | uint8_t event; 109 | 110 | /* only horizontal strings are supported, so force this here */ 111 | u8g2_SetFontDirection(u8g2, 0); 112 | 113 | /* force baseline position */ 114 | u8g2_SetFontPosBaseline(u8g2); 115 | 116 | 117 | /* calculate line height */ 118 | line_height = u8g2_GetAscent(u8g2); 119 | line_height -= u8g2_GetDescent(u8g2); 120 | 121 | /* calculate overall height of the message box in lines*/ 122 | height = 1; /* button line */ 123 | height += u8x8_GetStringLineCnt(title1); 124 | if ( title2 != NULL ) 125 | height++; 126 | height += u8x8_GetStringLineCnt(title3); 127 | 128 | /* calculate the height in pixel */ 129 | pixel_height = height; 130 | pixel_height *= line_height; 131 | 132 | /* ... and add the space between the text and the buttons */ 133 | pixel_height +=SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL; 134 | 135 | /* calculate offset from top */ 136 | y = 0; 137 | if ( pixel_height < u8g2_GetDisplayHeight(u8g2) ) 138 | { 139 | y = u8g2_GetDisplayHeight(u8g2); 140 | y -= pixel_height; 141 | y /= 2; 142 | } 143 | y += u8g2_GetAscent(u8g2); 144 | 145 | 146 | for(;;) 147 | { 148 | u8g2_FirstPage(u8g2); 149 | do 150 | { 151 | yy = y; 152 | /* draw message box */ 153 | 154 | yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title1); 155 | if ( title2 != NULL ) 156 | { 157 | u8g2_DrawUTF8Line(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), title2, 0, 0); 158 | yy+=line_height; 159 | } 160 | yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title3); 161 | yy += SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL; 162 | 163 | button_cnt = u8g2_draw_button_line(u8g2, yy, u8g2_GetDisplayWidth(u8g2), cursor, buttons); 164 | 165 | } while( u8g2_NextPage(u8g2) ); 166 | 167 | #ifdef U8G2_REF_MAN_PIC 168 | return 0; 169 | #endif 170 | 171 | for(;;) 172 | { 173 | event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2)); 174 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 175 | return cursor+1; 176 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 177 | return 0; 178 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN ) 179 | { 180 | cursor++; 181 | if ( cursor >= button_cnt ) 182 | cursor = 0; 183 | break; 184 | } 185 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP ) 186 | { 187 | if ( cursor == 0 ) 188 | cursor = button_cnt; 189 | cursor--; 190 | break; 191 | } 192 | } 193 | } 194 | /* never reached */ 195 | //return 0; 196 | } 197 | 198 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8log_u8g2.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8log_u8g2.c 4 | 5 | 6 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 7 | 8 | Copyright (c) 2018, olikraus@gmail.com 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without modification, 12 | are permitted provided that the following conditions are met: 13 | 14 | * Redistributions of source code must retain the above copyright notice, this list 15 | of conditions and the following disclaimer. 16 | 17 | * Redistributions in binary form must reproduce the above copyright notice, this 18 | list of conditions and the following disclaimer in the documentation and/or other 19 | materials provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 22 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 23 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | */ 36 | 37 | #include "u8g2.h" 38 | /* 39 | Draw the u8log text at the specified x/y position. 40 | x/y position is the reference position of the first char of the first line. 41 | the line height is 42 | u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) + line_height_offset; 43 | line_height_offset can be set with u8log_SetLineHeightOffset() 44 | Use 45 | u8g2_SetFontRefHeightText(u8g2_t *u8g2); 46 | u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2); 47 | u8g2_SetFontRefHeightAll(u8g2_t *u8g2); 48 | to change the return values for u8g2_GetAscent and u8g2_GetDescent 49 | 50 | */ 51 | void u8g2_DrawLog(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8log_t *u8log) 52 | { 53 | u8g2_uint_t disp_x, disp_y; 54 | uint8_t buf_x, buf_y; 55 | uint8_t c; 56 | 57 | disp_y = y; 58 | u8g2_SetFontDirection(u8g2, 0); 59 | for( buf_y = 0; buf_y < u8log->height; buf_y++ ) 60 | { 61 | disp_x = x; 62 | for( buf_x = 0; buf_x < u8log->width; buf_x++ ) 63 | { 64 | c = u8log->screen_buffer[buf_y * u8log->width + buf_x]; 65 | disp_x += u8g2_DrawGlyph(u8g2, disp_x, disp_y, c); 66 | } 67 | disp_y += u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2); 68 | disp_y += u8log->line_height_offset; 69 | } 70 | } 71 | 72 | /* 73 | u8lib callback for u8g2 74 | 75 | Only font direction 0 is supported: u8g2_SetFontDirection(u8g2, 0) 76 | Use 77 | u8g2_SetFontRefHeightText(u8g2_t *u8g2); 78 | u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2); 79 | u8g2_SetFontRefHeightAll(u8g2_t *u8g2); 80 | to change the top offset and the line height and 81 | u8log_SetLineHeightOffset(u8log_t *u8log, int8_t line_height_offset) 82 | to change the line height. 83 | 84 | */ 85 | void u8log_u8g2_cb(u8log_t * u8log) 86 | { 87 | u8g2_t *u8g2 = (u8g2_t *)(u8log->aux_data); 88 | if ( u8log->is_redraw_line || u8log->is_redraw_all ) 89 | { 90 | u8g2_FirstPage(u8g2); 91 | do 92 | { 93 | u8g2_DrawLog( u8g2, 0, u8g2_GetAscent(u8g2), u8log); 94 | } 95 | while( u8g2_NextPage(u8g2) ); 96 | } 97 | } 98 | 99 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8log_u8x8.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8log_u8x8.c 4 | 5 | 6 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 7 | 8 | Copyright (c) 2018, olikraus@gmail.com 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without modification, 12 | are permitted provided that the following conditions are met: 13 | 14 | * Redistributions of source code must retain the above copyright notice, this list 15 | of conditions and the following disclaimer. 16 | 17 | * Redistributions in binary form must reproduce the above copyright notice, this 18 | list of conditions and the following disclaimer in the documentation and/or other 19 | materials provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 22 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 23 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | */ 36 | 37 | #include "u8x8.h" 38 | 39 | static void u8x8_DrawLogLine(u8x8_t *u8x8, uint8_t disp_x, uint8_t disp_y, uint8_t buf_y, u8log_t *u8log) U8X8_NOINLINE; 40 | static void u8x8_DrawLogLine(u8x8_t *u8x8, uint8_t disp_x, uint8_t disp_y, uint8_t buf_y, u8log_t *u8log) 41 | { 42 | uint8_t buf_x; 43 | uint8_t c; 44 | for( buf_x = 0; buf_x < u8log->width; buf_x++ ) 45 | { 46 | c = u8log->screen_buffer[buf_y * u8log->width + buf_x]; 47 | u8x8_DrawGlyph(u8x8, disp_x, disp_y, c); 48 | disp_x++; 49 | } 50 | } 51 | 52 | void u8x8_DrawLog(u8x8_t *u8x8, uint8_t x, uint8_t y, u8log_t *u8log) 53 | { 54 | uint8_t buf_y; 55 | for( buf_y = 0; buf_y < u8log->height; buf_y++ ) 56 | { 57 | u8x8_DrawLogLine(u8x8, x, y, buf_y, u8log); 58 | y++; 59 | } 60 | } 61 | 62 | 63 | void u8log_u8x8_cb(u8log_t * u8log) 64 | { 65 | u8x8_t *u8x8 = (u8x8_t *)(u8log->aux_data); 66 | if ( u8log->is_redraw_all ) 67 | { 68 | u8x8_DrawLog(u8x8, 0, 0, u8log); 69 | } 70 | else if ( u8log->is_redraw_line ) 71 | { 72 | u8x8_DrawLogLine(u8x8, 0, u8log->redraw_line, u8log->redraw_line, u8log); 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_d_a2printer.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_a2printer.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | 35 | Use DC2 bitmap command of the A2 Micro panel termal printer 36 | double stroke 37 | 38 | 39 | */ 40 | 41 | 42 | #include "u8x8.h" 43 | 44 | #define LINE_MIN_DELAY_MS 15 45 | /* higher values improve quality */ 46 | /* however if the value is too high (>=5) then form feed does not work any more */ 47 | #define LINE_EXTRA_8PIXEL_DELAY_MS 3 48 | /* this must be a power of two and between 1 and 8 */ 49 | /* best quality only with 1 */ 50 | #define NO_OF_LINES_TO_SEND_WITHOUT_DELAY 1 51 | 52 | /* calculates the delay, based on the number of black pixel */ 53 | /* actually only "none-zero" bytes are calculated which is, of course not so accurate, but should be good enough */ 54 | uint16_t get_delay_in_milliseconds(uint8_t cnt, uint8_t *data) 55 | { 56 | uint8_t i; 57 | uint16_t time = LINE_MIN_DELAY_MS; 58 | for ( i = 0; i < cnt; i++ ) 59 | if ( data[i] != 0 ) 60 | time += LINE_EXTRA_8PIXEL_DELAY_MS; 61 | return time; 62 | } 63 | 64 | uint8_t u8x8_d_a2printer_common(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr) 65 | { 66 | uint8_t c, i, j; 67 | uint8_t *ptr; 68 | uint16_t delay_in_milliseconds; 69 | switch(msg) 70 | { 71 | /* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */ 72 | /* 73 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 74 | break; 75 | */ 76 | case U8X8_MSG_DISPLAY_INIT: 77 | u8x8_d_helper_display_init(u8x8); 78 | // no setup required 79 | // u8x8_cad_SendSequence(u8x8, u8x8_d_a2printer_init_seq); 80 | break; 81 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 82 | // no powersave 83 | break; 84 | case U8X8_MSG_DISPLAY_DRAW_TILE: 85 | u8x8_cad_StartTransfer(u8x8); 86 | 87 | u8x8_cad_SendCmd(u8x8, 27); /* ESC */ 88 | u8x8_cad_SendCmd(u8x8, 55 ); /* parameter command */ 89 | /* increasing the "max printing dots" requires a good power supply, but LINE_EXTRA_8PIXEL_DELAY_MS could be reduced then */ 90 | u8x8_cad_SendCmd(u8x8, 0); /* Max printing dots,Unit(8dots),Default:7(64 dots) 8*(x+1) ... lower values improve, probably my current supply is not sufficient */ 91 | u8x8_cad_SendCmd(u8x8, 200); /* 3-255 Heating time,Unit(10us),Default:80(800us) */ 92 | u8x8_cad_SendCmd(u8x8, 2); /* 0-255 Heating interval,Unit(10us),Default:2(20us) ... does not have much influence */ 93 | 94 | //c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */ 95 | c = u8x8->display_info->tile_width; 96 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */ 97 | 98 | u8x8_cad_SendCmd(u8x8, 18); /* DC2 */ 99 | u8x8_cad_SendCmd(u8x8, 42 ); /* * */ 100 | u8x8_cad_SendCmd(u8x8, 8 ); /* height */ 101 | u8x8_cad_SendCmd(u8x8, c ); /* c, u8x8->display_info->tile_width */ 102 | 103 | for( j = 0; j < 8 / NO_OF_LINES_TO_SEND_WITHOUT_DELAY; j ++ ) 104 | { 105 | 106 | delay_in_milliseconds = 0; 107 | for( i = 0; i < NO_OF_LINES_TO_SEND_WITHOUT_DELAY; i++ ) 108 | { 109 | u8x8_cad_SendData(u8x8, c, ptr); /* c, note: SendData can not handle more than 255 bytes, send one line of data */ 110 | delay_in_milliseconds += get_delay_in_milliseconds(c, ptr); 111 | ptr += c; 112 | } 113 | 114 | while( delay_in_milliseconds > 200 ) 115 | { 116 | u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_MILLI, 200, NULL); 117 | delay_in_milliseconds -= 200; 118 | } 119 | u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_MILLI, delay_in_milliseconds, NULL); 120 | } 121 | 122 | /* set parameters back to their default values */ 123 | u8x8_cad_SendCmd(u8x8, 27); /* ESC */ 124 | u8x8_cad_SendCmd(u8x8, 55 ); /* parameter command */ 125 | u8x8_cad_SendCmd(u8x8, 7); /* Max printing dots,Unit(8dots),Default:7(64 dots) 8*(x+1)*/ 126 | u8x8_cad_SendCmd(u8x8, 80); /* 3-255 Heating time,Unit(10us),Default:80(800us) */ 127 | u8x8_cad_SendCmd(u8x8, 2); /* 0-255 Heating interval,Unit(10us),Default:2(20us)*/ 128 | 129 | u8x8_cad_EndTransfer(u8x8); 130 | 131 | break; 132 | default: 133 | return 0; 134 | } 135 | return 1; 136 | } 137 | 138 | 139 | static const u8x8_display_info_t u8x8_a2printer_384x240_display_info = 140 | { 141 | /* most of the settings are not required, because this is a serial RS232 printer */ 142 | 143 | /* chip_enable_level = */ 1, 144 | /* chip_disable_level = */ 0, 145 | 146 | /* post_chip_enable_wait_ns = */ 5, 147 | /* pre_chip_disable_wait_ns = */ 5, 148 | /* reset_pulse_width_ms = */ 1, 149 | /* post_reset_wait_ms = */ 6, 150 | /* sda_setup_time_ns = */ 20, 151 | /* sck_pulse_width_ns = */ 140, 152 | /* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 153 | /* spi_mode = */ 0, /* old: sck_takeover_edge, new: active high (bit 1), rising edge (bit 0) */ 154 | /* i2c_bus_clock_100kHz = */ 4, 155 | /* data_setup_time_ns = */ 30, 156 | /* write_pulse_width_ns = */ 40, 157 | /* tile_width = */ 48, 158 | /* tile_hight = */ 30, 159 | /* default_x_offset = */ 0, 160 | /* flipmode_x_offset = */ 0, 161 | /* pixel_width = */ 384, 162 | /* pixel_height = */ 240 163 | }; 164 | 165 | uint8_t u8x8_d_a2printer_384x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 166 | { 167 | switch(msg) 168 | { 169 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 170 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_a2printer_384x240_display_info); 171 | break; 172 | default: 173 | return u8x8_d_a2printer_common(u8x8, msg, arg_int, arg_ptr); 174 | } 175 | return 1; 176 | } 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_d_pcd8544_84x48.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_pcd8544_84x48.c (so called "Nokia 5110" displays) 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | 35 | */ 36 | #include "u8x8.h" 37 | 38 | 39 | 40 | 41 | static const uint8_t u8x8_d_pcd8544_84x48_init_seq[] = { 42 | 43 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 44 | 45 | U8X8_C(0x021), /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */ 46 | U8X8_C(0x006), /* temp. control: b10 = 2 */ 47 | U8X8_C(0x013), /* bias system 1:48 */ 48 | U8X8_C(0x0c0), /* medium Vop */ 49 | 50 | U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 51 | U8X8_C(0x008), /* blank */ 52 | U8X8_C(0x024), /* power down (PD=1), horizontal increment (V=0), enter normal command set (H=0) */ 53 | 54 | U8X8_END_TRANSFER(), /* disable chip */ 55 | U8X8_END() /* end of sequence */ 56 | }; 57 | 58 | static const uint8_t u8x8_d_pcd8544_84x48_powersave0_seq[] = { 59 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 60 | U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 61 | U8X8_C(0x00c), /* display on */ 62 | U8X8_END_TRANSFER(), /* disable chip */ 63 | U8X8_END() /* end of sequence */ 64 | }; 65 | 66 | static const uint8_t u8x8_d_pcd8544_84x48_powersave1_seq[] = { 67 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 68 | U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 69 | U8X8_C(0x008), /* blank */ 70 | U8X8_C(0x024), /* power down (PD=1), horizontal increment (V=0), enter normal command set (H=0) */ 71 | U8X8_END_TRANSFER(), /* disable chip */ 72 | U8X8_END() /* end of sequence */ 73 | }; 74 | 75 | 76 | 77 | static const u8x8_display_info_t u8x8_pcd8544_84x48_display_info = 78 | { 79 | /* chip_enable_level = */ 0, 80 | /* chip_disable_level = */ 1, 81 | 82 | /* post_chip_enable_wait_ns = */ 5, 83 | /* pre_chip_disable_wait_ns = */ 5, 84 | /* reset_pulse_width_ms = */ 2, 85 | /* post_reset_wait_ms = */ 2, 86 | /* sda_setup_time_ns = */ 12, 87 | /* sck_pulse_width_ns = */ 75, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */ 88 | /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 89 | /* spi_mode = */ 0, /* active high, rising edge */ 90 | /* i2c_bus_clock_100kHz = */ 4, 91 | /* data_setup_time_ns = */ 30, 92 | /* write_pulse_width_ns = */ 40, 93 | /* tile_width = */ 11, /* width of 11*8=88 pixel */ 94 | /* tile_hight = */ 6, 95 | /* default_x_offset = */ 0, 96 | /* flipmode_x_offset = */ 0, 97 | /* pixel_width = */ 84, 98 | /* pixel_height = */ 48 99 | }; 100 | 101 | uint8_t u8x8_d_pcd8544_84x48(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 102 | { 103 | uint8_t x, c; 104 | uint8_t *ptr; 105 | switch(msg) 106 | { 107 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 108 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcd8544_84x48_display_info); 109 | break; 110 | case U8X8_MSG_DISPLAY_INIT: 111 | u8x8_d_helper_display_init(u8x8); 112 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_init_seq); 113 | break; 114 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 115 | if ( arg_int == 0 ) 116 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_powersave0_seq); 117 | else 118 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_powersave1_seq); 119 | break; 120 | // case U8X8_MSG_DISPLAY_SET_FLIP_MODE: 121 | // break; NOT SUPPORTED 122 | 123 | #ifdef U8X8_WITH_SET_CONTRAST 124 | case U8X8_MSG_DISPLAY_SET_CONTRAST: 125 | u8x8_cad_StartTransfer(u8x8); 126 | u8x8_cad_SendCmd(u8x8, 0x021 ); /* command mode, extended function set */ 127 | u8x8_cad_SendCmd(u8x8, 0x080 | (arg_int >> 1) ); 128 | u8x8_cad_EndTransfer(u8x8); 129 | break; 130 | #endif 131 | case U8X8_MSG_DISPLAY_DRAW_TILE: 132 | u8x8_cad_StartTransfer(u8x8); 133 | 134 | x = ((u8x8_tile_t *)arg_ptr)->x_pos; 135 | x *= 8; 136 | x += u8x8->x_offset; 137 | u8x8_cad_SendCmd(u8x8, 0x020 ); /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 138 | u8x8_cad_SendCmd(u8x8, 0x080 | (x) ); /* set X address */ 139 | u8x8_cad_SendCmd(u8x8, 0x040 | (((u8x8_tile_t *)arg_ptr)->y_pos) ); /* set Y address */ 140 | 141 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; 142 | c = ((u8x8_tile_t *)arg_ptr)->cnt; 143 | c *= 8; 144 | do 145 | { 146 | if ( c + x > 84u ) 147 | { 148 | if ( x >= 84u ) 149 | break; 150 | c = 84u; 151 | c -= x; 152 | } 153 | u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */ 154 | x += c; 155 | arg_int--; 156 | } while( arg_int > 0 ); 157 | 158 | u8x8_cad_EndTransfer(u8x8); 159 | break; 160 | default: 161 | return 0; 162 | } 163 | return 1; 164 | } 165 | 166 | 167 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_d_pcf8812.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_pcf8812.c 4 | 5 | pcf8812: 65x102 6 | pcf8814: 65x96 7 | 8 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 9 | 10 | Copyright (c) 2017, olikraus@gmail.com 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without modification, 14 | are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, this list 17 | of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright notice, this 20 | list of conditions and the following disclaimer in the documentation and/or other 21 | materials provided with the distribution. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 24 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 25 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 28 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 35 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | 37 | */ 38 | 39 | 40 | #include "u8x8.h" 41 | 42 | 43 | 44 | static const uint8_t u8x8_d_pcf8812_96x65_init_seq[] = { 45 | 46 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 47 | 48 | U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 49 | U8X8_C(0x008), /* blank display */ 50 | 51 | U8X8_C(0x021), /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */ 52 | U8X8_C(0x006), /* temp. control: b10 = 2 */ 53 | U8X8_C(0x013), /* bias system, 0x010..0x07 1:48 */ 54 | U8X8_C(0x09f), /* contrast setting, 0..127 */ 55 | //U8X8_CA(0x020 | 2, 0x080 | 0), /* contrast setting, pcf8814 */ 56 | 57 | U8X8_C(0x024), /* deactivate chip (PD=1), horizontal increment (V=0), enter normal command set (H=0) */ 58 | 59 | U8X8_END_TRANSFER(), /* disable chip */ 60 | U8X8_END() /* end of sequence */ 61 | }; 62 | 63 | static const uint8_t u8x8_d_pcf8812_96x65_powersave0_seq[] = { 64 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 65 | U8X8_C(0x020), /* power on */ 66 | U8X8_C(0x00c), /* display on */ 67 | U8X8_END_TRANSFER(), /* disable chip */ 68 | U8X8_END() /* end of sequence */ 69 | }; 70 | 71 | static const uint8_t u8x8_d_pcf8812_96x65_powersave1_seq[] = { 72 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 73 | U8X8_C(0x020), /* power on */ 74 | U8X8_C(0x008), /* blank display */ 75 | U8X8_C(0x024), /* power down */ 76 | U8X8_END_TRANSFER(), /* disable chip */ 77 | U8X8_END() /* end of sequence */ 78 | }; 79 | 80 | 81 | static uint8_t u8x8_d_pcf8812_96x65_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 82 | { 83 | uint8_t x, c; 84 | uint8_t *ptr; 85 | switch(msg) 86 | { 87 | /* handled by the calling function 88 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 89 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info); 90 | break; 91 | */ 92 | case U8X8_MSG_DISPLAY_INIT: 93 | u8x8_d_helper_display_init(u8x8); 94 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_init_seq); 95 | break; 96 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 97 | if ( arg_int == 0 ) 98 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave0_seq); 99 | else 100 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave1_seq); 101 | break; 102 | /* 103 | case U8X8_MSG_DISPLAY_SET_FLIP_MODE: 104 | if ( arg_int == 0 ) 105 | { 106 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip0_seq); 107 | u8x8->x_offset = u8x8->display_info->default_x_offset; 108 | } 109 | else 110 | { 111 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip1_seq); 112 | u8x8->x_offset = u8x8->display_info->flipmode_x_offset; 113 | } 114 | break; 115 | */ 116 | #ifdef U8X8_WITH_SET_CONTRAST 117 | case U8X8_MSG_DISPLAY_SET_CONTRAST: 118 | u8x8_cad_StartTransfer(u8x8); 119 | u8x8_cad_SendCmd(u8x8, 0x021 ); /* command mode, extended function set */ 120 | u8x8_cad_SendArg(u8x8, (arg_int>>1)|0x80 ); /* 0..127 for contrast */ 121 | u8x8_cad_EndTransfer(u8x8); 122 | break; 123 | #endif 124 | case U8X8_MSG_DISPLAY_DRAW_TILE: 125 | u8x8_cad_StartTransfer(u8x8); 126 | x = ((u8x8_tile_t *)arg_ptr)->x_pos; 127 | x *= 8; 128 | x += u8x8->x_offset; 129 | 130 | u8x8_cad_SendCmd(u8x8, 0x020 ); /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 131 | u8x8_cad_SendCmd(u8x8, 0x080 | x); 132 | u8x8_cad_SendCmd(u8x8, 0x040 | ((u8x8_tile_t *)arg_ptr)->y_pos); 133 | 134 | do 135 | { 136 | c = ((u8x8_tile_t *)arg_ptr)->cnt; 137 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; 138 | u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */ 139 | /* 140 | do 141 | { 142 | u8x8_cad_SendData(u8x8, 8, ptr); 143 | ptr += 8; 144 | c--; 145 | } while( c > 0 ); 146 | */ 147 | arg_int--; 148 | } while( arg_int > 0 ); 149 | 150 | u8x8_cad_EndTransfer(u8x8); 151 | break; 152 | default: 153 | return 0; 154 | } 155 | return 1; 156 | } 157 | 158 | 159 | static const u8x8_display_info_t u8x8_pcf8812_96x65_display_info = 160 | { 161 | /* chip_enable_level = */ 0, 162 | /* chip_disable_level = */ 1, 163 | 164 | /* post_chip_enable_wait_ns = */ 100, 165 | /* pre_chip_disable_wait_ns = */ 100, 166 | /* reset_pulse_width_ms = */ 100, 167 | /* post_reset_wait_ms = */ 100, 168 | /* sda_setup_time_ns = */ 100, 169 | /* sck_pulse_width_ns = */ 100, 170 | /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 171 | /* spi_mode = */ 0, /* active high, rising edge */ 172 | /* i2c_bus_clock_100kHz = */ 4, 173 | /* data_setup_time_ns = */ 40, 174 | /* write_pulse_width_ns = */ 150, 175 | /* tile_width = */ 12, 176 | /* tile_hight = */ 9, 177 | /* default_x_offset = */ 0, 178 | /* flipmode_x_offset = */ 0, 179 | /* pixel_width = */ 96, 180 | /* pixel_height = */ 65 181 | }; 182 | 183 | uint8_t u8x8_d_pcf8812_96x65(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 184 | { 185 | if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY ) 186 | { 187 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info); 188 | return 1; 189 | } 190 | return u8x8_d_pcf8812_96x65_generic(u8x8, msg, arg_int, arg_ptr); 191 | } 192 | 193 | 194 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_d_pcf8814_hx1230.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_pcf8814_hc1230.c 4 | 5 | pcf8814: 65x96 6 | hx1230: 68x96 7 | 8 | pcf8814 and hc1230 are almost identical. 9 | 10 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 11 | 12 | Copyright (c) 2017, olikraus@gmail.com 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without modification, 16 | are permitted provided that the following conditions are met: 17 | 18 | * Redistributions of source code must retain the above copyright notice, this list 19 | of conditions and the following disclaimer. 20 | 21 | * Redistributions in binary form must reproduce the above copyright notice, this 22 | list of conditions and the following disclaimer in the documentation and/or other 23 | materials provided with the distribution. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 26 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 27 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 29 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 30 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 32 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 33 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 34 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 35 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 37 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | 39 | */ 40 | 41 | 42 | #include "u8x8.h" 43 | 44 | 45 | 46 | static const uint8_t u8x8_d_hx1230_96x68_init_seq[] = { 47 | 48 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 49 | 50 | U8X8_C(0x0ae), /* display off */ 51 | U8X8_C(0x020), /* power off */ 52 | U8X8_C(0x080), /* contrast setting, 0..31, set to 0 */ 53 | U8X8_C(0x0a6), /* not inverted display */ 54 | U8X8_C(0x0a4), /* normal display mode */ 55 | 56 | U8X8_C(0x0a0), /* */ 57 | U8X8_C(0x0c0), /* */ 58 | 59 | U8X8_C(0x040), /* start at scanline 0 */ 60 | 61 | U8X8_END_TRANSFER(), /* disable chip */ 62 | U8X8_END() /* end of sequence */ 63 | }; 64 | 65 | static const uint8_t u8x8_d_hx1230_96x68_powersave0_seq[] = { 66 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 67 | U8X8_C(0x02f), /* power on */ 68 | U8X8_C(0x0af), /* display on */ 69 | U8X8_END_TRANSFER(), /* disable chip */ 70 | U8X8_END() /* end of sequence */ 71 | }; 72 | 73 | static const uint8_t u8x8_d_hx1230_96x68_powersave1_seq[] = { 74 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 75 | U8X8_C(0x0ae), /* display off */ 76 | U8X8_C(0x0a5), /* All pixels on = powersave */ 77 | U8X8_END_TRANSFER(), /* disable chip */ 78 | U8X8_END() /* end of sequence */ 79 | }; 80 | 81 | static const uint8_t u8x8_d_hx1230_96x68_flip0_seq[] = { 82 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 83 | U8X8_C(0x0a0), /* */ 84 | U8X8_C(0x0c0), /* */ 85 | U8X8_END_TRANSFER(), /* disable chip */ 86 | U8X8_END() /* end of sequence */ 87 | }; 88 | 89 | static const uint8_t u8x8_d_hx1230_96x68_flip1_seq[] = { 90 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 91 | U8X8_C(0x0a1), /* */ 92 | U8X8_C(0x0c8), /* */ 93 | U8X8_END_TRANSFER(), /* disable chip */ 94 | U8X8_END() /* end of sequence */ 95 | }; 96 | 97 | 98 | static uint8_t u8x8_d_hx1230_96x68_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 99 | { 100 | uint8_t x, c; 101 | uint8_t *ptr; 102 | switch(msg) 103 | { 104 | /* handled by the calling function 105 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 106 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_hx1230_96x68_display_info); 107 | break; 108 | */ 109 | case U8X8_MSG_DISPLAY_INIT: 110 | u8x8_d_helper_display_init(u8x8); 111 | u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_init_seq); 112 | break; 113 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 114 | if ( arg_int == 0 ) 115 | u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_powersave0_seq); 116 | else 117 | u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_powersave1_seq); 118 | break; 119 | case U8X8_MSG_DISPLAY_SET_FLIP_MODE: 120 | if ( arg_int == 0 ) 121 | { 122 | u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_flip0_seq); 123 | u8x8->x_offset = u8x8->display_info->default_x_offset; 124 | } 125 | else 126 | { 127 | u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_flip1_seq); 128 | u8x8->x_offset = u8x8->display_info->flipmode_x_offset; 129 | } 130 | break; 131 | #ifdef U8X8_WITH_SET_CONTRAST 132 | case U8X8_MSG_DISPLAY_SET_CONTRAST: 133 | u8x8_cad_StartTransfer(u8x8); 134 | u8x8_cad_SendCmd(u8x8, (arg_int>>3)|0x80 ); /* 0..31 for contrast */ 135 | u8x8_cad_EndTransfer(u8x8); 136 | break; 137 | #endif 138 | case U8X8_MSG_DISPLAY_DRAW_TILE: 139 | u8x8_cad_StartTransfer(u8x8); 140 | x = ((u8x8_tile_t *)arg_ptr)->x_pos; 141 | x *= 8; 142 | x += u8x8->x_offset; 143 | 144 | u8x8_cad_SendCmd(u8x8, x&15); 145 | u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4)); 146 | u8x8_cad_SendCmd(u8x8, 0x0b0 | ((u8x8_tile_t *)arg_ptr)->y_pos); 147 | 148 | do 149 | { 150 | c = ((u8x8_tile_t *)arg_ptr)->cnt; 151 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; 152 | u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */ 153 | arg_int--; 154 | } while( arg_int > 0 ); 155 | 156 | u8x8_cad_EndTransfer(u8x8); 157 | break; 158 | default: 159 | return 0; 160 | } 161 | return 1; 162 | } 163 | 164 | static const u8x8_display_info_t u8x8_hx1230_96x68_display_info = 165 | { 166 | /* chip_enable_level = */ 0, 167 | /* chip_disable_level = */ 1, 168 | 169 | /* post_chip_enable_wait_ns = */ 100, 170 | /* pre_chip_disable_wait_ns = */ 100, 171 | /* reset_pulse_width_ms = */ 100, 172 | /* post_reset_wait_ms = */ 100, 173 | /* sda_setup_time_ns = */ 100, 174 | /* sck_pulse_width_ns = */ 100, 175 | /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 176 | /* spi_mode = */ 0, /* active high, rising edge */ 177 | /* i2c_bus_clock_100kHz = */ 4, 178 | /* data_setup_time_ns = */ 40, 179 | /* write_pulse_width_ns = */ 150, 180 | /* tile_width = */ 12, 181 | /* tile_hight = */ 9, 182 | /* default_x_offset = */ 0, 183 | /* flipmode_x_offset = */ 0, 184 | /* pixel_width = */ 96, 185 | /* pixel_height = */ 68 186 | }; 187 | 188 | uint8_t u8x8_d_hx1230_96x68(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 189 | { 190 | if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY ) 191 | { 192 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_hx1230_96x68_display_info); 193 | return 1; 194 | } 195 | return u8x8_d_hx1230_96x68_generic(u8x8, msg, arg_int, arg_ptr); 196 | } 197 | 198 | 199 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_d_stdio.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_stdio.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8x8.h" 37 | 38 | #include 39 | 40 | #define W 8 41 | #define H 2 42 | 43 | uint8_t bitmap[W*H*8]; 44 | 45 | void bitmap_place_tile(uint8_t x, uint8_t y, uint8_t *tile) 46 | { 47 | uint8_t i; 48 | for(i = 0; i < 8; i++ ) 49 | bitmap[x*8+y*W*8+i] = tile[i]; 50 | } 51 | 52 | void bitmap_show(void) 53 | { 54 | int x, y; 55 | for( y = 0; y < H*8; y++ ) 56 | { 57 | for( x = 0; x < W*8; x++ ) 58 | { 59 | if ( (bitmap[x+(y/8)*W*8] & (1<<((y&7)))) != 0 ) 60 | { 61 | printf("*"); 62 | } 63 | else 64 | { 65 | printf("."); 66 | } 67 | } 68 | printf("\n"); 69 | } 70 | } 71 | 72 | 73 | uint8_t u8x8_d_stdio(U8X8_UNUSED u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 74 | { 75 | switch(msg) 76 | { 77 | case U8X8_MSG_DISPLAY_INIT: 78 | break; 79 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 80 | if ( arg_int == 0 ) 81 | bitmap_show(); 82 | break; 83 | case U8X8_MSG_DISPLAY_SET_CONTRAST: 84 | break; 85 | case U8X8_MSG_DISPLAY_DRAW_TILE: 86 | bitmap_place_tile(((u8x8_tile_t *)arg_ptr)->x_pos, ((u8x8_tile_t *)arg_ptr)->y_pos, ((u8x8_tile_t *)arg_ptr)->tile_ptr); 87 | break; 88 | default: 89 | break; 90 | } 91 | return 1; 92 | } 93 | 94 | 95 | 96 | void u8x8_SetupStdio(u8x8_t *u8x8) 97 | { 98 | u8x8_SetupDefaults(u8x8); 99 | u8x8->display_cb = u8x8_d_stdio; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_d_uc1601.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_uc1601.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2017, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | This is for the uc1601s controller 35 | 36 | 37 | */ 38 | #include "u8x8.h" 39 | 40 | 41 | 42 | 43 | static const uint8_t u8x8_d_uc1601_128x32_powersave0_seq[] = { 44 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 45 | U8X8_C(0x0af), /* display on */ 46 | U8X8_END_TRANSFER(), /* disable chip */ 47 | U8X8_END() /* end of sequence */ 48 | }; 49 | 50 | static const uint8_t u8x8_d_uc1601_128x32_powersave1_seq[] = { 51 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 52 | U8X8_C(0x0ae), /* display off */ 53 | U8X8_END_TRANSFER(), /* disable chip */ 54 | U8X8_END() /* end of sequence */ 55 | }; 56 | 57 | static const uint8_t u8x8_d_uc1601_128x32_flip0_seq[] = { 58 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 59 | U8X8_C(0x0c4), /* bit 1: MX, bit 2: MY */ 60 | U8X8_C(0x060), /* set display start line to 32 */ 61 | U8X8_END_TRANSFER(), /* disable chip */ 62 | U8X8_END() /* end of sequence */ 63 | }; 64 | 65 | static const uint8_t u8x8_d_uc1601_128x32_flip1_seq[] = { 66 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 67 | U8X8_C(0x0c2), /* bit 1: MX, bit 2: MY */ 68 | U8X8_C(0x040), /* set display start line to 0 */ 69 | U8X8_END_TRANSFER(), /* disable chip */ 70 | U8X8_END() /* end of sequence */ 71 | }; 72 | 73 | 74 | static const u8x8_display_info_t u8x8_uc1601_128x32_display_info = 75 | { 76 | /* chip_enable_level = */ 0, 77 | /* chip_disable_level = */ 1, 78 | 79 | /* post_chip_enable_wait_ns = */ 1, /* uc1601 datasheet, page 46 */ 80 | /* pre_chip_disable_wait_ns = */ 5, /* uc1601 datasheet, page 46 */ 81 | /* reset_pulse_width_ms = */ 1, 82 | /* post_reset_wait_ms = */ 6, 83 | /* sda_setup_time_ns = */ 12, /* uc1601 datasheet, page 44 */ 84 | /* sck_pulse_width_ns = */ 15, /* uc1601 datasheet, page 44 */ 85 | /* sck_clock_hz = */ 2000000UL, /* */ 86 | /* spi_mode = */ 0, /* active high, rising edge */ 87 | /* i2c_bus_clock_100kHz = */ 1, 88 | /* data_setup_time_ns = */ 60, /* uc1601 datasheet, page 43 */ 89 | /* write_pulse_width_ns = */ 80, /* uc1601 datasheet, page 43 */ 90 | /* tile_width = */ 16, 91 | /* tile_hight = */ 4, 92 | /* default_x_offset = */ 0, 93 | /* flipmode_x_offset = */ 4, 94 | /* pixel_width = */ 128, 95 | /* pixel_height = */ 32 96 | }; 97 | 98 | static const uint8_t u8x8_d_uc1601_128x32_init_seq[] = { 99 | 100 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 101 | 102 | U8X8_C(0x0e2), /* soft reset */ 103 | U8X8_C(0x0eb), /* LCD Bias: 0xe8: 6, 0xe9: 7, 0xea: 8, 0xeb: 9 */ 104 | //U8X8_C(0x023), /* 0x020...0x023 only for UC1601, not for UC1601s */ 105 | 106 | 107 | //U8X8_C(0x02e), /* LCD Load + Internal Charge Pump (default: 0x2e) */ 108 | U8X8_C(0x024), /* Temperature Compenstation, default: 0x24 */ 109 | U8X8_C(0x089), /* RAM address ctrl, default: 0x89 */ 110 | U8X8_C(0x0c4), /* RAM mapping ctrl */ 111 | U8X8_C(0x0a0), /* Frame Rate, 0x0a0 or 0x0a1 */ 112 | U8X8_CA(0x081, 0x0df), /* set contrast */ 113 | U8X8_C(0x02e), /* LCD Load + Internal Charge Pump (default: 0x2e) */ 114 | U8X8_C(0x060), /* set display start line to 32 */ 115 | 116 | U8X8_C(0x0a6), /* normal display */ 117 | 118 | U8X8_END_TRANSFER(), /* disable chip */ 119 | U8X8_END() /* end of sequence */ 120 | }; 121 | 122 | uint8_t u8x8_d_uc1601_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 123 | { 124 | uint8_t x, c; 125 | uint8_t *ptr; 126 | switch(msg) 127 | { 128 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 129 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1601_128x32_display_info); 130 | break; 131 | case U8X8_MSG_DISPLAY_INIT: 132 | u8x8_d_helper_display_init(u8x8); 133 | u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_init_seq); 134 | break; 135 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 136 | if ( arg_int == 0 ) 137 | u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_powersave0_seq); 138 | else 139 | u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_powersave1_seq); 140 | break; 141 | case U8X8_MSG_DISPLAY_SET_FLIP_MODE: 142 | if ( arg_int == 0 ) 143 | { 144 | u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_flip0_seq); 145 | u8x8->x_offset = u8x8->display_info->default_x_offset; 146 | } 147 | else 148 | { 149 | u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_flip1_seq); 150 | u8x8->x_offset = u8x8->display_info->flipmode_x_offset; 151 | } 152 | break; 153 | #ifdef U8X8_WITH_SET_CONTRAST 154 | case U8X8_MSG_DISPLAY_SET_CONTRAST: 155 | u8x8_cad_StartTransfer(u8x8); 156 | u8x8_cad_SendCmd(u8x8, 0x081 ); 157 | u8x8_cad_SendArg(u8x8, arg_int ); /* uc1601 has range from 0 to 255 */ 158 | u8x8_cad_EndTransfer(u8x8); 159 | break; 160 | #endif 161 | case U8X8_MSG_DISPLAY_DRAW_TILE: 162 | u8x8_cad_StartTransfer(u8x8); 163 | 164 | x = ((u8x8_tile_t *)arg_ptr)->x_pos; 165 | x *= 8; 166 | x += u8x8->x_offset; 167 | u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) ); 168 | u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15))); 169 | u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos)); 170 | 171 | c = ((u8x8_tile_t *)arg_ptr)->cnt; 172 | c *= 8; 173 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; 174 | do 175 | { 176 | u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */ 177 | arg_int--; 178 | } while( arg_int > 0 ); 179 | 180 | u8x8_cad_EndTransfer(u8x8); 181 | break; 182 | default: 183 | return 0; 184 | } 185 | return 1; 186 | } 187 | 188 | 189 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_debounce.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_debounce.c 4 | 5 | Key/button simple debounce algorithm (Addon for u8x8) 6 | 7 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 8 | 9 | Copyright (c) 2016, olikraus@gmail.com 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, this list 16 | of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright notice, this 19 | list of conditions and the following disclaimer in the documentation and/or other 20 | materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 24 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #include "u8x8.h" 39 | 40 | static uint8_t u8x8_read_pin_state(u8x8_t *u8x8) 41 | { 42 | uint8_t i; 43 | uint8_t pin_state; 44 | 45 | pin_state = 255; /* be compatible with the setup of the default pin setup, which is 255 */ 46 | for( i = 0; i < U8X8_PIN_INPUT_CNT; i++ ) 47 | { 48 | pin_state <<= 1; 49 | 50 | /* the callback function should put the return value into this variable */ 51 | u8x8->gpio_result = 1; 52 | u8x8_gpio_call(u8x8, U8X8_MSG_GPIO(i+U8X8_PIN_OUTPUT_CNT), 0); 53 | pin_state |= u8x8->gpio_result & 1; 54 | } 55 | 56 | return pin_state; 57 | } 58 | 59 | /* 60 | return 0 to U8X8_PIN_INPUT_CNT-1 if there is a difference 61 | return U8X8_PIN_INPUT_CNT if there is no difference 62 | */ 63 | static uint8_t u8x8_find_first_diff(uint8_t a, uint8_t b) 64 | { 65 | uint8_t mask; 66 | uint8_t i; 67 | mask = 1; 68 | i = U8X8_PIN_INPUT_CNT; 69 | do 70 | { 71 | i--; 72 | if ( (a & mask) != (b & mask) ) 73 | return i; 74 | mask <<= 1; 75 | } while( i > 0 ); 76 | return U8X8_PIN_INPUT_CNT; 77 | } 78 | 79 | /* 80 | State A: 81 | u8x8->debounce_last_pin_state == current_state 82 | --> State A 83 | u8x8->debounce_last_pin_state != current_state 84 | --> u8x8->debounce_last_pin_state = current_state 85 | --> State B + cnt 86 | 87 | State B + cnt 88 | --> state-- 89 | 90 | State B 91 | u8x8->debounce_last_pin_state == current_state 92 | --> keypress detected 93 | --> State C 94 | u8x8->debounce_last_pin_state != current_state 95 | --> State A 96 | 97 | State C 98 | u8x8->debounce_last_pin_state == current_state 99 | --> State C 100 | u8x8->debounce_last_pin_state != current_state 101 | --> State A 102 | 103 | */ 104 | 105 | #ifdef __unix__xxxxxx_THIS_IS_DISABLED 106 | 107 | #include 108 | #include 109 | uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8) 110 | { 111 | int c; 112 | c = getc(stdin); 113 | switch(c) 114 | { 115 | case 'n': 116 | return U8X8_MSG_GPIO_MENU_NEXT; 117 | case 'p': 118 | return U8X8_MSG_GPIO_MENU_PREV; 119 | case 's': 120 | return U8X8_MSG_GPIO_MENU_SELECT; 121 | case 'h': 122 | return U8X8_MSG_GPIO_MENU_HOME; 123 | case 'x': 124 | exit(0); 125 | default: 126 | puts("press n, p, s, h or x"); 127 | break; 128 | } 129 | return 0; 130 | } 131 | 132 | 133 | #else /* __unix__ */ 134 | 135 | 136 | #define U8X8_DEBOUNCE_WAIT 2 137 | /* do debounce and return a GPIO msg which indicates the event */ 138 | /* returns 0, if there is no event */ 139 | #if defined(__GNUC__) && !defined(__CYGWIN__) 140 | # pragma weak u8x8_GetMenuEvent 141 | #endif 142 | uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8) 143 | { 144 | uint8_t pin_state; 145 | uint8_t result_msg = 0; /* invalid message, no event */ 146 | 147 | pin_state = u8x8_read_pin_state(u8x8); 148 | 149 | /* States A, B, C & D are encoded in the upper 4 bit*/ 150 | switch(u8x8->debounce_state) 151 | { 152 | case 0x00: /* State A, default state */ 153 | if ( u8x8->debounce_default_pin_state != pin_state ) 154 | { 155 | //u8x8->debounce_last_pin_state = pin_state; 156 | u8x8->debounce_state = 0x010 + U8X8_DEBOUNCE_WAIT; 157 | } 158 | break; 159 | case 0x10: /* State B */ 160 | //if ( u8x8->debounce_last_pin_state != pin_state ) 161 | if ( u8x8->debounce_default_pin_state == pin_state ) 162 | { 163 | u8x8->debounce_state = 0x00; /* back to state A */ 164 | } 165 | else 166 | { 167 | /* keypress detected */ 168 | u8x8->debounce_last_pin_state = pin_state; 169 | //result_msg = U8X8_MSG_GPIO_MENU_NEXT; 170 | u8x8->debounce_state = 0x020 + U8X8_DEBOUNCE_WAIT; /* got to state C */ 171 | } 172 | break; 173 | 174 | case 0x20: /* State C */ 175 | if ( u8x8->debounce_last_pin_state != pin_state ) 176 | { 177 | u8x8->debounce_state = 0x00; /* back to state A */ 178 | } 179 | else 180 | { 181 | u8x8->debounce_state = 0x030; /* got to state D */ 182 | } 183 | break; 184 | 185 | case 0x30: /* State D */ 186 | /* wait until key release */ 187 | if ( u8x8->debounce_default_pin_state == pin_state ) 188 | { 189 | u8x8->debounce_state = 0x00; /* back to state A */ 190 | result_msg = U8X8_MSG_GPIO(u8x8_find_first_diff(u8x8->debounce_default_pin_state, u8x8->debounce_last_pin_state)+U8X8_PIN_OUTPUT_CNT); 191 | } 192 | else 193 | { 194 | //result_msg = U8X8_MSG_GPIO_MENU_NEXT; 195 | // maybe implement autorepeat here 196 | } 197 | break; 198 | default: 199 | u8x8->debounce_state--; /* count down, until there is a valid state */ 200 | break; 201 | } 202 | return result_msg; 203 | } 204 | 205 | #endif /* __unix__ */ 206 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_display.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_display.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | 35 | Abstraction layer for the graphics controller. 36 | Main goal is the placement of a 8x8 pixel block (tile) on the display. 37 | 38 | */ 39 | 40 | 41 | #include "u8x8.h" 42 | 43 | 44 | /*==========================================*/ 45 | /* internal library function */ 46 | 47 | /* 48 | this is a helper function for the U8X8_MSG_DISPLAY_SETUP_MEMORY function. 49 | It can be called within the display callback function to carry out the usual standard tasks. 50 | 51 | */ 52 | void u8x8_d_helper_display_setup_memory(u8x8_t *u8x8, const u8x8_display_info_t *display_info) 53 | { 54 | /* 1) set display info struct */ 55 | u8x8->display_info = display_info; 56 | u8x8->x_offset = u8x8->display_info->default_x_offset; 57 | } 58 | 59 | /* 60 | this is a helper function for the U8X8_MSG_DISPLAY_INIT function. 61 | It can be called within the display callback function to carry out the usual standard tasks. 62 | 63 | */ 64 | void u8x8_d_helper_display_init(u8x8_t *u8x8) 65 | { 66 | /* 2) apply port directions to the GPIO lines and apply default values for the IO lines*/ 67 | u8x8_gpio_Init(u8x8); 68 | u8x8_cad_Init(u8x8); 69 | 70 | /* 3) do reset */ 71 | u8x8_gpio_SetReset(u8x8, 1); 72 | u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms); 73 | u8x8_gpio_SetReset(u8x8, 0); 74 | u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms); 75 | u8x8_gpio_SetReset(u8x8, 1); 76 | u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->post_reset_wait_ms); 77 | } 78 | 79 | /*==========================================*/ 80 | /* official functions */ 81 | 82 | uint8_t u8x8_DrawTile(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr) 83 | { 84 | u8x8_tile_t tile; 85 | tile.x_pos = x; 86 | tile.y_pos = y; 87 | tile.cnt = cnt; 88 | tile.tile_ptr = tile_ptr; 89 | return u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, 1, (void *)&tile); 90 | } 91 | 92 | /* should be implemented as macro */ 93 | void u8x8_SetupMemory(u8x8_t *u8x8) 94 | { 95 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SETUP_MEMORY, 0, NULL); 96 | } 97 | 98 | void u8x8_InitDisplay(u8x8_t *u8x8) 99 | { 100 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL); 101 | } 102 | 103 | void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable) 104 | { 105 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_POWER_SAVE, is_enable, NULL); 106 | } 107 | 108 | void u8x8_SetFlipMode(u8x8_t *u8x8, uint8_t mode) 109 | { 110 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_FLIP_MODE, mode, NULL); 111 | } 112 | 113 | void u8x8_SetContrast(u8x8_t *u8x8, uint8_t value) 114 | { 115 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_CONTRAST, value, NULL); 116 | } 117 | 118 | void u8x8_RefreshDisplay(u8x8_t *u8x8) 119 | { 120 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_REFRESH, 0, NULL); 121 | } 122 | 123 | void u8x8_ClearDisplayWithTile(u8x8_t *u8x8, const uint8_t *buf) 124 | { 125 | u8x8_tile_t tile; 126 | uint8_t h; 127 | 128 | tile.x_pos = 0; 129 | tile.cnt = 1; 130 | tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */ 131 | 132 | h = u8x8->display_info->tile_height; 133 | tile.y_pos = 0; 134 | do 135 | { 136 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile); 137 | tile.y_pos++; 138 | } while( tile.y_pos < h ); 139 | } 140 | 141 | void u8x8_ClearDisplay(u8x8_t *u8x8) 142 | { 143 | uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 144 | u8x8_ClearDisplayWithTile(u8x8, buf); 145 | } 146 | 147 | void u8x8_FillDisplay(u8x8_t *u8x8) 148 | { 149 | uint8_t buf[8] = { 255, 255, 255, 255, 255, 255, 255, 255 }; 150 | u8x8_ClearDisplayWithTile(u8x8, buf); 151 | } 152 | 153 | void u8x8_ClearLine(u8x8_t *u8x8, uint8_t line) 154 | { 155 | uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 156 | u8x8_tile_t tile; 157 | if ( line < u8x8->display_info->tile_height ) 158 | { 159 | tile.x_pos = 0; 160 | tile.y_pos = line; 161 | tile.cnt = 1; 162 | tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */ 163 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile); 164 | } 165 | } -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_fonts.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Drivers/u8g2/Src/u8x8_fonts.c -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_gpio.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_gpio.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | 37 | #include "u8x8.h" 38 | 39 | 40 | void u8x8_gpio_call(u8x8_t *u8x8, uint8_t msg, uint8_t arg) 41 | { 42 | u8x8->gpio_and_delay_cb(u8x8, msg, arg, NULL); 43 | } 44 | 45 | /* 46 | void u8x8_gpio_Delay(u8x8_t *u8x8, uint8_t msg, uint8_t dly) 47 | { 48 | u8x8->gpio_and_delay_cb(u8x8, msg, dly, NULL); 49 | } 50 | */ -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_input_value.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_input_value.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8x8.h" 37 | 38 | /* 39 | return: 40 | 0: value is not changed (HOME/Break Button pressed) 41 | 1: value has been updated 42 | */ 43 | 44 | uint8_t u8x8_UserInterfaceInputValue(u8x8_t *u8x8, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post) 45 | { 46 | uint8_t height; 47 | uint8_t y; 48 | uint8_t width; 49 | uint8_t x; 50 | uint8_t local_value = *value; 51 | uint8_t r; 52 | uint8_t event; 53 | 54 | /* calculate overall height of the input value box */ 55 | height = 1; /* button line */ 56 | height += u8x8_GetStringLineCnt(title); 57 | 58 | /* calculate offset from top */ 59 | y = 0; 60 | if ( height < u8x8_GetRows(u8x8) ) 61 | { 62 | y = u8x8_GetRows(u8x8); 63 | y -= height; 64 | y /= 2; 65 | } 66 | 67 | /* calculate offset from left for the label */ 68 | x = 0; 69 | width = u8x8_GetUTF8Len(u8x8, pre); 70 | width += digits; 71 | width += u8x8_GetUTF8Len(u8x8, post); 72 | if ( width < u8x8_GetCols(u8x8) ) 73 | { 74 | x = u8x8_GetCols(u8x8); 75 | x -= width; 76 | x /= 2; 77 | } 78 | 79 | /* render */ 80 | u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */ 81 | u8x8_SetInverseFont(u8x8, 0); 82 | y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title); 83 | x += u8x8_DrawUTF8(u8x8, x, y, pre); 84 | u8x8_DrawUTF8(u8x8, x+digits, y, post); 85 | u8x8_SetInverseFont(u8x8, 1); 86 | 87 | /* event loop */ 88 | u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits)); 89 | for(;;) 90 | { 91 | event = u8x8_GetMenuEvent(u8x8); 92 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 93 | { 94 | *value = local_value; 95 | r = 1; 96 | break; 97 | } 98 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 99 | { 100 | r = 0; 101 | break; 102 | } 103 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP ) 104 | { 105 | if ( local_value >= hi ) 106 | local_value = lo; 107 | else 108 | local_value++; 109 | u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits)); 110 | } 111 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN ) 112 | { 113 | if ( local_value <= lo ) 114 | local_value = hi; 115 | else 116 | local_value--; 117 | u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits)); 118 | } 119 | } 120 | 121 | u8x8_SetInverseFont(u8x8, 0); 122 | return r; 123 | } 124 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_message.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_message.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8x8.h" 37 | 38 | uint8_t u8x8_draw_button_line(u8x8_t *u8x8, uint8_t y, uint8_t w, uint8_t cursor, const char *s) 39 | { 40 | uint8_t i; 41 | uint8_t cnt; 42 | uint8_t total; 43 | uint8_t d; 44 | uint8_t x; 45 | cnt = u8x8_GetStringLineCnt(s); 46 | 47 | /* calculate the width of the button */ 48 | total = 0; 49 | for( i = 0; i < cnt; i++ ) 50 | { 51 | total += u8x8_GetUTF8Len(u8x8, u8x8_GetStringLineStart(i, s)); 52 | } 53 | total += (cnt-1); /* had one space between the buttons */ 54 | 55 | /* calculate the left offset */ 56 | d = 0; 57 | if ( total < w ) 58 | { 59 | d = w; 60 | d -= total; 61 | d /= 2; 62 | } 63 | 64 | /* draw the buttons */ 65 | x = d; 66 | u8x8_SetInverseFont(u8x8, 0); 67 | for( i = 0; i < cnt; i++ ) 68 | { 69 | if ( i == cursor ) 70 | u8x8_SetInverseFont(u8x8, 1); 71 | 72 | x+=u8x8_DrawUTF8(u8x8, x, y, u8x8_GetStringLineStart(i, s)); 73 | u8x8_SetInverseFont(u8x8, 0); 74 | x+=u8x8_DrawUTF8(u8x8, x, y, " "); 75 | } 76 | 77 | /* return the number of buttons */ 78 | return cnt; 79 | } 80 | 81 | /* 82 | title1: Multiple lines,separated by '\n' 83 | title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart() 84 | title3: Multiple lines,separated by '\n' 85 | buttons: one more more buttons separated by '\n' and terminated with '\0' 86 | */ 87 | 88 | uint8_t u8x8_UserInterfaceMessage(u8x8_t *u8x8, const char *title1, const char *title2, const char *title3, const char *buttons) 89 | { 90 | uint8_t height; 91 | uint8_t y; 92 | uint8_t cursor = 0; 93 | uint8_t button_cnt; 94 | uint8_t event; 95 | 96 | u8x8_SetInverseFont(u8x8, 0); 97 | 98 | /* calculate overall height of the message box */ 99 | height = 1; /* button line */ 100 | height += u8x8_GetStringLineCnt(title1); 101 | if ( title2 != NULL ) 102 | height ++; 103 | height += u8x8_GetStringLineCnt(title3); 104 | 105 | /* calculate offset from top */ 106 | y = 0; 107 | if ( height < u8x8_GetRows(u8x8) ) 108 | { 109 | y = u8x8_GetRows(u8x8); 110 | y -= height; 111 | y /= 2; 112 | } 113 | 114 | /* draw message box */ 115 | 116 | u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */ 117 | 118 | y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title1); 119 | if ( title2 != NULL ) 120 | { 121 | u8x8_DrawUTF8Line(u8x8, 0, y, u8x8_GetCols(u8x8), title2); 122 | y++; 123 | } 124 | y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title3); 125 | 126 | button_cnt = u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons); 127 | 128 | for(;;) 129 | { 130 | event = u8x8_GetMenuEvent(u8x8); 131 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 132 | return cursor+1; 133 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 134 | break; 135 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP ) 136 | { 137 | cursor++; 138 | if ( cursor >= button_cnt ) 139 | cursor = 0; 140 | u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons); 141 | } 142 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN ) 143 | { 144 | if ( cursor == 0 ) 145 | cursor = button_cnt; 146 | cursor--; 147 | u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons); 148 | } 149 | } 150 | return 0; 151 | } 152 | 153 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_selection_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_selection_list.c 4 | 5 | selection list with scroll option 6 | 7 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 8 | 9 | Copyright (c) 2016, olikraus@gmail.com 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, this list 16 | of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright notice, this 19 | list of conditions and the following disclaimer in the documentation and/or other 20 | materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 24 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #include "u8x8.h" 39 | 40 | /* 41 | increase the cursor position 42 | */ 43 | void u8sl_Next(u8sl_t *u8sl) 44 | { 45 | u8sl->current_pos++; 46 | if ( u8sl->current_pos >= u8sl->total ) 47 | { 48 | u8sl->current_pos = 0; 49 | u8sl->first_pos = 0; 50 | } 51 | else 52 | { 53 | if ( u8sl->first_pos + u8sl->visible <= u8sl->current_pos + 1 ) 54 | { 55 | u8sl->first_pos = u8sl->current_pos - u8sl->visible + 1; 56 | } 57 | } 58 | } 59 | 60 | void u8sl_Prev(u8sl_t *u8sl) 61 | { 62 | if ( u8sl->current_pos == 0 ) 63 | { 64 | u8sl->current_pos = u8sl->total - 1; 65 | u8sl->first_pos = 0; 66 | if ( u8sl->total > u8sl->visible ) 67 | u8sl->first_pos = u8sl->total - u8sl->visible; 68 | } 69 | else 70 | { 71 | u8sl->current_pos--; 72 | if ( u8sl->first_pos > u8sl->current_pos ) 73 | u8sl->first_pos = u8sl->current_pos; 74 | } 75 | } 76 | 77 | void u8x8_DrawSelectionList(u8x8_t *u8x8, u8sl_t *u8sl, u8x8_sl_cb sl_cb, const void *aux) 78 | { 79 | uint8_t i; 80 | for( i = 0; i < u8sl->visible; i++ ) 81 | { 82 | sl_cb(u8x8, u8sl, i+u8sl->first_pos, aux); 83 | } 84 | } 85 | 86 | /* selection list with string line */ 87 | void u8x8_sl_string_line_cb(u8x8_t *u8x8, u8sl_t *u8sl, uint8_t idx, const void *aux) 88 | { 89 | const char *s; 90 | uint8_t row; 91 | /* calculate offset from display upper border */ 92 | row = u8sl->y; 93 | 94 | /* calculate target pos */ 95 | row += idx; 96 | row -= u8sl->first_pos; 97 | 98 | /* check whether this is the current cursor line */ 99 | if ( idx == u8sl->current_pos ) 100 | u8x8_SetInverseFont(u8x8, 1); 101 | else 102 | u8x8_SetInverseFont(u8x8, 0); 103 | 104 | /* get the line from the array */ 105 | s = u8x8_GetStringLineStart(idx, (const char *)aux); 106 | 107 | /* draw the line */ 108 | if ( s == NULL ) 109 | s = ""; 110 | u8x8_DrawUTF8Line(u8x8, u8sl->x, row, u8x8_GetCols(u8x8), s); 111 | u8x8_SetInverseFont(u8x8, 0); 112 | } 113 | 114 | /* 115 | title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n' 116 | start_pos: default position for the cursor (starts with 1) 117 | sl: string list (list of strings separated by \n) 118 | returns 0 if user has pressed the home key 119 | returns the selected line+1 if user has pressed the select key (e.g. 1 for the first line) 120 | */ 121 | uint8_t u8x8_UserInterfaceSelectionList(u8x8_t *u8x8, const char *title, uint8_t start_pos, const char *sl) 122 | { 123 | u8sl_t u8sl; 124 | uint8_t event; 125 | uint8_t title_lines; 126 | 127 | if ( start_pos > 0 ) 128 | start_pos--; 129 | 130 | u8sl.visible = u8x8_GetRows(u8x8); 131 | u8sl.total = u8x8_GetStringLineCnt(sl); 132 | u8sl.first_pos = 0; 133 | u8sl.current_pos = start_pos; 134 | u8sl.x = 0; 135 | u8sl.y = 0; 136 | 137 | 138 | //u8x8_ClearDisplay(u8x8); /* not required because all is 100% filled */ 139 | u8x8_SetInverseFont(u8x8, 0); 140 | 141 | if ( title != NULL ) 142 | { 143 | title_lines = u8x8_DrawUTF8Lines(u8x8, u8sl.x, u8sl.y, u8x8_GetCols(u8x8), title); 144 | u8sl.y+=title_lines; 145 | u8sl.visible-=title_lines; 146 | } 147 | 148 | if ( u8sl.current_pos >= u8sl.total ) 149 | u8sl.current_pos = u8sl.total-1; 150 | 151 | 152 | u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl); 153 | 154 | for(;;) 155 | { 156 | event = u8x8_GetMenuEvent(u8x8); 157 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 158 | return u8sl.current_pos+1; 159 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 160 | return 0; 161 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN ) 162 | { 163 | u8sl_Next(&u8sl); 164 | u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl); 165 | } 166 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP ) 167 | { 168 | u8sl_Prev(&u8sl); 169 | u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl); 170 | } 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_setup.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_setup.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | 37 | #include "u8x8.h" 38 | 39 | /* universal dummy callback, which will be default for all callbacks */ 40 | uint8_t u8x8_dummy_cb(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr) 41 | { 42 | /* the dummy callback will not handle any message and will fail for all messages */ 43 | return 0; 44 | } 45 | 46 | 47 | static const u8x8_display_info_t u8x8_null_display_info = 48 | { 49 | /* chip_enable_level = */ 0, 50 | /* chip_disable_level = */ 1, 51 | 52 | /* post_chip_enable_wait_ns = */ 0, 53 | /* pre_chip_disable_wait_ns = */ 0, 54 | /* reset_pulse_width_ms = */ 0, 55 | /* post_reset_wait_ms = */ 0, 56 | /* sda_setup_time_ns = */ 0, 57 | /* sck_pulse_width_ns = */ 0, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */ 58 | /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 59 | /* spi_mode = */ 0, /* active high, rising edge */ 60 | /* i2c_bus_clock_100kHz = */ 4, 61 | /* data_setup_time_ns = */ 0, 62 | /* write_pulse_width_ns = */ 0, 63 | /* tile_width = */ 1, /* 8x8 */ 64 | /* tile_hight = */ 1, 65 | /* default_x_offset = */ 0, 66 | /* flipmode_x_offset = */ 0, 67 | /* pixel_width = */ 8, 68 | /* pixel_height = */ 8 69 | }; 70 | 71 | 72 | /* a special null device */ 73 | uint8_t u8x8_d_null_cb(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr) 74 | { 75 | switch(msg) 76 | { 77 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 78 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_null_display_info); 79 | break; 80 | case U8X8_MSG_DISPLAY_INIT: 81 | u8x8_d_helper_display_init(u8x8); 82 | break; 83 | } 84 | /* the null device callback will succeed for all messages */ 85 | return 1; 86 | } 87 | 88 | 89 | /* 90 | Description: 91 | Setup u8x8 92 | Args: 93 | u8x8 An empty u8x8 structure 94 | */ 95 | void u8x8_SetupDefaults(u8x8_t *u8x8) 96 | { 97 | u8x8->display_info = NULL; 98 | u8x8->display_cb = u8x8_dummy_cb; 99 | u8x8->cad_cb = u8x8_dummy_cb; 100 | u8x8->byte_cb = u8x8_dummy_cb; 101 | u8x8->gpio_and_delay_cb = u8x8_dummy_cb; 102 | u8x8->is_font_inverse_mode = 0; 103 | u8x8->device_address = 0; 104 | u8x8->utf8_state = 0; /* also reset by u8x8_utf8_init */ 105 | u8x8->bus_clock = 0; /* issue 769 */ 106 | u8x8->i2c_address = 255; 107 | u8x8->debounce_default_pin_state = 255; /* assume all low active buttons */ 108 | 109 | #ifdef U8X8_USE_PINS 110 | { 111 | uint8_t i; 112 | for( i = 0; i < U8X8_PIN_CNT; i++ ) 113 | u8x8->pins[i] = U8X8_PIN_NONE; 114 | } 115 | #endif 116 | } 117 | 118 | 119 | /* 120 | Description: 121 | Setup u8x8 and assign the callback function. The dummy 122 | callback "u8x8_dummy_cb" can be used, if no callback is required. 123 | This setup will not communicate with the display itself. 124 | Use u8x8_InitDisplay() to send the startup code to the Display. 125 | Args: 126 | u8x8 An empty u8x8 structure 127 | display_cb Display/controller specific callback function 128 | cad_cb Display controller specific communication callback function 129 | byte_cb Display controller/communication specific callback funtion 130 | gpio_and_delay_cb Environment specific callback function 131 | 132 | */ 133 | void u8x8_Setup(u8x8_t *u8x8, u8x8_msg_cb display_cb, u8x8_msg_cb cad_cb, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) 134 | { 135 | /* setup defaults and reset pins to U8X8_PIN_NONE */ 136 | u8x8_SetupDefaults(u8x8); 137 | 138 | /* setup specific callbacks */ 139 | u8x8->display_cb = display_cb; 140 | u8x8->cad_cb = cad_cb; 141 | u8x8->byte_cb = byte_cb; 142 | u8x8->gpio_and_delay_cb = gpio_and_delay_cb; 143 | 144 | /* setup display info */ 145 | u8x8_SetupMemory(u8x8); 146 | } 147 | 148 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_string.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_string.c 4 | 5 | string line procedures 6 | 7 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 8 | 9 | Copyright (c) 2016, olikraus@gmail.com 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, this list 16 | of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright notice, this 19 | list of conditions and the following disclaimer in the documentation and/or other 20 | materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 24 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #include "u8x8.h" 39 | 40 | uint8_t u8x8_GetStringLineCnt(const char *str) 41 | { 42 | char e; 43 | uint8_t line_cnt = 1; 44 | if ( str == NULL ) 45 | return 0; 46 | for(;;) 47 | { 48 | e = *str; 49 | if ( e == '\0' ) 50 | break; 51 | str++; 52 | if ( e == '\n' ) 53 | line_cnt++; 54 | } 55 | return line_cnt; 56 | } 57 | 58 | 59 | /* 60 | Assumes strings, separated by '\n' in "str". 61 | Returns the string at index "line_idx". First strng has line_idx = 0 62 | Example: 63 | Returns "xyz" for line_idx = 1 with str = "abc\nxyz" 64 | Support both UTF8 and normal strings. 65 | */ 66 | const char *u8x8_GetStringLineStart(uint8_t line_idx, const char *str ) 67 | { 68 | char e; 69 | uint8_t line_cnt = 1; 70 | 71 | if ( line_idx == 0 ) 72 | return str; 73 | 74 | for(;;) 75 | { 76 | e = *str; 77 | if ( e == '\0' ) 78 | break; 79 | str++; 80 | if ( e == '\n' ) 81 | { 82 | if ( line_cnt == line_idx ) 83 | return str; 84 | line_cnt++; 85 | } 86 | } 87 | return NULL; /* line not found */ 88 | } 89 | 90 | /* copy until first '\n' or '\0' in str */ 91 | /* Important: There is no string overflow check, ensure */ 92 | /* that the destination buffer is large enough */ 93 | void u8x8_CopyStringLine(char *dest, uint8_t line_idx, const char *str) 94 | { 95 | if ( dest == NULL ) 96 | return; 97 | str = u8x8_GetStringLineStart( line_idx, str ); 98 | if ( str != NULL ) 99 | { 100 | for(;;) 101 | { 102 | if ( *str == '\n' || *str == '\0' ) 103 | break; 104 | *dest = *str; 105 | dest++; 106 | str++; 107 | } 108 | } 109 | *dest = '\0'; 110 | } 111 | 112 | /* 113 | Draw a string 114 | Extend the string to size "w" 115 | Center the string within "w" 116 | return the size of the string 117 | 118 | */ 119 | uint8_t u8x8_DrawUTF8Line(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s) 120 | { 121 | uint8_t d, lw; 122 | uint8_t cx, dx; 123 | 124 | d = 0; 125 | 126 | lw = u8x8_GetUTF8Len(u8x8, s); 127 | if ( lw < w ) 128 | { 129 | d = w; 130 | d -=lw; 131 | d /= 2; 132 | } 133 | 134 | cx = x; 135 | dx = cx + d; 136 | while( cx < dx ) 137 | { 138 | u8x8_DrawUTF8(u8x8, cx, y, " "); 139 | cx++; 140 | } 141 | cx += u8x8_DrawUTF8(u8x8, cx, y, s); 142 | dx = x + w; 143 | while( cx < dx ) 144 | { 145 | u8x8_DrawUTF8(u8x8, cx, y, " "); 146 | cx++; 147 | } 148 | cx -= x; 149 | return cx; 150 | } 151 | 152 | /* 153 | draw several lines at position x,y. 154 | lines are stored in s and must be separated with '\n'. 155 | lines can be centered with respect to "w" 156 | if s == NULL nothing is drawn and 0 is returned 157 | returns the number of lines in s 158 | */ 159 | uint8_t u8x8_DrawUTF8Lines(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s) 160 | { 161 | uint8_t i; 162 | uint8_t cnt; 163 | cnt = u8x8_GetStringLineCnt(s); 164 | for( i = 0; i < cnt; i++ ) 165 | { 166 | u8x8_DrawUTF8Line(u8x8, x, y, w, u8x8_GetStringLineStart(i, s)); 167 | y++; 168 | } 169 | return cnt; 170 | } 171 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_u16toa.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_u16toa.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | 35 | */ 36 | 37 | 38 | #include "u8x8.h" 39 | 40 | const char *u8x8_u16toap(char * dest, uint16_t v) 41 | { 42 | uint8_t pos; 43 | uint8_t d; 44 | uint16_t c; 45 | c = 10000; 46 | for( pos = 0; pos < 5; pos++ ) 47 | { 48 | d = '0'; 49 | while( v >= c ) 50 | { 51 | v -= c; 52 | d++; 53 | } 54 | dest[pos] = d; 55 | c /= 10; 56 | } 57 | dest[5] = '\0'; 58 | return dest; 59 | } 60 | 61 | /* v = value, d = number of digits */ 62 | const char *u8x8_u16toa(uint16_t v, uint8_t d) 63 | { 64 | static char buf[6]; 65 | d = 5-d; 66 | return u8x8_u16toap(buf, v) + d; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /Drivers/u8g2/Src/u8x8_u8toa.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_u8toa.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | 37 | #include "u8x8.h" 38 | 39 | static const unsigned char u8x8_u8toa_tab[3] = { 100, 10, 1 } ; 40 | const char *u8x8_u8toap(char * dest, uint8_t v) 41 | { 42 | uint8_t pos; 43 | uint8_t d; 44 | uint8_t c; 45 | for( pos = 0; pos < 3; pos++ ) 46 | { 47 | d = '0'; 48 | c = *(u8x8_u8toa_tab+pos); 49 | while( v >= c ) 50 | { 51 | v -= c; 52 | d++; 53 | } 54 | dest[pos] = d; 55 | } 56 | dest[3] = '\0'; 57 | return dest; 58 | } 59 | 60 | /* v = value, d = number of digits */ 61 | const char *u8x8_u8toa(uint8_t v, uint8_t d) 62 | { 63 | static char buf[4]; 64 | d = 3-d; 65 | return u8x8_u8toap(buf, v) + d; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /Inc/buzzer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Inc/buzzer.h -------------------------------------------------------------------------------- /Inc/cfgtypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cfgtypes.h 3 | * 4 | * Created on: 15 aug. 2019 5 | * Author: Alex 6 | */ 7 | 8 | #ifndef CFGTYPES_H_ 9 | #define CFGTYPES_H_ 10 | #include "iron_tips.h" 11 | 12 | /* 13 | * The configuration bit map: 14 | * CFG_CELSIUS - The temperature units: Celsius (1) or Fahrenheit (0) 15 | * CFG_BUZZER - Is the Buzzer Enabled (1) 16 | * CFG_KEEP_IRON - Is keep the iron working while in Hot Air Gun mode 17 | * CFG_SWITCH - Switch type: Tilt (0) or REED (1) 18 | */ 19 | typedef enum { CFG_CELSIUS = 1, CFG_BUZZER = 2, CFG_KEEP_IRON = 4, CFG_SWITCH = 8, CFG_AU_START = 16, CFG_BIG_STEP = 128 } CFG_BIT_MASK; 20 | 21 | /* Configuration record in the EEPROM (after the tip table) has the following format: 22 | * Records are aligned by 2**n bytes (in this case, 32 bytes) 23 | * 24 | * Boost is a bit map. The upper 4 bits are boost increment temperature (n*5 Celsius), i.e. 25 | * 0000 - disabled 26 | * 0001 - +4 degrees 27 | * 1111 - +75 degrees 28 | * The lower 4 bits is the boost time ((n+1)* 20 seconds), i.e. 29 | * 0000 - 20 seconds 30 | * 0001 - 40 seconds 31 | * 1111 - 320 seconds 32 | */ 33 | typedef struct s_config RECORD; 34 | struct s_config { 35 | uint32_t ID; // The configuration record ID 36 | uint16_t crc; // The checksum 37 | uint16_t iron_temp; // The IRON preset temperature in degrees (Celsius or Fahrenheit) 38 | uint16_t gun_temp; // The Hot Air Gun preset temperature in degrees (Celsius or Fahrenheit) 39 | uint16_t gun_fan_speed; // The Hot Air Gun fan speed 40 | uint16_t iron_Kp, iron_Ki, iron_Kd; // The IRON PID coefficients 41 | uint16_t gun_Kp, gun_Ki, gun_Kd; // The Hot Air Gun PID coefficients 42 | uint16_t low_temp; // The low power temperature (C) or 0 if the tilt sensor is disabled 43 | uint8_t low_to; // The low power timeout (5 seconds intervals) 44 | uint8_t scr_save_timeout; // The screen saver timeout (in minutes) [0-60]. Zero if disabled 45 | uint8_t boost; // Two 4-bits parameters: The boost increment temperature and boost time. See description above 46 | uint8_t tip; // Current tip index 47 | uint8_t off_timeout; // The Automatic switch-off timeout in minutes [0 - 30] 48 | uint8_t bit_mask; // See CFG_BIT_MASK 49 | }; 50 | 51 | /* Configuration data of each initialized tip are saved in the upper area of the EEPROM. 52 | * Two tip record per one EEPROM chunk, as soon each tip recored requires 16 bytes only. 53 | * The tip configuration record has the following format: 54 | * 4 reference temperature points 55 | * tip status bitmap 56 | * tip suffix name 57 | */ 58 | 59 | typedef struct s_tip TIP; 60 | struct s_tip { 61 | uint16_t t200, t260, t330, t400; // The internal temperature in reference points 62 | uint8_t mask; // The bit mask: TIP_ACTIVE + TIP_CALIBRATED 63 | char name[tip_name_sz]; // T12 tip name suffix, JL02 for T12-JL02 64 | int8_t ambient; // The ambient temperature in Celsius when the tip being calibrated 65 | uint8_t crc; // CRC checksum 66 | }; 67 | 68 | // This tip structure is used to show available tips when tip is activating 69 | typedef struct s_tip_list_item TIP_ITEM; 70 | struct s_tip_list_item { 71 | uint8_t tip_index; // Index of the tip in the global list in EEPROM 72 | uint8_t mask; // The bit mask: 0 - active, 1 - calibrated 73 | char name[tip_name_sz+5]; // Complete tip name, i.e. T12-*** 74 | }; 75 | 76 | /* 77 | * This structure presents a tip record for all possible tips, declared in iron_tips.c 78 | * During controller initialization phase, the buildTipTable() function creates 79 | * the tip list in memory of all possible tips. If the tip is calibrated, i.e. has a record 80 | * in the upper area of EEPROM, the tip record saves chunk number, where the calibration data resides 81 | */ 82 | typedef struct s_tip_table TIP_TABLE; 83 | struct s_tip_table { 84 | uint8_t tip_chunk_index; // The tip chunk index in the EEPROM 85 | uint8_t tip_mask; // The bit mask: 0 - active, 1 - calibrated 86 | }; 87 | 88 | typedef enum tip_status { TIP_ACTIVE = 1, TIP_CALIBRATED = 2 } TIP_STATUS; 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /Inc/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * config.h 3 | * 4 | * Created on: 15 aug. 2019. 5 | * Author: Alex 6 | */ 7 | 8 | #ifndef CONFIG_H_ 9 | #define CONFIG_H_ 10 | #include "main.h" 11 | #include "pid.h" 12 | #include "eeprom.h" 13 | #include "cfgtypes.h" 14 | #include "iron_tips.h" 15 | #include "pid.h" 16 | #include "buzzer.h" 17 | 18 | typedef enum cfg_status {CFG_OK = 0, CFG_NO_TIP, CFG_READ_ERROR} CFG_STATUS; 19 | typedef enum temp_force {DEV_DEFAULT = 0, DEV_IRON = 1, DEV_GUN = 2} CFG_TEMP_DEVICE; 20 | 21 | /* 22 | * The actual configuration record is loaded from the EEPROM chunk into a_cfg variable 23 | * The spare copy of the configuration record is preserved into s_cfg variable 24 | * When update request arrives, configuration record writes into EEPROM if spare copy is different from actual copy 25 | */ 26 | class CFG_CORE: public TIPS { 27 | public: 28 | CFG_CORE(void) { } 29 | bool isCelsius(void) { return a_cfg.bit_mask & CFG_CELSIUS; } 30 | bool isBuzzerEnabled(void) { return a_cfg.bit_mask & CFG_BUZZER; } 31 | bool isKeepIron(void) { return a_cfg.bit_mask & CFG_KEEP_IRON;} 32 | bool isReedType(void) { return a_cfg.bit_mask & CFG_SWITCH; } 33 | bool isBigTempStep(void) { return a_cfg.bit_mask & CFG_BIG_STEP; } 34 | bool isAutoStart(void) { return a_cfg.bit_mask & CFG_AU_START; } 35 | uint16_t tempPresetHuman(void) { return a_cfg.iron_temp; } 36 | uint16_t gunTempPreset(void) { return a_cfg.gun_temp; } 37 | uint16_t gunFanPreset(void) { return a_cfg.gun_fan_speed; } 38 | uint8_t getOffTimeout(void) { return a_cfg.off_timeout; } 39 | uint16_t getLowTemp(void) { return a_cfg.low_temp; } 40 | uint8_t getLowTO(void) { return a_cfg.low_to; } // 5-seconds intervals 41 | uint8_t getScrTo(void) { return a_cfg.scr_save_timeout; } 42 | void setup(uint8_t off_timeout, bool buzzer, bool celsius, bool keep_iron, bool reed, bool big_temp_step, bool auto_start, 43 | uint16_t low_temp, uint8_t low_to, uint8_t scr_saver); 44 | void savePresetTempHuman(uint16_t temp_set); 45 | void saveGunPreset(uint16_t temp, uint16_t fan = 0); 46 | uint8_t boostTemp(void); 47 | uint16_t boostDuration(void); 48 | void saveBoost(uint8_t temp, uint16_t duration); 49 | void restoreConfig(void); 50 | PIDparam pidParams(bool iron); 51 | PIDparam pidParamsSmooth(bool iron = true); 52 | protected: 53 | void setDefaults(void); 54 | void correctConfig(RECORD *cfg); 55 | void syncConfig(void); 56 | bool areConfigsIdentical(void); 57 | RECORD a_cfg; // active configuration 58 | private: 59 | RECORD s_cfg; // spare configuration, used when save the configuration to the EEPROM 60 | }; 61 | 62 | typedef struct s_TIP_RECORD TIP_RECORD; 63 | struct s_TIP_RECORD { 64 | uint16_t calibration[4]; 65 | uint8_t mask; 66 | int8_t ambient; 67 | }; 68 | 69 | class TIP_CFG { 70 | public: 71 | TIP_CFG(void) { } 72 | bool isTipCalibrated(void) { return tip[0].mask & TIP_CALIBRATED; } 73 | uint16_t tempMinC(void) { return t_minC; } 74 | uint16_t tempMaxC(void) { return t_maxC; } 75 | bool gunActive(void) { return gun_active; } 76 | void load(const TIP& tip, bool gun = false); 77 | void dump(TIP* tip, bool gun = false); 78 | int8_t ambientTemp(void); 79 | uint16_t calibration(uint8_t index); 80 | void activateGun(bool gun); // Activate Hot Air Gun calibration (or return to the current tip) 81 | uint16_t referenceTemp(uint8_t index, CFG_TEMP_DEVICE force_device = DEV_DEFAULT); 82 | uint16_t tempCelsius(uint16_t temp, int16_t ambient, CFG_TEMP_DEVICE force_device = DEV_DEFAULT); 83 | void getTipCalibtarion(uint16_t temp[4]); 84 | void applyTipCalibtarion(uint16_t temp[4], int8_t ambient); 85 | void resetTipCalibration(void); 86 | protected: 87 | void defaultCalibration(bool gun = false); 88 | bool isValidTipConfig(TIP *tip); 89 | private: 90 | TIP_RECORD tip[2]; // Active IRON tip (0) and Hot Air Gun virtual tip (1) 91 | uint16_t t_minC = 0; 92 | uint16_t t_maxC = 0; 93 | bool gun_active = false; // Current Working mode: Hot Air Gun or soldering IRON 94 | const uint16_t temp_ref_iron[4] = { 200, 260, 330, 400}; 95 | const uint16_t temp_ref_gun[4] = { 200, 300, 400, 500}; 96 | }; 97 | 98 | class CFG : public EEPROM, public CFG_CORE, public TIP_CFG, public BUZZER { 99 | public: 100 | CFG(I2C_HandleTypeDef* pHi2c): EEPROM(pHi2c) { } 101 | CFG_STATUS init(void); 102 | uint16_t tipChunksTotal(void); 103 | uint16_t tempToHuman(uint16_t temp, int16_t ambient, CFG_TEMP_DEVICE force_device = DEV_DEFAULT); 104 | uint16_t humanToTemp(uint16_t temp, int16_t ambient); 105 | uint16_t lowTempInternal(int16_t ambient); 106 | const char* tipName(void); 107 | void changeTip(uint8_t index); 108 | uint8_t currentTipIndex(void); 109 | void saveTipCalibtarion(uint8_t index, uint16_t temp[4], uint8_t mask, int8_t ambient); 110 | bool toggleTipActivation(uint8_t index); 111 | int tipList(uint8_t second, TIP_ITEM list[], uint8_t list_len, bool active_only); 112 | void saveConfig(void); 113 | void savePID(PIDparam &pp, bool iron = true); 114 | void initConfigArea(void); 115 | void clearAllTipsCalibration(void); 116 | private: 117 | bool selectTip(uint8_t index); 118 | uint8_t buildTipTable(TIP_TABLE tt[]); 119 | char* buildFullTipName(char tip_name[tip_name_sz], const uint8_t index); 120 | uint8_t freeTipChunkIndex(void); 121 | bool isTipCorrect(uint8_t tip_chunk_index, TIP *tip); 122 | TIP_TABLE *tip_table = 0; // Tip table - chunk number of the tip or 0xFF if does not exist in the EEPROM 123 | }; 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /Inc/core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * core.h 3 | * 4 | * Created on: 16 sep 2019 5 | * Author: Alex 6 | */ 7 | 8 | #ifndef CORE_H_ 9 | #define CORE_H_ 10 | 11 | #include "main.h" 12 | 13 | #ifndef __cplusplus 14 | typedef uint8_t bool; 15 | #endif 16 | 17 | // Forward function declaration 18 | bool isACsine(void); 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | void setup(void); 25 | void loop(void); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Inc/display.h: -------------------------------------------------------------------------------- 1 | /* 2 | * display.h 3 | * 4 | */ 5 | 6 | #ifndef DISPLAY_H_ 7 | #define DISPLAY_H_ 8 | 9 | #include "main.h" 10 | #include "oled.h" 11 | #include "config.h" 12 | 13 | typedef enum { SCR_MODE_OFF = 0, SCR_MODE_IRON_ON, SCR_MODE_IRON_STBY, SCR_MODE_GUN_ON } SCR_MODE; 14 | 15 | const uint16_t d_width = 128; // display width 16 | const uint16_t d_height = 64; // display height 17 | 18 | class DSPL : public U8G2 { 19 | public: 20 | DSPL(void) : U8G2() { } 21 | void init(void); 22 | void mainInit(void) { msg_buff[0] = tip_name[0] = 0; } 23 | void status(const char *msg); 24 | void msgClean(void); 25 | void msgOFF(void); 26 | void msgON(void); 27 | void msgCold(void); 28 | void msgReady(void); 29 | void msgIdle(void); 30 | void msgStandby(void); 31 | void msgBoost(void); 32 | void timeToOff(uint8_t time); 33 | void tip(const char *tip_name); 34 | void fanSpeed(uint8_t pcnt); 35 | void pidInit(void); 36 | void pidSetLowerAxisLabel(const char *label); 37 | void pidModify(uint8_t index, uint16_t value); 38 | void autoPidInfo(const char *message); 39 | void autoPidCurrentLoop(uint16_t loop, uint32_t period); 40 | void pidPutData(int16_t temp, uint16_t disp); 41 | void pidShowGraph(uint8_t pwr); 42 | void pidShowMenu(uint16_t pid_k[3], uint8_t index); 43 | void animateFan(uint8_t indx); 44 | void mainShow(uint16_t t_set, uint16_t t_cur, int16_t t_amb, uint8_t p_applied, 45 | bool is_celsius, bool tip_calibrated, uint16_t t_alter, uint8_t fan_index = 0, bool tilt_iron_used=false); 46 | void scrSave(SCR_MODE mode, uint16_t t_cur, uint16_t t_alter); 47 | void tuneShow(uint16_t tune_temp, uint16_t temp, uint8_t pwr_pcnt); 48 | void calibShow(const char* tip_name, uint8_t ref_point, uint16_t current_temp, 49 | uint16_t real_temp, bool celsius, uint8_t power, bool on, bool ready, uint8_t int_temp_pcnt); 50 | void calibManualShow(const char* tip_name, uint16_t ref_temp, uint16_t current_temp, 51 | uint16_t setup_temp, bool celsius, uint8_t power, bool on, bool ready); 52 | void tipListShow(const char* title, TIP_ITEM list[], uint8_t list_len, uint8_t index, bool name_only); 53 | void menuItemShow(const char* title, const char* item, const char* value, bool modify); 54 | void errorShow(void); 55 | void errorMessage(const char *msg); 56 | void debugShow(bool gun_mode, uint16_t power, bool iron, bool gun, uint16_t data[4]); 57 | void showVersion(void); 58 | private: 59 | char msg_buff[8] = {0}; // the buffer for the message in top right corner 60 | char tip_name[10] = {0}; // the buffer for tip name 61 | char err_msg[40] = {0}; // the buffer of error message 62 | // PID tune data 63 | uint32_t default_mode = 0; // The time in ms to return to the default mode 64 | char modified_value[25] = {0}; // The buffer to show current value of being modified coefficient 65 | char lower_axis[3] = {0}; // Lower axis label (2 symbols and '\0' at the end) 66 | int16_t h_temp[80] = {0}; // The temperature history data 67 | uint16_t h_disp[80] = {0}; // The dispersion history data 68 | uint8_t data_index = 0; // The index in the array to put new data 69 | bool full_buff = false; // Whether the history data buffer is full 70 | // Screen saver data 71 | uint16_t saver_center[2] = {d_width/2, d_height/2}; // Current center of the output data 72 | int8_t saver_speed[2] = {1, 1}; // Current speed of center pointer 73 | }; 74 | 75 | void DPIDK_init(void); 76 | void DPIDK_modify(uint8_t index, uint16_t value); 77 | void DPIDK_putData(int16_t temp, uint16_t disp); 78 | void DPIDK_showGraph(void); 79 | void DPIDK_showMenu(uint16_t pid_k[3], uint8_t index); 80 | 81 | void DISPL_showCalibration(const char* tip_name, uint16_t ref_temp, uint16_t current_temp, uint16_t real_temp, bool celsius, uint8_t power, bool on, bool ready); 82 | void DISPL_showCalibManual(const char* tip_name, uint16_t ref_temp, uint16_t current_temp, uint16_t setup_temp, bool celsius, uint8_t power, bool on, bool ready); 83 | void DISPL_showTipList(const char* title, TIP_ITEM list[], uint8_t list_len, uint8_t index, bool name_only); 84 | void DISPL_showMenuItem(const char* title, const char* item, const char* value, bool modify); 85 | void DISPL_showError(void); 86 | void DISPL_resetScale(void); 87 | void DDEBUG_show(int16_t delta_t, uint32_t td, uint32_t pd, int ip, int ap); 88 | #endif 89 | -------------------------------------------------------------------------------- /Inc/eeprom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * eeprom.h 3 | * 4 | * Created on: 15 aug. 2019. 5 | * Author: Alex 6 | * 7 | * The data in the EEPROM is addressed by chunks. 8 | * There are 128 chunks of 32 bytes in the EEPROM IC at24c32a. 9 | * First 64 chunks [0-63] are used to store configuration data. 10 | * One record per chunk as soon the configuration record can fit into one chunk. 11 | * To save EEPROM rewrite cycles, new record is written to the next free chunk, increasing record ID. 12 | * When the controller starts, it reads all the chunks in the configuration area and find the last record 13 | * that has the biggest record ID. 14 | * 15 | * Last 64 chunks [64-127] are used to store the tip configuration data. 16 | * As soon as tip configuration requires only 16 bytes, two records can fit to the chunk. 17 | * Only active and calibrated tips are stored in this area. 18 | * When the controller starts, it reads all the chunks in the tip area and builds tip configuration table (tip_table, see config.c). 19 | * The tip_table tip_chunk_index field is the index of the tip in tip configuration area. 20 | * index = 0 means the first (of two) record in the first tip configuration chunk (64 chunk of the EEPROM). 21 | * index = 1 means the second record record in the first tip configuration chunk (64 chunk of the EEPROM). 22 | * 23 | * For chunk manipulations two functions are used: readChunk() and writeChunk(). 24 | * These functions read and write the EEPROM chunk from/to static data buffer. 25 | * To increase performance, last read and written chunk index is stored to chunk_in_data variable. 26 | * readChunk( function returns immediately, if data in the buffer is already actual. 27 | */ 28 | 29 | #ifndef EEPROM_H_ 30 | #define EEPROM_H_ 31 | #include "main.h" 32 | #include "cfgtypes.h" 33 | 34 | typedef enum tip_io_status {EPR_OK = 0, EPR_IO, EPR_CHECKSUM, EPR_INDEX} TIP_IO_STATUS; 35 | 36 | #define eeprom_chunk_size (32) // Number of bytes in one EEPROM chunk 37 | 38 | class EEPROM { 39 | public: 40 | EEPROM(I2C_HandleTypeDef* pHi2c) { hi2c = pHi2c; } 41 | bool init(); 42 | uint16_t tipDataTotal(void); 43 | bool loadRecord(RECORD* config_record); 44 | bool saveRecord(RECORD* config_record); // Modifies the record: increment the ID and calculate CRC 45 | TIP_IO_STATUS loadTipData(TIP* tip, uint8_t tip_chunk_index); 46 | TIP_IO_STATUS saveTipData(TIP* tip, uint8_t tip_chunk_index); 47 | void clearConfigArea(void); 48 | void forceReloadChunk(void) { chunk_in_data = 65535; } 49 | private: 50 | bool readChunk(uint16_t chunk_index); 51 | bool writeChunk(uint16_t chunk_index); 52 | uint8_t CFG_checkSum(RECORD* cfg, bool write); 53 | uint8_t TIP_checkSum(TIP* tip, bool write); 54 | uint16_t requiredTipSpace(void); 55 | I2C_HandleTypeDef* hi2c = 0; 56 | bool can_write = false; // The flag indicates that data can be saved to the EEPROM 57 | uint16_t r_chunk = 0; // Chunk number of the correct record in EEPROM to be read 58 | uint16_t w_chunk = 0; // Chunk number in the EEPROM to start write new record 59 | uint8_t data[eeprom_chunk_size]; // Data buffer for one EEPROM chunk 60 | uint16_t chunk_in_data = 65535; // Current chunk number in the data buffer [0-(eeprom_chunks-1)]. For caching 61 | const uint16_t eeprom_chunks = 128; // The number of chunks in my EEPROM IC 62 | const uint16_t eeprom_address = 0x50; // AT24C32 EEPROM IC address on the I2C bus 63 | const uint16_t cfg_chunks = 64; // The space of EEPROM (in chunks) dedicated to the configuration data 64 | const uint16_t tip_chunks = 64; // The maximum number of chunks used to store the configured tips 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /Inc/encoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * encoder.h 3 | * 4 | * Created on: 15 aug. 2019. 5 | * Author: Alex 6 | */ 7 | 8 | #ifndef ENCODER_H_ 9 | #define ENCODER_H_ 10 | #include "main.h" 11 | #include "stat.h" 12 | 13 | class RENC { 14 | public: 15 | RENC(GPIO_TypeDef* aPORT, uint16_t aPIN, GPIO_TypeDef* bPORT, uint16_t bPIN); 16 | void addButton(GPIO_TypeDef* ButtonPORT, uint16_t ButtonPIN); 17 | uint8_t buttonStatus(void); 18 | bool write(int16_t initPos); 19 | void reset(int16_t initPos, int16_t low, int16_t upp, uint8_t inc, uint8_t fast_inc, bool looped); 20 | void encoderIntr(void); 21 | void setTimeout(uint16_t timeout_ms) { over_press = timeout_ms; } 22 | void setIncrement(uint8_t inc) { increment = fast_increment = inc; } 23 | uint8_t getIncrement(void) { return increment; } 24 | int16_t read(void) { return pos; } 25 | private: 26 | EMP_AVERAGE avg; // Do average the button readings to maintain the button status 27 | int16_t min_pos = 0; // Minimum value of rotary encoder 28 | int16_t max_pos = 0; // Maximum value of roraty encoder 29 | uint16_t over_press = 0; // Maximum time in ms the button can be pressed 30 | bool is_looped = false; // Whether the encoder is looped 31 | uint8_t increment = 0; // The value to add or substract for each encoder tick 32 | uint8_t fast_increment = 0; // The value to change encoder when it runs quickly 33 | volatile uint32_t rpt = 0; // Time in ms when the encoder was rotated 34 | volatile uint32_t changed = 0; // Time in ms when the value was changed 35 | volatile int16_t pos = 0; // Encoder current position 36 | volatile bool s_up = false; // The status of the secondary channel 37 | bool i_b_rel = false; // Ignore button release event 38 | bool b_on = false; // The button current position: true - pressed 39 | uint32_t bpt = 0; // Time in ms when the button was pressed (press time) 40 | uint32_t b_check = 0; // Time in ms when the button should be checked 41 | GPIO_TypeDef* b_port = 0; // The PORT of the press button 42 | GPIO_TypeDef* m_port = 0; // The PORT of the main channel 43 | GPIO_TypeDef* s_port = 0; // The PORT of the secondary channel 44 | uint16_t b_pin = 0; // The PIN number of the button 45 | uint16_t m_pin = 0; // The PIN number of the main channel 46 | uint16_t s_pin = 0; // The PIN number of the secondary channel 47 | const uint8_t trigger_on = 100; // avg limit to change button status to on 48 | const uint8_t trigger_off = 50; // avg limit to change button status to off 49 | const uint8_t avg_length = 4; // avg length 50 | const uint8_t b_check_period = 20; // The button check period, ms 51 | const uint16_t long_press = 1500; // If the button was pressed more that this timeout, we assume the long button press 52 | const uint16_t fast_timeout = 300; // Time in ms to change encoder quickly 53 | const uint16_t def_over_press = 2500; // Default value for button over press timeout (ms) 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /Inc/font.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Inc/font.h -------------------------------------------------------------------------------- /Inc/gun.h: -------------------------------------------------------------------------------- 1 | /* 2 | * gun.h 3 | * 4 | * Created on: 14 aug 2019 5 | * Author: Alex 6 | */ 7 | 8 | #ifndef GUN_H_ 9 | #define GUN_H_ 10 | 11 | #include "stat.h" 12 | #include "pid.h" 13 | #include "tools.h" 14 | #include "unit.h" 15 | 16 | #define FAN_TIM htim2 17 | extern TIM_HandleTypeDef FAN_TIM; 18 | 19 | class HOTGUN : public UNIT { 20 | public: 21 | typedef enum { POWER_OFF, POWER_HEATING, POWER_ON, POWER_FIXED, POWER_COOLING, POWER_PID_TUNE } PowerMode; 22 | HOTGUN(void) : h_power(hot_gun_hist_length), h_temp(hot_gun_hist_length) { } 23 | void init(void); 24 | virtual bool isOn(void) { return (mode == POWER_ON || mode == POWER_FIXED); } 25 | virtual uint16_t presetTemp(void) { return temp_set; } 26 | virtual uint16_t averageTemp(void) { return avg_sync_temp; } 27 | virtual uint16_t getMaxFixedPower(void) { return max_fix_power; } 28 | virtual bool isCold(void) { return h_temp.read() < temp_gun_cold; } 29 | virtual uint16_t pwrDispersion(void) { return d_power.read(); } 30 | virtual void setTemp(uint16_t temp) { temp_set = constrain(temp, 0, int_temp_max); } 31 | virtual uint16_t tmpDispersion(void) { return d_temp.read(); } 32 | virtual uint16_t avgPower(void) { return avgPowerPcnt(); } 33 | uint16_t presetFan(void) { return fan_speed; } 34 | bool isFanWorking(void) { return (fanSpeed() >= min_fan_speed); } 35 | uint16_t maxFanSpeed(void) { return max_fan_speed; } 36 | void setFan(uint16_t fan) { fan_speed = constrain(fan, min_working_fan, max_fan_speed); } 37 | void fanFixed(uint16_t fan) { TIM2->CCR2 = constrain(fan, 0, max_fan_speed);} 38 | void updateTemp(uint16_t value); 39 | uint16_t alternateTemp(void); // Current temperature or 0 if cold 40 | virtual void switchPower(bool On); 41 | virtual uint8_t avgPowerPcnt(void); 42 | uint16_t appliedPower(void); 43 | uint16_t fanSpeed(void); // Fan supplied to Fan, PWM duty 44 | virtual void fixPower(uint16_t Power); // Set the specified power to the the hot gun 45 | uint8_t presetFanPcnt(void); 46 | uint16_t power(void); // Required Hot Air Gun power to keep the preset temperature 47 | protected: 48 | void safetyRelay(bool activate); 49 | volatile uint8_t relay_ready_cnt = 0; // The relay ready counter, see HOTHUN::power() 50 | private: 51 | void shutdown(void); 52 | PowerMode mode = POWER_OFF; 53 | uint8_t fix_power = 0; // Fixed power value of the Hot Air Gun (or zero if off) 54 | bool chill = false; // Chill the Hot Air gun if it is over heating 55 | bool reach_cold_temp = true; // Flag indicating the Hot Air Gun has reached the 'temp_gun_cold' temperature 56 | uint16_t temp_set = 0; // The preset temperature of the hot air gun (internal units) 57 | uint16_t fan_speed = 0; // Preset fan speed 58 | uint32_t fan_off_time = 0; // Time when the fan should be powered off in cooling mode (ms) 59 | EMP_AVERAGE h_power; // Exponential average of applied power 60 | EMP_AVERAGE h_temp; // Exponential average of Hot Air Gun temperature 61 | EMP_AVERAGE d_power; // Exponential average of power dispersion 62 | EMP_AVERAGE d_temp; // Exponential temperature math dispersion 63 | EMP_AVERAGE zero_temp; // Exponential average of minimum (zero) temperature 64 | volatile uint16_t avg_sync_temp = 0; // Average temperature synchronized with TIM1 (used to calculate required power, see power() method) 65 | const uint8_t max_fix_power = 70; 66 | const uint8_t max_power = 99; 67 | const uint16_t min_fan_speed = 600; 68 | const uint16_t max_fan_speed = 1999; 69 | const uint16_t max_cool_fan = 1600; 70 | const uint16_t min_working_fan = 800; 71 | const uint16_t temp_gun_cold = 100; // The temperature of the cold Hot Air Gun 72 | const uint32_t fan_off_timeout = 6*60*1000;// The timeout to turn the fan off in cooling mode 73 | const uint32_t fan_extra_time = 60000; // Extra time to wait after the Hot Air Gun reaches the 'temp_gun_cold' temperature 74 | const uint16_t fan_off_value = 500; 75 | const uint16_t fan_on_value = 1000; 76 | const uint8_t sw_off_value = 30; 77 | const uint8_t sw_on_value = 60; 78 | const uint8_t sw_avg_len = 10; 79 | const uint32_t relay_activate = 1; // The relay activation delay (loops of TIM1, 1 time per second) 80 | const int32_t stable = 300000; // The power value when the Hot Gun reaches the preset temperature. Used in PID::pidStable() 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /Inc/hw.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hw.h 3 | * 4 | * Created on: 12 aug 2019 5 | * Author: Alex 6 | */ 7 | 8 | #ifndef HW_H_ 9 | #define HW_H_ 10 | 11 | #include "stat.h" 12 | #include "iron.h" 13 | #include "gun.h" 14 | #include "encoder.h" 15 | #include "display.h" 16 | #include "config.h" 17 | 18 | extern I2C_HandleTypeDef hi2c1; 19 | 20 | class SCRSAVER { 21 | public: 22 | SCRSAVER(void) { } 23 | void init(uint8_t timeout) { to = timeout; reset(); } 24 | void reset(void); 25 | bool scrSaver(void); 26 | private: 27 | uint32_t scr_save_ms = 0; // Time to switch to Screen Saver mode (if > 0, ms) 28 | uint8_t to = 0; // Timeout, minutes 29 | bool scr_saver = false; // Is the screen saver active 30 | }; 31 | 32 | class HW { 33 | public: 34 | HW(void) : cfg(&hi2c1), 35 | encoder(ENCODER_R_GPIO_Port, ENCODER_R_Pin, ENCODER_L_GPIO_Port, ENCODER_L_Pin) { } 36 | CFG_STATUS init(void); 37 | CFG cfg; 38 | DSPL dspl; 39 | IRON iron; 40 | RENC encoder; 41 | HOTGUN hotgun; 42 | BUZZER buzz; 43 | SCRSAVER scrsaver; 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /Inc/iron.h: -------------------------------------------------------------------------------- 1 | /* 2 | * iron.h 3 | * 4 | * Created on: 13 aug 2019 5 | * Author: Alex 6 | */ 7 | 8 | #ifndef IRON_H_ 9 | #define IRON_H_ 10 | 11 | #include "pid.h" 12 | #include "stat.h" 13 | #include "unit.h" 14 | 15 | class IRON : public UNIT { 16 | public: 17 | typedef enum { POWER_OFF, POWER_ON, POWER_FIXED, POWER_COOLING, POWER_PID_TUNE } PowerMode; 18 | IRON(void) { } 19 | void init(void); 20 | virtual void switchPower(bool On); 21 | virtual bool isOn(void) { return (mode == POWER_ON); } 22 | virtual uint16_t presetTemp(void) { return temp_set; } 23 | virtual uint16_t averageTemp(void) { return h_temp.read(); } 24 | virtual uint16_t tmpDispersion(void) { return d_temp.read(); } 25 | virtual uint16_t pwrDispersion(void) { return d_power.read(); } 26 | virtual uint16_t getMaxFixedPower(void) { return max_fix_power; } 27 | virtual bool isCold(void) { return (mode == POWER_OFF); } 28 | int32_t tempShortAverage(int32_t t) { return t_iron_short.average(t); } 29 | void resetShortTemp(void) { t_iron_short.reset(); } 30 | void updateAmbient(uint32_t value) { t_amb.update(value); } 31 | uint16_t ambientInternal(void) { return t_amb.read(); } 32 | bool noAmbientSensor(void) { return t_amb.read() >= max_ambient_value; } 33 | uint16_t temp(void) { return temp_curr; } 34 | int32_t ambientTemp(void); 35 | uint16_t alternateTemp(void); // Current temperature or 0 if cold 36 | virtual void setTemp(uint16_t t); // Set the temperature to be kept (internal units) 37 | virtual uint16_t avgPower(void); // Average applied power 38 | virtual uint8_t avgPowerPcnt(void); // Power applied to the IRON in percents 39 | virtual void fixPower(uint16_t Power); // Set the specified power to the the soldering IRON 40 | void adjust(uint16_t t); // Adjust preset temperature depending on ambient temperature 41 | uint16_t power(int32_t t); // Required power to keep preset temperature 42 | void reset(void); // Iron is disconnected, clear the temp history 43 | void lowPowerMode(uint16_t t); // Activate low power mode (preset temp.) To disable, use switchPower(true) 44 | private: 45 | uint16_t temp_set = 0; // The temperature that should be kept 46 | uint16_t temp_low = 0; // The temperature in low power mode (if not zero) 47 | uint16_t fix_power = 0; // Fixed power value of the IRON (or zero if off) 48 | volatile PowerMode mode = POWER_OFF; // Working mode of the IRON 49 | volatile bool chill = false; // Whether the IRON should be cooled (preset temp is lower than current) 50 | volatile uint16_t temp_curr = 0; // The actual IRON temperature 51 | EMP_AVERAGE t_iron_short; // Exponential average of the IRON temperature (short period) 52 | EMP_AVERAGE t_amb; // Exponential average of the ambient temperature 53 | EMP_AVERAGE h_power; // Exponential average of applied power 54 | EMP_AVERAGE h_temp; // Exponential average of temperature 55 | EMP_AVERAGE d_power; // Exponential average of power math dispersion 56 | EMP_AVERAGE d_temp; // Exponential temperature math dispersion 57 | const uint16_t max_power = 1999; // Maximum power to the IRON 58 | const uint16_t max_fix_power = 1000; // Maximum power in fixed power mode 59 | const uint8_t ec = 20; // Exponential average coefficient 60 | const uint16_t iron_cold = 100; // The internal temperature when the IRON is cold 61 | const uint8_t ambient_emp_coeff = 10; // Exponential average coefficient for ambient temperature 62 | const uint8_t iron_emp_coeff = 8; // Exponential average coefficient for IRON temperature 63 | const uint16_t iron_off_value = 500; 64 | const uint16_t iron_on_value = 1000; 65 | const uint8_t iron_sw_len = 3; // Exponential coefficient of current through the IRON switch 66 | const uint8_t sw_off_value = 14; 67 | const uint8_t sw_on_value = 20; 68 | const uint8_t sw_avg_len = 5; 69 | const uint8_t sw_tilt_len = 2; 70 | const uint32_t check_sw_period = 100; // Tilt switch check period, ms 71 | const uint16_t max_ambient_value = 3900; // About -30 degrees. If the soldering IRON disconnected completely, "ambient" value is greater than this 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /Inc/iron_tips.h: -------------------------------------------------------------------------------- 1 | /* 2 | * iron_tips.h 3 | * 4 | * Created on: 15 aug. 2019. 5 | * Author: Alex 6 | */ 7 | 8 | #ifndef IRON_TIPS_H_ 9 | #define IRON_TIPS_H_ 10 | #include "main.h" 11 | 12 | // The length of the tip name 13 | #define tip_name_sz (5) 14 | 15 | class TIPS { 16 | public: 17 | TIPS() { } 18 | uint16_t loaded(void); 19 | const char* name(uint8_t index); 20 | int index(const char *name); 21 | }; 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Inc/main.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file : main.h 5 | * @brief : Header for main.c file. 6 | * This file contains the common defines of the application. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2019 STMicroelectronics. 11 | * All rights reserved.

12 | * 13 | * This software component is licensed by ST under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: 16 | * opensource.org/licenses/BSD-3-Clause 17 | * 18 | ****************************************************************************** 19 | */ 20 | /* USER CODE END Header */ 21 | 22 | /* Define to prevent recursive inclusion -------------------------------------*/ 23 | #ifndef __MAIN_H 24 | #define __MAIN_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Includes ------------------------------------------------------------------*/ 31 | #include "stm32f1xx_hal.h" 32 | 33 | /* Private includes ----------------------------------------------------------*/ 34 | /* USER CODE BEGIN Includes */ 35 | 36 | /* USER CODE END Includes */ 37 | 38 | /* Exported types ------------------------------------------------------------*/ 39 | /* USER CODE BEGIN ET */ 40 | 41 | /* USER CODE END ET */ 42 | 43 | /* Exported constants --------------------------------------------------------*/ 44 | /* USER CODE BEGIN EC */ 45 | 46 | /* USER CODE END EC */ 47 | 48 | /* Exported macro ------------------------------------------------------------*/ 49 | /* USER CODE BEGIN EM */ 50 | 51 | /* USER CODE END EM */ 52 | 53 | void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); 54 | 55 | /* Exported functions prototypes ---------------------------------------------*/ 56 | void Error_Handler(void); 57 | 58 | /* USER CODE BEGIN EFP */ 59 | 60 | /* USER CODE END EFP */ 61 | 62 | /* Private defines -----------------------------------------------------------*/ 63 | #define IRON_POWER_Pin GPIO_PIN_0 64 | #define IRON_POWER_GPIO_Port GPIOA 65 | #define FAN_POWER_Pin GPIO_PIN_1 66 | #define FAN_POWER_GPIO_Port GPIOA 67 | #define IRON_CURRENT_Pin GPIO_PIN_2 68 | #define IRON_CURRENT_GPIO_Port GPIOA 69 | #define FAN_CURRENT_Pin GPIO_PIN_3 70 | #define FAN_CURRENT_GPIO_Port GPIOA 71 | #define IRON_TEMP_Pin GPIO_PIN_4 72 | #define IRON_TEMP_GPIO_Port GPIOA 73 | #define GUN_TEMP_Pin GPIO_PIN_5 74 | #define GUN_TEMP_GPIO_Port GPIOA 75 | #define AMBIENT_Pin GPIO_PIN_6 76 | #define AMBIENT_GPIO_Port GPIOA 77 | #define ENCODER_L_Pin GPIO_PIN_0 78 | #define ENCODER_L_GPIO_Port GPIOB 79 | #define ENCODER_L_EXTI_IRQn EXTI0_IRQn 80 | #define ENCODER_B_Pin GPIO_PIN_1 81 | #define ENCODER_B_GPIO_Port GPIOB 82 | #define OLED_RESET_Pin GPIO_PIN_10 83 | #define OLED_RESET_GPIO_Port GPIOB 84 | #define OLED_DC_Pin GPIO_PIN_11 85 | #define OLED_DC_GPIO_Port GPIOB 86 | #define OLED_SCK_Pin GPIO_PIN_13 87 | #define OLED_SCK_GPIO_Port GPIOB 88 | #define OLED_SDA_Pin GPIO_PIN_15 89 | #define OLED_SDA_GPIO_Port GPIOB 90 | #define GUN_REED_Pin GPIO_PIN_8 91 | #define GUN_REED_GPIO_Port GPIOA 92 | #define ENCODER_R_Pin GPIO_PIN_9 93 | #define ENCODER_R_GPIO_Port GPIOA 94 | #define OLED_CS_Pin GPIO_PIN_10 95 | #define OLED_CS_GPIO_Port GPIOA 96 | #define GUN_POWER_Pin GPIO_PIN_11 97 | #define GUN_POWER_GPIO_Port GPIOA 98 | #define AC_ZERO_Pin GPIO_PIN_12 99 | #define AC_ZERO_GPIO_Port GPIOA 100 | #define AC_RELAY_Pin GPIO_PIN_15 101 | #define AC_RELAY_GPIO_Port GPIOA 102 | #define TILT_SW_Pin GPIO_PIN_3 103 | #define TILT_SW_GPIO_Port GPIOB 104 | #define BUZZER_Pin GPIO_PIN_9 105 | #define BUZZER_GPIO_Port GPIOB 106 | 107 | /* USER CODE BEGIN Private defines */ 108 | #define FW_VERSION ("4.08") 109 | 110 | /* USER CODE END Private defines */ 111 | 112 | #ifdef __cplusplus 113 | } 114 | #endif 115 | 116 | #endif /* __MAIN_H */ 117 | -------------------------------------------------------------------------------- /Inc/myU8g2lib.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Inc/myU8g2lib.h -------------------------------------------------------------------------------- /Inc/oled.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Inc/oled.h -------------------------------------------------------------------------------- /Inc/pid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pid.h 3 | * 4 | * Created on: 13 ���. 2019 �. 5 | * Author: Alex 6 | */ 7 | 8 | #ifndef _PID_H 9 | #define _PID_H 10 | 11 | #include "main.h" 12 | #include "stat.h" 13 | #include "vars.h" 14 | 15 | class PIDparam { 16 | public: 17 | PIDparam(int32_t Kp = 0, int32_t Ki = 0, int32_t Kd = 0); 18 | PIDparam(const PIDparam &p); 19 | int32_t Kp = 0; 20 | int32_t Ki = 0; 21 | int32_t Kd = 0; 22 | }; 23 | 24 | 25 | /* The PID algorithm 26 | * Un = Kp*(Xs - Xn) + Ki*summ{j=0; j<=n}(Xs - Xj) + Kd(Xn - Xn-1), 27 | * Where Xs - is the setup temperature, Xn - the temperature on n-iteration step 28 | * In this program the interactive formula is used: 29 | * Un = Un-1 + Kp*(Xn-1 - Xn) + Ki*(Xs - Xn) + Kd*(Xn-2 + Xn - 2*Xn-1) 30 | * With the first step: 31 | * U0 = Kp*(Xs - X0) + Ki*(Xs - X0); Xn-1 = Xn; 32 | * 33 | * The default values of PID coefficients can be found in config.cpp 34 | */ 35 | class PID { 36 | public: 37 | PID(void) { } 38 | void load(const PIDparam &p); 39 | PIDparam dump(void) { return PIDparam(Kp, Ki, Kd); } 40 | void pidStable(int32_t power) { this->power = power; } 41 | void init(uint16_t ms, uint8_t denominator_p = 11, bool heat_force = true); 42 | void resetPID(uint16_t t = 0); // reset PID algorithm history parameters 43 | int32_t reqPower(int16_t temp_set, int16_t temp_curr); 44 | int32_t changePID(uint8_t p, int32_t k); // set or get (if parameter < 0) PID parameter 45 | void newPIDparams(uint16_t delta_power, uint32_t diff, uint32_t period); 46 | private: 47 | void debugPID(int t_set, int t_curr, long kp, long ki, long kd, long delta_p); 48 | uint32_t T = 20; // Check IRON or Hot Air Gun period, ms (to calculate auto PID parameters) 49 | int16_t temp_h0 = 0; // previously measured temperatures 50 | int16_t temp_h1 = 0; 51 | int32_t power = 0; // The power iterative multiplied by denominator 52 | int32_t Kp = 10; // The PID coefficients multiplied by denominator. 53 | int32_t Ki = 10; 54 | int32_t Kd = 0; 55 | int32_t Kp_force = 10; // Kp * 5 56 | int32_t Ki_force = 5; // Ki / 10 57 | int16_t denominator_p = 11; // The common coefficient denominator power of 2 (11 means 2048) 58 | bool use_force = true; // Flag indicating to use forcibly heating mode 59 | }; 60 | 61 | class PIDTUNE { 62 | public: 63 | PIDTUNE(void) : period(auto_pid_hist_length), temp_max(auto_pid_hist_length), temp_min(auto_pid_hist_length) { } 64 | void start(uint16_t base_pwr, uint16_t delta_power, uint16_t base_temp, uint16_t delta_temp); 65 | uint16_t run(uint32_t t); 66 | uint16_t autoTuneLoops(void) { return loops; } 67 | uint32_t autoTunePeriod(void) { return period.read(); } 68 | uint16_t tempMin(void) { return temp_min.read(); } 69 | uint16_t tempMax(void) { return temp_max.read(); } 70 | bool periodStable(void); 71 | private: 72 | HIST period; // Average value of relay method oscillations period 73 | HIST temp_max; // Average value of maximum temperature 74 | HIST temp_min; // Average value of minimum temperature 75 | volatile uint16_t base_power = 0; // Base power value 76 | volatile uint16_t delta_power = 0; // PLUS delta power applied 77 | volatile uint16_t base_temp = 0; // Base temperature value 78 | volatile uint16_t delta_temp = 0; // The temperature limit (base_temp - delta_temp <= t <= base_temp + delta_temp) 79 | volatile bool app_delta_power = false; // Do apply delta power 80 | volatile uint32_t pwr_change = 0; // The time (ms) when tune extra power changed 81 | volatile bool check_max = false; 82 | volatile bool check_min = false; 83 | volatile uint16_t t_max = 0; 84 | volatile uint16_t t_min = 0; 85 | volatile uint16_t loops = 0; // Whole tune oscillation loop count 86 | }; 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /Inc/stat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stat.h 3 | * 4 | * Math statistic class 5 | */ 6 | 7 | #ifndef STAT_H_ 8 | #define STAT_H_ 9 | 10 | #include "main.h" 11 | 12 | // Exponential average 13 | class EMP_AVERAGE { 14 | public: 15 | EMP_AVERAGE(uint8_t h_length = 8) { emp_k = h_length; emp_data = 0; } 16 | void length(uint8_t h_length) { emp_k = h_length; emp_data = 0; } 17 | void reset(void) { emp_data = 0; } 18 | int32_t average(int32_t value); 19 | void update(int32_t value); 20 | int32_t read(void); 21 | private: 22 | volatile uint8_t emp_k = 8; 23 | volatile uint32_t emp_data = 0; 24 | }; 25 | 26 | #define H_LENGTH (16) 27 | // Flat history data with round buffer 28 | class HIST { 29 | public: 30 | HIST(uint8_t h_length = H_LENGTH) { len = index = 0; max_len = h_length; } 31 | void length(uint8_t h_length) { len = index = 0; if (h_length > H_LENGTH) h_length = H_LENGTH; max_len = h_length; } 32 | void reset() { len = index = 0; } 33 | int32_t read(void); 34 | int32_t average(int32_t value); 35 | void update(int32_t value); 36 | uint32_t dispersion(void); // the math dispersion of the data 37 | private: 38 | volatile int32_t queue[H_LENGTH]; 39 | volatile uint8_t len; // The number of elements in the queue 40 | volatile uint8_t max_len; // Maximum length of the queue, not greater than H_LENGTH 41 | volatile uint8_t index; // The current element position, use ring buffer 42 | }; 43 | 44 | class SWITCH : public EMP_AVERAGE { 45 | public: 46 | SWITCH(uint8_t len=8) : EMP_AVERAGE(len) { } 47 | void init(uint8_t h_len, uint16_t on = 500, uint16_t off = 500); 48 | bool status(void) { return mode; } 49 | bool changed(void); 50 | void update(uint16_t value); 51 | private: 52 | bool sw_changed = false; // The status has changed flag 53 | bool mode = false; // The switch mode on (true)/off 54 | int16_t on_val = 400; // Turn on value 55 | int16_t off_val = 500; // Turn off value 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /Inc/stm32f1xx_it.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f1xx_it.h 5 | * @brief This file contains the headers of the interrupt handlers. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Define to prevent recursive inclusion -------------------------------------*/ 22 | #ifndef __STM32F1xx_IT_H 23 | #define __STM32F1xx_IT_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* Private includes ----------------------------------------------------------*/ 30 | /* USER CODE BEGIN Includes */ 31 | 32 | /* USER CODE END Includes */ 33 | 34 | /* Exported types ------------------------------------------------------------*/ 35 | /* USER CODE BEGIN ET */ 36 | 37 | /* USER CODE END ET */ 38 | 39 | /* Exported constants --------------------------------------------------------*/ 40 | /* USER CODE BEGIN EC */ 41 | 42 | /* USER CODE END EC */ 43 | 44 | /* Exported macro ------------------------------------------------------------*/ 45 | /* USER CODE BEGIN EM */ 46 | 47 | /* USER CODE END EM */ 48 | 49 | /* Exported functions prototypes ---------------------------------------------*/ 50 | void NMI_Handler(void); 51 | void HardFault_Handler(void); 52 | void MemManage_Handler(void); 53 | void BusFault_Handler(void); 54 | void UsageFault_Handler(void); 55 | void SVC_Handler(void); 56 | void DebugMon_Handler(void); 57 | void PendSV_Handler(void); 58 | void SysTick_Handler(void); 59 | void DMA1_Channel1_IRQHandler(void); 60 | void TIM1_CC_IRQHandler(void); 61 | void TIM2_IRQHandler(void); 62 | /* USER CODE BEGIN EFP */ 63 | 64 | /* USER CODE END EFP */ 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif /* __STM32F1xx_IT_H */ 71 | -------------------------------------------------------------------------------- /Inc/tools.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Inc/tools.h -------------------------------------------------------------------------------- /Inc/unit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * unit.h 3 | * 4 | */ 5 | 6 | #ifndef UNIT_H_ 7 | #define UNIT_H_ 8 | #include "pid.h" 9 | #include "stat.h" 10 | 11 | // Common interface methods for IRON and Hot Air Gun 12 | class UNIT : public PID, public PIDTUNE { 13 | public: 14 | UNIT(void) { } 15 | virtual ~UNIT(void) { } 16 | void init(uint8_t c_len, uint16_t c_min, uint16_t c_max, uint8_t s_len, uint16_t s_min, uint16_t s_max); 17 | bool isConnected(void) { return current.status(); } 18 | uint16_t unitCurrent(void) { return current.read(); } // Used in debug mode only 19 | void updateCurrent(uint16_t value) { current.update(value); } 20 | uint16_t reedInternal(void) { return sw.read(); } 21 | void updateReedStatus(bool on) { sw.update(on?100:0); } // Update Reed switch status 22 | bool isReedSwitch(bool reed); // REED switch: TRUE if switch is shorten; else: TRUE if status has been changed 23 | virtual bool isCold(void) = 0; 24 | virtual bool isOn(void) = 0; 25 | virtual void switchPower(bool On) = 0; 26 | virtual uint16_t presetTemp(void) = 0; 27 | virtual void setTemp(uint16_t t) = 0; 28 | virtual uint16_t averageTemp(void) = 0; 29 | virtual uint8_t avgPowerPcnt(void) = 0; 30 | virtual uint16_t avgPower(void) = 0; 31 | virtual uint16_t tmpDispersion(void) = 0; 32 | virtual uint16_t pwrDispersion(void) = 0; 33 | virtual void fixPower(uint16_t Power) = 0; 34 | virtual uint16_t getMaxFixedPower(void) = 0; 35 | private: 36 | SWITCH current; // The current through the unit 37 | SWITCH sw; // Tilt switch of T12 or Reed switch of Hot Air Gun 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /Inc/vars.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Inc/vars.h -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # F1-T12-858D 2 | Soldering station for hakko t12 tips + 858D rework station 3 | 4 | The project description is available here: https://www.hackster.io/sfrwmaker/stm32-based-soldering-and-rework-station-e3955b 5 | 6 | REVISION HISTORY: 7 | 8 | Nov 2019. First release created 9 | 10 | Jan 2020. Second release created 11 | - Minor changes in the controller schematics 12 | - Now the Hot Air Gun reed switch controls working mode 13 | - The soldering iron can keep working while Hot Air Gun mode 14 | - Screen saver feature implemented 15 | 16 | Jan 2020. Some updates of the second release 17 | - Minor changes in the controller schematics 18 | - Buzzer is always on issue fixed 19 | 20 | Feb 11 2020. Error on Op-amp label on schematics fixed. LM328 - > LM358 21 | 22 | Mar 23 2020. New firmware release, 2.02. See detailed description on the project page. 23 | - Updated Hot Air Gun cooling procedure 24 | - Debug mode added allowing monitoring of the internal parameters 25 | 26 | Apr 17 2020. New firmware release, 2.03. See detailed description on the project page. 27 | - Two mode hardware switch supported: REED and TILT. Tilt switch algorithm updated. 28 | - Fixed issue 'jammed on tip selection screen'. Now the main menu reacheble from tip selection mode by long press. 29 | - Ambient temperature and tilt switch readings now are available on debug screen. 30 | - Controller without soldering handle connected starts working in Hot Air Gun mode. 31 | 32 | Apr 29 2020. New firmware release, 3.00. See detailed description on the project page. 33 | - Optional 220v safety relay added. 34 | - Rotary encoder acceleration deactivated. 35 | 36 | May 12 2020. New firmware release, 3.01. See detailed description on the project page. 37 | - Standby mode issues fixed. 38 | - Temperature step feature added. 39 | 40 | June 03 2020. New firmaware release, 3.02. 41 | - Hot Air GUN start issue fixed. The power is supplied to the Hot Gun in 1 second after it activated allowing enabling AC relay. 42 | - "About" menu item issue fixed. Now this menu is available. 43 | - Tilt switch procedures reviewed and updated. 44 | - The standby mode separated from main working mode and implemented as a new one. 45 | - Screen saver timeout now is a single entity. It is no longer depended on mode switching. To return to the normal screen mode, touch the encoder. 46 | - Software automatic power off procedure reviewed and updated. The controller can power off the iron in case of no tilt switch available. 47 | - Accelerated mode of rotary encoder implemented in setting low power temperature procedure in the main menu. 48 | 49 | Jan 03 2021. New firmware release, 4.00. 50 | - Display initialization method chhanged. Now the rotation parameter is inside the contstuctor in display.cpp. 51 | - Added support for 'Guarantee cool gun' feature. New feature requires the hardware to be updated. 52 | With new hardware schematics the controller guarantees the Hot Air Gun cooled before shutdown. 53 | You can put Hot Air Gun to the base then switch off the main power switch and leave your working place. 54 | The controller will switch-off the Hot Air Gun, waits till the Hot Air gun cooled and power-off itself. 55 | The new firmware release suports old hardware also. Of course, new 'guarantee cool gun feature' will not be available on old hardware. 56 | 57 | Jan 30 2021. New hardware and firmware release, 4.01. The schematics with relay has been simplified. 58 | - Support for 'Guarantee cool gun' feature changed. New feature requires the hardware to be updated. See stm32_T12+858D_v4.sch file in the eagle directory. 59 | 60 | Feb 01 2021. Release 4.02. 61 | - Fixed controller hangs after Hot Air Gun cooled issue. 62 | 63 | Apr 28 2021. Release 4.03. 64 | - Debug information about AC zero events added to the debug mode 65 | 66 | May 25 2021. Release 4.04. 67 | - New feature added. Now it is possible to manage soldering iron while in hot air gun mode. If the "keep iron" option is enabled in main menu, long-press the encoder toggles the soldering iron. 68 | 69 | May 30 2021. Release 4.05. 70 | - Automatic startup mode implemented. The soldering iron would power-up when the power applied to the controller if mode activated. 71 | - Boost mode updated. Now boost duration time can be increment by 20 seconds upto 320 seconds. Boost mode temperature now more stable. 72 | 73 | Jun 02 2021. Release 4.06 74 | - No "about" item menu bug fixed 75 | 76 | Sep 21 2021. Release 4.07 77 | - Support for system clock checking procedure added. The controller checks its clock speed at startup. In case the ckock is lower than 72 MHz, the error message will be displayed. To return to the working mode long press the encoder. 78 | 79 | Sep 22 2021. Revert to release 4.06 80 | - The controller speed inialized correctly alwas, the speed test is not necessary. 81 | - Some followers reported the new firmware does not work. 82 | - Restore old source files, rebuild the project. Perhaps, the issue is about the flash limit of the stm32 microcontroller. 83 | 84 | Apr 01 2022. Release 4.07 85 | - Rotaruy encoder manager improved 86 | - New PID parameters for the Hot Air Gun caliration procedure applied 87 | - New TIP, T12-D32 added to the tip list 88 | 89 | Nov 07 2023. Release 4.08 90 | - The CubeMX file and project are mirgated to STM32CubeIDE. 91 | - Implemented new PID algorithm, trying to prevent overheating the soldering iron during heating up. 92 | - Faster heat-up procedure of soldering iron. 93 | - New manage procedure for Hot Air Gun imported from my recent project of soldering station with JBC tips. 94 | -------------------------------------------------------------------------------- /Src/buzzer.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Src/buzzer.cpp -------------------------------------------------------------------------------- /Src/encoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * encoder.cpp 3 | * 4 | * Created on: 15 aug. 2019. 5 | * Author: Alex 6 | */ 7 | 8 | #include "encoder.h" 9 | 10 | RENC::RENC(GPIO_TypeDef* aPORT, uint16_t aPIN, GPIO_TypeDef* bPORT, uint16_t bPIN) { 11 | rpt = 0; 12 | m_port = aPORT; s_port = bPORT; m_pin = aPIN; s_pin = bPIN; 13 | pos = 0; 14 | min_pos = -32767; max_pos = 32766; increment = 1; 15 | changed = 0; 16 | s_up = false; 17 | is_looped = false; 18 | increment = fast_increment = 1; 19 | } 20 | 21 | void RENC::addButton(GPIO_TypeDef* ButtonPORT, uint16_t ButtonPIN) { 22 | bpt = 0; 23 | b_port = ButtonPORT; 24 | b_pin = ButtonPIN; 25 | over_press = def_over_press; 26 | avg.length(avg_length); 27 | } 28 | 29 | void RENC::reset(int16_t initPos, int16_t low, int16_t upp, uint8_t inc, uint8_t fast_inc, bool looped) { 30 | min_pos = low; max_pos = upp; 31 | if (!write(initPos)) initPos = min_pos; 32 | increment = fast_increment = inc; 33 | if (fast_inc > increment) fast_increment = fast_inc; 34 | is_looped = looped; 35 | } 36 | 37 | /* 38 | * The Encoder button current status 39 | * 0 - not pressed 40 | * 1 - short press 41 | * 2 - long press 42 | */ 43 | uint8_t RENC::buttonStatus(void) { 44 | if (HAL_GetTick() >= b_check) { // It is time to check the button status 45 | b_check = HAL_GetTick() + b_check_period; 46 | uint8_t s = 0; 47 | if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(b_port, b_pin)) // if port state is low, the button pressed 48 | s = trigger_on << 1; 49 | if (b_on) { 50 | if (avg.average(s) < trigger_off) 51 | b_on = false; 52 | } else { 53 | if (avg.average(s) > trigger_on) 54 | b_on = true; 55 | } 56 | 57 | if (b_on) { // Button status is 'pressed' 58 | uint32_t n = HAL_GetTick() - bpt; 59 | if ((bpt == 0) || (n > over_press)) { 60 | bpt = HAL_GetTick(); 61 | } else if (n > long_press) { // Long press 62 | if (i_b_rel) { 63 | return 0; 64 | } else{ 65 | i_b_rel = true; 66 | return 2; 67 | } 68 | } 69 | } else { // Button status is 'not pressed' 70 | if (bpt == 0 || i_b_rel) { 71 | bpt = 0; 72 | i_b_rel = false; 73 | return 0; 74 | } 75 | uint32_t e = HAL_GetTick() - bpt; 76 | bpt = 0; // Ready for next press 77 | if (e < over_press) { // Long press already managed 78 | return 1; 79 | } 80 | } 81 | } 82 | return 0; 83 | } 84 | 85 | bool RENC::write(int16_t initPos) { 86 | if ((initPos >= min_pos) && (initPos <= max_pos)) { 87 | pos = initPos; 88 | return true; 89 | } 90 | return false; 91 | } 92 | 93 | 94 | void RENC::encoderIntr(void) { // Interrupt function, called when the channel A of encoder changed 95 | bool mUp = (HAL_GPIO_ReadPin(m_port, m_pin) == GPIO_PIN_SET); 96 | uint32_t now_t = HAL_GetTick(); 97 | if (!mUp) { // The main channel has been "pressed" 98 | if ((rpt == 0) || (now_t - rpt > over_press)) { 99 | rpt = now_t; 100 | s_up = (HAL_GPIO_ReadPin(s_port, s_pin) == GPIO_PIN_SET); 101 | } 102 | } else { 103 | if (rpt > 0) { 104 | if (s_up == (HAL_GPIO_ReadPin(s_port, s_pin) == GPIO_PIN_RESET)) { // Secondary channel polarity has been changed 105 | uint8_t inc = increment; 106 | if ((now_t - rpt) < over_press) { 107 | if ((now_t - changed) < fast_timeout) inc = fast_increment; 108 | changed = now_t; 109 | if (s_up) pos -= inc; else pos += inc; 110 | if (pos > max_pos) { 111 | pos = (is_looped)?min_pos:max_pos; 112 | } else if (pos < min_pos) { 113 | pos = (is_looped)?max_pos:min_pos; 114 | } 115 | } 116 | } 117 | rpt = 0; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Src/font.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Src/font.c -------------------------------------------------------------------------------- /Src/iron.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * iron.cpp 3 | * 4 | * Created on: 13 aug 2019 5 | * Author: Alex 6 | */ 7 | 8 | #include 9 | #include "iron.h" 10 | #include "tools.h" 11 | 12 | void IRON::init(void) { 13 | mode = POWER_OFF; 14 | fix_power = 0; 15 | chill = false; 16 | UNIT::init(iron_sw_len, iron_off_value, iron_on_value, sw_tilt_len, sw_off_value, sw_on_value); 17 | t_iron_short.length(iron_emp_coeff); 18 | t_amb.length(ambient_emp_coeff); 19 | h_power.length(ec); 20 | h_temp.length(ec); 21 | d_power.length(ec); 22 | d_temp.length(ec); 23 | // The IRON is powered by TIM2, calculate the TIM2 period in ms 24 | uint32_t tim2_period = (TIM2->PSC + 1) * (TIM2->ARR + 1); 25 | uint32_t cpu_speed = SystemCoreClock / 1000; // Calculate TIM2 period in ms 26 | tim2_period /= cpu_speed; 27 | PID::init(tim2_period, 11, true); // Initialize PID for IRON 28 | resetPID(); 29 | } 30 | 31 | void IRON::switchPower(bool On) { 32 | if (!On) { 33 | fix_power = 0; 34 | if (mode != POWER_OFF) 35 | mode = POWER_COOLING; // Start the cooling process 36 | } else { 37 | resetPID(); 38 | temp_low = 0; // Disable low power mode 39 | mode = POWER_ON; 40 | } 41 | h_power.reset(); 42 | d_power.reset(); 43 | temp_low = 0; 44 | } 45 | 46 | uint16_t IRON::alternateTemp(void) { 47 | uint16_t t = h_temp.read(); 48 | if (mode == POWER_OFF) 49 | t = 0; 50 | return t; 51 | } 52 | 53 | void IRON::setTemp(uint16_t t) { 54 | if (mode == POWER_ON) resetPID(); 55 | if (t > int_temp_max) t = int_temp_max; // Do not allow over heating. int_temp_max is defined in vars.cpp 56 | temp_set = t; 57 | uint16_t ta = h_temp.read(); 58 | chill = (ta > t + 20); // The IRON must be cooled 59 | } 60 | 61 | uint16_t IRON::avgPower(void) { 62 | uint16_t p = h_power.read(); 63 | if (mode == POWER_FIXED) 64 | p = fix_power; 65 | if (p > max_power) p = max_power; 66 | return p; 67 | } 68 | 69 | uint8_t IRON::avgPowerPcnt(void) { 70 | uint16_t p = h_power.read(); 71 | uint16_t max_p = max_power; 72 | if (mode == POWER_FIXED) { 73 | p = fix_power; 74 | max_p = max_fix_power; 75 | } else if (mode == POWER_PID_TUNE) { 76 | max_p = max_fix_power; 77 | } 78 | p = constrain(p, 0, max_p); 79 | return map(p, 0, max_p, 0, 100); 80 | } 81 | 82 | void IRON::fixPower(uint16_t Power) { 83 | h_power.reset(); 84 | d_power.reset(); 85 | if (Power == 0) { // To switch off the IRON, set the Power to 0 86 | fix_power = 0; 87 | mode = POWER_COOLING; 88 | return; 89 | } 90 | 91 | if (Power > max_fix_power) 92 | fix_power = max_fix_power; 93 | 94 | fix_power = Power; 95 | mode = POWER_FIXED; 96 | } 97 | 98 | void IRON::adjust(uint16_t t) { 99 | if (t > int_temp_max) t = int_temp_max; // Do not allow over heating 100 | temp_set = t; 101 | } 102 | 103 | // Called from HAL_ADC_ConvCpltCallback() event handler. See core.cpp for details. 104 | uint16_t IRON::power(int32_t t) { 105 | t = tempShortAverage(t); // Prevent temperature deviation using short term history average 106 | temp_curr = t; 107 | int32_t at = h_temp.average(temp_curr); 108 | int32_t diff = at - temp_curr; 109 | d_temp.update(diff*diff); 110 | 111 | if ((t >= int_temp_max + 100) || (t > (temp_set + 400))) { // Prevent global over heating 112 | if (mode == POWER_ON) chill = true; // Turn off the power in main working mode only; 113 | } 114 | 115 | int32_t p = 0; 116 | switch (mode) { 117 | case POWER_OFF: 118 | break; 119 | case POWER_COOLING: 120 | if (at < iron_cold) 121 | mode = POWER_OFF; 122 | break; 123 | case POWER_ON: 124 | { 125 | uint16_t t_set = temp_set; 126 | if (temp_low) t_set = temp_low; // If temp_low setup, turn-on low power mode 127 | if (chill) { 128 | if (t < (t_set - 2)) { 129 | chill = false; 130 | resetPID(); 131 | } else { 132 | break; 133 | } 134 | } 135 | p = PID::reqPower(t_set, t); 136 | p = constrain(p, 0, max_power); 137 | break; 138 | } 139 | case POWER_FIXED: 140 | p = fix_power; 141 | break; 142 | case POWER_PID_TUNE: 143 | p = PIDTUNE::run(t); 144 | break; 145 | default: 146 | break; 147 | } 148 | 149 | int32_t ap = h_power.average(p); 150 | diff = ap - p; 151 | d_power.update(diff*diff); 152 | return p; 153 | } 154 | 155 | void IRON::reset(void) { 156 | resetShortTemp(); 157 | h_power.reset(); 158 | h_temp.reset(); 159 | d_power.reset(); 160 | d_temp.reset(); 161 | mode = POWER_OFF; // New tip inserted, clear COOLING mode 162 | } 163 | 164 | 165 | void IRON::lowPowerMode(uint16_t t) { 166 | if (mode == POWER_ON && t < temp_set) { 167 | temp_low = t; // Activate low power mode 168 | chill = true; // Stop heating, when temp reaches standby one, reset PID 169 | h_power.reset(); 170 | d_power.reset(); 171 | } 172 | } 173 | 174 | /* 175 | * Return ambient temperature in Celsius 176 | * Caches previous result to skip expensive calculations 177 | */ 178 | int32_t IRON::ambientTemp(void) { 179 | static const uint16_t add_resistor = 10000; // The additional resistor value (10koHm) 180 | static const float normal_temp[2]= { 10000, 25 }; // nominal resistance and the nominal temperature 181 | static const uint16_t beta = 3950; // The beta coefficient of the thermistor (usually 3000-4000) 182 | static int32_t average = 0; // Previous value of analog read 183 | static int cached_ambient = 0; // Previous value of the temperature 184 | 185 | if (!isConnected()) return default_ambient; // If IRON is not connected, return default ambient temperature 186 | if (abs(t_amb.read() - average) < 20) 187 | return cached_ambient; 188 | 189 | average = t_amb.read(); 190 | 191 | if (average < max_ambient_value) { // prevent division by zero; About -30 degrees 192 | // convert the value to resistance 193 | float resistance = 4095.0 / (float)average - 1.0; 194 | resistance = (float)add_resistor / resistance; 195 | 196 | float steinhart = resistance / normal_temp[0]; // (R/Ro) 197 | steinhart = log(steinhart); // ln(R/Ro) 198 | steinhart /= beta; // 1/B * ln(R/Ro) 199 | steinhart += 1.0 / (normal_temp[1] + 273.15); // + (1/To) 200 | steinhart = 1.0 / steinhart; // Invert 201 | steinhart -= 273.15; // convert to Celsius 202 | cached_ambient = round(steinhart); 203 | } else { 204 | cached_ambient = default_ambient; 205 | } 206 | return cached_ambient; 207 | } 208 | -------------------------------------------------------------------------------- /Src/iron_tips.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * iron_tips.cpp 3 | * 4 | * Created on: 15 aug. 2019. 5 | * Author: Alex 6 | */ 7 | 8 | #include "iron_tips.h" 9 | #include "eeprom.h" 10 | #include "string.h" 11 | 12 | static char tip_names[][tip_name_sz] = { 13 | {'H', 'O', 'G', 'U', 'N'}, // The Hot Air Gun is just another virtual tip that has its own calibration. It should be on the top of list!!! 14 | {'B', '\0', '\0', '\0', '\0'}, 15 | {'B', '1', '\0', '\0', '\0'}, 16 | {'B', '2', '\0', '\0', '\0'}, 17 | {'B', '3', '\0', '\0', '\0'}, 18 | {'B', '4', '\0', '\0', '\0'}, 19 | {'B', '2', 'Z', '\0', '\0'}, 20 | {'B', 'C', '1', '\0', '\0'}, 21 | {'B', 'C', '1', '.' , '5'}, 22 | {'B', 'C', '2', '\0', '\0'}, 23 | {'B', 'C', '3', '\0', '\0'}, 24 | {'B', 'C', '1', 'Z', '\0'}, 25 | {'B', 'C', '2', 'Z', '\0'}, 26 | {'B', 'C', '4', 'Z', '\0'}, 27 | {'B', 'C', 'F', '1', '\0'}, 28 | {'B', 'C', 'F', '2', '\0'}, 29 | {'B', 'C', 'F', '3', '\0'}, 30 | {'B', 'C', 'F', '4', '\0'}, 31 | {'B', 'C', 'F', '1', 'Z'}, 32 | {'B', 'C', 'F', '2', 'Z'}, 33 | {'B', 'C', 'F', '3', 'Z'}, 34 | {'B', 'C', 'M', '2', '\0'}, 35 | {'B', 'C', 'M', '3', '\0'}, 36 | {'B', 'L', '\0', '\0', '\0'}, 37 | {'B', 'Z', '\0', '\0', '\0'}, 38 | {'C', '1', '\0', '\0', '\0'}, 39 | {'C', '2', '\0', '\0', '\0'}, 40 | {'C', '3', '\0', '\0', '\0'}, 41 | {'C', '4', '\0', '\0', '\0'}, 42 | {'D', '0', '8', '\0', '\0'}, 43 | {'D', '1', '2', '\0', '\0'}, 44 | {'D', '1', '6', '\0', '\0'}, 45 | {'D', '2', '4', '\0', '\0'}, 46 | {'D', '3', '2', '\0', '\0'}, // Tip added 04/01/2022 47 | {'D', '5', '2', '\0', '\0'}, 48 | {'D', '4', '\0', '\0', '\0'}, 49 | {'D', 'L', '1', '2', '\0'}, 50 | {'D', 'L', '3', '2', '\0'}, 51 | {'D', 'L', '5', '2', '\0'}, 52 | {'D', '1', '2', 'Z', '\0'}, 53 | {'D', '2', '4', 'Z', '\0'}, 54 | {'D', '4', 'Z', '\0', '\0'}, 55 | {'I', '\0', '\0', '\0', '\0'}, 56 | {'I', 'L', '\0', '\0', '\0'}, 57 | {'I', 'L', 'S', '\0', '\0'}, 58 | {'J', '0', '2', '\0', '\0'}, 59 | {'J', 'L', '0', '2', '\0'}, 60 | {'J', 'S', '0', '2', '\0'}, 61 | {'K', '\0', '\0', '\0', '\0'}, 62 | {'K', 'F', '\0', '\0', '\0'}, 63 | {'K', 'L', '\0', '\0', '\0'}, 64 | {'K', 'R', '\0', '\0', '\0'}, 65 | {'K', 'F', 'Z', '\0', '\0'}, 66 | {'K', 'R', 'Z', '\0', '\0'}, 67 | {'K', 'U', '\0', '\0', '\0'}, // Tip added 09/12/2018 68 | {'W', 'B', '2', '\0', '\0'}, 69 | {'W', 'D', '0', '8', '\0'}, 70 | {'W', 'D', '1', '2', '\0'}, 71 | {'W', 'D', '1', '6', '\0'}, 72 | {'W', 'D', '5', '2', '\0'}, 73 | {'W', 'I', '\0', '\0', '\0'}, 74 | {'N', '1', '-', '0', '6'}, 75 | {'N', '1', '-', '0', '8'}, 76 | {'N', '1', '-', '1', '0'}, 77 | {'N', '1', '-', '1', '3'}, 78 | {'N', '1', '-', '1', '6'}, 79 | {'N', '1', '-', '2', '0'}, 80 | {'N', '1', '-', '2', '3'}, 81 | {'N', '1', '-', 'L', '1'}, 82 | {'1', '0', '0', '1', '\0'}, 83 | {'1', '0', '0', '2', '\0'}, 84 | {'1', '0', '0', '3', '\0'}, 85 | {'1', '0', '0', '4', '\0'}, 86 | {'1', '0', '0', '5', '\0'}, 87 | {'1', '0', '0', '6', '\0'}, 88 | {'1', '0', '0', '7', '\0'}, 89 | {'1', '0', '0', '8', '\0'}, 90 | {'1', '0', '0', '9', '\0'}, 91 | {'1', '0', '1', '0', '\0'}, 92 | {'1', '2', '0', '1', '\0'}, 93 | {'1', '2', '0', '2', '\0'}, 94 | {'1', '2', '0', '3', '\0'}, 95 | {'1', '2', '0', '4', '\0'}, 96 | {'1', '2', '0', '5', '\0'}, 97 | {'1', '2', '0', '6', '\0'}, 98 | {'1', '2', '0', '7', '\0'}, 99 | {'1', '2', '0', '8', '\0'}, 100 | {'1', '2', '0', '9', '\0'}, 101 | {'1', '4', '0', '1', '\0'}, 102 | {'1', '4', '0', '2', '\0'}, 103 | {'1', '4', '0', '3', '\0'}, 104 | {'1', '4', '0', '4', '\0'}, 105 | {'1', '4', '0', '5', '\0'}, 106 | {'1', '4', '0', '6', '\0'} 107 | }; 108 | 109 | static uint16_t tip_number = sizeof(tip_names) / tip_name_sz; 110 | 111 | uint16_t TIPS::loaded(void) { 112 | return tip_number; 113 | } 114 | 115 | const char* TIPS::name(uint8_t index) { 116 | if (index < tip_number) { 117 | return tip_names[index]; 118 | } 119 | return 0; 120 | } 121 | 122 | int TIPS::index(const char *name) { 123 | for (uint16_t i = 0; i < tip_number; ++i) { 124 | if (strncmp(name, tip_names[i], tip_name_sz) == 0) 125 | return i; 126 | } 127 | return -1; 128 | } 129 | -------------------------------------------------------------------------------- /Src/oled.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Src/oled.cpp -------------------------------------------------------------------------------- /Src/pid.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * pid.cpp 3 | * 4 | * 2023 FEB 19, v1.01 5 | * Introduced the heating-up PID parameters: Kp_force and Ki_force 6 | * Changed the methods: PID::init(), PID::load(), PID::reqPower() 7 | * When the temperature is far lower than the preset one, the aggressive PID parameters are used 8 | */ 9 | 10 | #include "pid.h" 11 | #include "tools.h" 12 | #include 13 | 14 | PIDparam::PIDparam(int32_t Kp, int32_t Ki, int32_t Kd) { 15 | this->Kp = Kp; 16 | this->Ki = Ki; 17 | this->Kd = Kd; 18 | } 19 | 20 | PIDparam::PIDparam(const PIDparam &p) { 21 | Kp = p.Kp; 22 | Ki = p.Ki; 23 | Kd = p.Kd; 24 | } 25 | 26 | // When load the PID parameters, calculate aggressive heating mode parameter values also: 27 | // Increase the Kp in the aggressive mode in several times, 28 | // Decrease the Ki in the aggressive mode. The Kd is not used in the aggressive mode 29 | void PID::load(const PIDparam &p) { 30 | Kp = p.Kp; 31 | Ki = p.Ki; 32 | Kd = p.Kd; 33 | Kp_force = Kp * 5; 34 | Ki_force = Ki / 10; 35 | if (Ki_force < 5) Ki_force = 5; 36 | } 37 | 38 | void PID::init(uint16_t ms, uint8_t denominator_p, bool heat_force) { // PID parameters are initialized from EEPROM by call 39 | Kp = 10; 40 | Ki = 10; 41 | Kd = 0; 42 | T = ms; 43 | Kp_force = 10; 44 | Ki_force = 5; 45 | this->denominator_p = denominator_p; 46 | use_force = heat_force; 47 | } 48 | 49 | void PID::resetPID(uint16_t t) { 50 | temp_h0 = t; 51 | temp_h1 = t; 52 | power = 0; 53 | } 54 | 55 | int32_t PID::changePID(uint8_t p, int32_t k) { 56 | switch(p) { 57 | case 1: 58 | if (k >= 0) Kp = k; 59 | return Kp; 60 | case 2: 61 | if (k >= 0) Ki = k; 62 | return Ki; 63 | case 3: 64 | if (k >= 0) Kd = k; 65 | return Kd; 66 | default: 67 | break; 68 | } 69 | return 0; 70 | } 71 | /* 72 | * Ku = 4 * delta_power / (PI * SQRT(alpha^2-epsion^2), where 73 | * diff = alpha^2-epsion^2, 74 | * alpha - amplitude of temperature oscillation 75 | * epsilon - hysteresis (delta_temp) 76 | * 77 | * Pu = period - the oscillation period, ms 78 | * Kp = 0.6*Ku; Ti = 0.5*Pu; Td = 0.125*Pu; 79 | * Ki = Kp*T/Ti; 80 | * Kd = Kp*Td/T; 81 | */ 82 | void PID::newPIDparams(uint16_t delta_power, uint32_t diff, uint32_t period) { 83 | double Ku = 4 * delta_power; 84 | Ku /= M_PI * sqrt(diff); 85 | uint32_t denominator = 1 << denominator_p; 86 | Kp = round(Ku * 0.6 * denominator); // Translate Kp to the numerator of implemented PID 87 | Ki = (Kp * T * 2 + period/2) / period; 88 | Kd = (Kp * period) >> 3; // 1/8 = 0.125 89 | Kd += T/2; 90 | Kd /= T; 91 | /* 92 | * The algorithm gives very big values for Kd 93 | * The big values of Kd gives us the big power dispersion 94 | * That is why it is better to limit the Kd value. 95 | */ 96 | if (Kd > 10000) Kd = Kp/2; 97 | } 98 | 99 | int32_t PID::reqPower(int16_t temp_set, int16_t temp_curr) { 100 | if (use_force && temp_curr + 100 < temp_set) { // Aggressive heat-up mode, use Kp_force and Ki_forse only 101 | if (temp_h0 == 0) { // Use direct formulae because do not know previous temperature 102 | int32_t i_summ = temp_set - temp_curr; 103 | power = Kp_force*(temp_set - temp_curr) + Ki_force * i_summ; 104 | } else { 105 | int32_t kp = Kp_force * (temp_h1 - temp_curr); 106 | int32_t ki = Ki_force * (temp_set - temp_curr); 107 | int32_t delta_p = kp + ki; 108 | power += delta_p; // Power is stored multiplied by denominator! 109 | } 110 | } else { // Use regular PID parameters near preset temperature 111 | if (temp_h0 == 0) { // Use direct formulae because do not know previous temperature 112 | int32_t i_summ = temp_set - temp_curr; 113 | power = Kp*(temp_set - temp_curr) + Ki * i_summ; 114 | } else { 115 | int32_t kp = Kp * (temp_h1 - temp_curr); 116 | int32_t ki = Ki * (temp_set - temp_curr); 117 | int32_t kd = Kd * (temp_h0 + temp_curr - 2 * temp_h1); 118 | int32_t delta_p = kp + ki + kd; 119 | power += delta_p; // Power is stored multiplied by denominator! 120 | } 121 | } 122 | temp_h0 = temp_h1; 123 | temp_h1 = temp_curr; 124 | int32_t pwr = power + (1 << (denominator_p-1)); // prepare the power to divide by denominator, round the result 125 | pwr >>= denominator_p; // divide by the denominator 126 | return pwr; 127 | } 128 | 129 | void PIDTUNE::start(uint16_t base_pwr, uint16_t delta_power, uint16_t base_temp, uint16_t delta_temp) { 130 | if (base_pwr && delta_power) { 131 | this->base_power = base_pwr; // The power required to keep the preset temperature 132 | this->delta_power = delta_power; // Apply +- delta power in relay method 133 | this->base_temp = base_temp; 134 | this->delta_temp = delta_temp; 135 | app_delta_power = false; 136 | pwr_change = 0; 137 | loops = 0; 138 | period.reset(); 139 | temp_min.reset(); 140 | temp_max.reset(); 141 | } 142 | } 143 | 144 | uint16_t PIDTUNE::run(uint32_t t) { 145 | if (app_delta_power) { // Applying extra power 146 | if (check_min && (int16_t)t > base_temp) { // Finish looking for minimum temperature 147 | check_min = false; 148 | temp_min.update(t_min); 149 | } 150 | if ((int16_t)t > base_temp + delta_temp) { // Crossed high temperature limit, decrease the power 151 | app_delta_power = false; 152 | if (pwr_change > 0) { 153 | uint32_t n = HAL_GetTick(); 154 | period.update(n-pwr_change); 155 | pwr_change = n; 156 | ++loops; 157 | } else { 158 | pwr_change = HAL_GetTick(); 159 | } 160 | check_min = false; // Be paranoid 161 | check_max = true; 162 | t_max = t; 163 | } 164 | } else { // Returning to preset temperature 165 | if (check_max && (int16_t)t < base_temp) { // Finish looking for maximum temperature 166 | check_max = false; 167 | temp_max.update(t_max); 168 | } 169 | if ((int16_t)t < base_temp - delta_temp) { // Crossed low temperature limit, increase the power 170 | app_delta_power = true; 171 | check_max = false; // Be paranoid 172 | check_min = true; 173 | t_min = t; 174 | } 175 | } 176 | if (check_max && t > t_max) t_max = t; // Update maximum temperature of this cycle 177 | if (check_min && t < t_min) t_min = t; // Update minimum temperature of this cycle 178 | uint16_t p = base_power; 179 | if (app_delta_power) p += delta_power; else p -= delta_power; 180 | return p; 181 | } 182 | 183 | bool PIDTUNE::periodStable(void) { 184 | uint32_t disp = period.dispersion() * 100; 185 | disp /= period.read(); // Relative dispersion, % 186 | return disp < 10; 187 | } 188 | -------------------------------------------------------------------------------- /Src/stat.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * stat.cpp 3 | * 4 | */ 5 | 6 | #include "stat.h" 7 | #include "tools.h" 8 | 9 | int32_t EMP_AVERAGE::average(int32_t value) { 10 | uint8_t round_v = emp_k >> 1; 11 | update(value); 12 | return (emp_data + round_v) / emp_k; 13 | } 14 | 15 | void EMP_AVERAGE::update(int32_t value) { 16 | uint8_t round_v = emp_k >> 1; 17 | emp_data += value - (emp_data + round_v) / emp_k; 18 | } 19 | 20 | int32_t EMP_AVERAGE::read(void) { 21 | uint8_t round_v = emp_k >> 1; 22 | return (emp_data + round_v) / emp_k; 23 | } 24 | 25 | int32_t HIST::read(void) { 26 | int32_t sum = 0; 27 | if (len == 0) return 0; 28 | if (len == 1) return queue[0]; 29 | for (uint8_t i = 0; i < len; ++i) sum += queue[i]; 30 | sum += len >> 1; // round the average 31 | sum /= len; 32 | return sum; 33 | } 34 | 35 | int32_t HIST::average(int32_t value) { 36 | update(value); 37 | return read(); 38 | } 39 | 40 | void HIST::update(int32_t value) { 41 | if (len < max_len) { 42 | queue[len++] = value; 43 | } else { 44 | queue[index] = value; 45 | if (++index >= max_len) index = 0; // Use ring buffer 46 | } 47 | } 48 | 49 | uint32_t HIST::dispersion(void) { 50 | if (len < 3) return 1000; 51 | uint32_t sum = 0; 52 | uint32_t avg = read(); 53 | for (uint8_t i = 0; i < len; ++i) { 54 | int32_t q = queue[i]; 55 | q -= avg; 56 | q *= q; 57 | sum += q; 58 | } 59 | sum += len >> 1; 60 | sum /= len; 61 | return sum; 62 | } 63 | 64 | void SWITCH::init(uint8_t h_len, uint16_t off, uint16_t on) { 65 | EMP_AVERAGE::length(h_len); 66 | if (on < off) on = off; 67 | on_val = on; 68 | off_val = off; 69 | mode = false; 70 | } 71 | 72 | 73 | bool SWITCH::changed(void) { 74 | if (sw_changed) { 75 | sw_changed = false; 76 | return true; 77 | } 78 | return false; 79 | } 80 | 81 | void SWITCH::update(uint16_t value) { 82 | uint16_t max_val = on_val + (on_val >> 1); 83 | uint16_t min_val = off_val - (off_val >> 1); 84 | value = constrain(value, min_val, max_val); 85 | uint16_t avg = EMP_AVERAGE::average(value); 86 | if (mode) { 87 | if (avg < off_val) { 88 | sw_changed = true; 89 | mode = false; 90 | } 91 | } else { 92 | if (avg > on_val) { 93 | sw_changed = true; 94 | mode = true; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Src/stm32f1xx_it.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f1xx_it.c 5 | * @brief Interrupt Service Routines. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | #include "main.h" 23 | #include "stm32f1xx_it.h" 24 | /* Private includes ----------------------------------------------------------*/ 25 | /* USER CODE BEGIN Includes */ 26 | /* USER CODE END Includes */ 27 | 28 | /* Private typedef -----------------------------------------------------------*/ 29 | /* USER CODE BEGIN TD */ 30 | 31 | /* USER CODE END TD */ 32 | 33 | /* Private define ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN PD */ 35 | 36 | /* USER CODE END PD */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN PM */ 40 | 41 | /* USER CODE END PM */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | /* USER CODE BEGIN PV */ 45 | 46 | /* USER CODE END PV */ 47 | 48 | /* Private function prototypes -----------------------------------------------*/ 49 | /* USER CODE BEGIN PFP */ 50 | 51 | /* USER CODE END PFP */ 52 | 53 | /* Private user code ---------------------------------------------------------*/ 54 | /* USER CODE BEGIN 0 */ 55 | 56 | /* USER CODE END 0 */ 57 | 58 | /* External variables --------------------------------------------------------*/ 59 | extern DMA_HandleTypeDef hdma_adc1; 60 | extern TIM_HandleTypeDef htim1; 61 | extern TIM_HandleTypeDef htim2; 62 | /* USER CODE BEGIN EV */ 63 | 64 | /* USER CODE END EV */ 65 | 66 | /******************************************************************************/ 67 | /* Cortex-M3 Processor Interruption and Exception Handlers */ 68 | /******************************************************************************/ 69 | /** 70 | * @brief This function handles Non maskable interrupt. 71 | */ 72 | void NMI_Handler(void) 73 | { 74 | /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ 75 | 76 | /* USER CODE END NonMaskableInt_IRQn 0 */ 77 | /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ 78 | 79 | /* USER CODE END NonMaskableInt_IRQn 1 */ 80 | } 81 | 82 | /** 83 | * @brief This function handles Hard fault interrupt. 84 | */ 85 | void HardFault_Handler(void) 86 | { 87 | /* USER CODE BEGIN HardFault_IRQn 0 */ 88 | 89 | /* USER CODE END HardFault_IRQn 0 */ 90 | while (1) 91 | { 92 | /* USER CODE BEGIN W1_HardFault_IRQn 0 */ 93 | /* USER CODE END W1_HardFault_IRQn 0 */ 94 | } 95 | } 96 | 97 | /** 98 | * @brief This function handles Memory management fault. 99 | */ 100 | void MemManage_Handler(void) 101 | { 102 | /* USER CODE BEGIN MemoryManagement_IRQn 0 */ 103 | 104 | /* USER CODE END MemoryManagement_IRQn 0 */ 105 | while (1) 106 | { 107 | /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ 108 | /* USER CODE END W1_MemoryManagement_IRQn 0 */ 109 | } 110 | } 111 | 112 | /** 113 | * @brief This function handles Prefetch fault, memory access fault. 114 | */ 115 | void BusFault_Handler(void) 116 | { 117 | /* USER CODE BEGIN BusFault_IRQn 0 */ 118 | 119 | /* USER CODE END BusFault_IRQn 0 */ 120 | while (1) 121 | { 122 | /* USER CODE BEGIN W1_BusFault_IRQn 0 */ 123 | /* USER CODE END W1_BusFault_IRQn 0 */ 124 | } 125 | } 126 | 127 | /** 128 | * @brief This function handles Undefined instruction or illegal state. 129 | */ 130 | void UsageFault_Handler(void) 131 | { 132 | /* USER CODE BEGIN UsageFault_IRQn 0 */ 133 | 134 | /* USER CODE END UsageFault_IRQn 0 */ 135 | while (1) 136 | { 137 | /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ 138 | /* USER CODE END W1_UsageFault_IRQn 0 */ 139 | } 140 | } 141 | 142 | /** 143 | * @brief This function handles System service call via SWI instruction. 144 | */ 145 | void SVC_Handler(void) 146 | { 147 | /* USER CODE BEGIN SVCall_IRQn 0 */ 148 | 149 | /* USER CODE END SVCall_IRQn 0 */ 150 | /* USER CODE BEGIN SVCall_IRQn 1 */ 151 | 152 | /* USER CODE END SVCall_IRQn 1 */ 153 | } 154 | 155 | /** 156 | * @brief This function handles Debug monitor. 157 | */ 158 | void DebugMon_Handler(void) 159 | { 160 | /* USER CODE BEGIN DebugMonitor_IRQn 0 */ 161 | 162 | /* USER CODE END DebugMonitor_IRQn 0 */ 163 | /* USER CODE BEGIN DebugMonitor_IRQn 1 */ 164 | 165 | /* USER CODE END DebugMonitor_IRQn 1 */ 166 | } 167 | 168 | /** 169 | * @brief This function handles Pendable request for system service. 170 | */ 171 | void PendSV_Handler(void) 172 | { 173 | /* USER CODE BEGIN PendSV_IRQn 0 */ 174 | 175 | /* USER CODE END PendSV_IRQn 0 */ 176 | /* USER CODE BEGIN PendSV_IRQn 1 */ 177 | 178 | /* USER CODE END PendSV_IRQn 1 */ 179 | } 180 | 181 | /** 182 | * @brief This function handles System tick timer. 183 | */ 184 | void SysTick_Handler(void) 185 | { 186 | /* USER CODE BEGIN SysTick_IRQn 0 */ 187 | 188 | /* USER CODE END SysTick_IRQn 0 */ 189 | HAL_IncTick(); 190 | /* USER CODE BEGIN SysTick_IRQn 1 */ 191 | 192 | /* USER CODE END SysTick_IRQn 1 */ 193 | } 194 | 195 | /******************************************************************************/ 196 | /* STM32F1xx Peripheral Interrupt Handlers */ 197 | /* Add here the Interrupt Handlers for the used peripherals. */ 198 | /* For the available peripheral interrupt handler names, */ 199 | /* please refer to the startup file (startup_stm32f1xx.s). */ 200 | /******************************************************************************/ 201 | 202 | /** 203 | * @brief This function handles DMA1 channel1 global interrupt. 204 | */ 205 | void DMA1_Channel1_IRQHandler(void) 206 | { 207 | /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */ 208 | 209 | /* USER CODE END DMA1_Channel1_IRQn 0 */ 210 | HAL_DMA_IRQHandler(&hdma_adc1); 211 | /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */ 212 | 213 | /* USER CODE END DMA1_Channel1_IRQn 1 */ 214 | } 215 | 216 | /** 217 | * @brief This function handles TIM1 capture compare interrupt. 218 | */ 219 | void TIM1_CC_IRQHandler(void) 220 | { 221 | /* USER CODE BEGIN TIM1_CC_IRQn 0 */ 222 | 223 | /* USER CODE END TIM1_CC_IRQn 0 */ 224 | HAL_TIM_IRQHandler(&htim1); 225 | /* USER CODE BEGIN TIM1_CC_IRQn 1 */ 226 | 227 | /* USER CODE END TIM1_CC_IRQn 1 */ 228 | } 229 | 230 | /** 231 | * @brief This function handles TIM2 global interrupt. 232 | */ 233 | void TIM2_IRQHandler(void) 234 | { 235 | /* USER CODE BEGIN TIM2_IRQn 0 */ 236 | 237 | /* USER CODE END TIM2_IRQn 0 */ 238 | HAL_TIM_IRQHandler(&htim2); 239 | /* USER CODE BEGIN TIM2_IRQn 1 */ 240 | 241 | /* USER CODE END TIM2_IRQn 1 */ 242 | } 243 | 244 | /* USER CODE BEGIN 1 */ 245 | 246 | /* USER CODE END 1 */ 247 | -------------------------------------------------------------------------------- /Src/syscalls.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Src/syscalls.c -------------------------------------------------------------------------------- /Src/tools.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Src/tools.cpp -------------------------------------------------------------------------------- /Src/unit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * unit.cpp 3 | * 4 | * Created on: 13 June 2022 5 | * Author: Alex 6 | */ 7 | 8 | #include "unit.h" 9 | 10 | void UNIT::init(uint8_t c_len, uint16_t c_min, uint16_t c_max, uint8_t s_len, uint16_t s_min, uint16_t s_max) { 11 | current.init(c_len, c_min, c_max); 12 | sw.init(s_len, s_min, s_max); 13 | } 14 | 15 | bool UNIT::isReedSwitch(bool reed) { 16 | if (reed) 17 | return sw.status(); // TRUE if switch is open (IRON in use) 18 | return sw.changed(); // TRUE if tilt status has been changed 19 | } 20 | -------------------------------------------------------------------------------- /Src/vars.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Src/vars.cpp -------------------------------------------------------------------------------- /Паяльная и ремонтная станция на STM32.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfrwmaker/F1-T12-858D/19be82d662f8d5346d210888d4c5b81c4dc31926/Паяльная и ремонтная станция на STM32.pdf --------------------------------------------------------------------------------