Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
u8g_com_arduino_st7920_spi.c
00001 /* 00002 00003 u8g_com_arduino_st7920_spi.c 00004 00005 Universal 8bit Graphics Library 00006 00007 Copyright (c) 2011, olikraus@gmail.com 00008 All rights reserved. 00009 00010 Redistribution and use in source and binary forms, with or without modification, 00011 are permitted provided that the following conditions are met: 00012 00013 * Redistributions of source code must retain the above copyright notice, this list 00014 of conditions and the following disclaimer. 00015 00016 * Redistributions in binary form must reproduce the above copyright notice, this 00017 list of conditions and the following disclaimer in the documentation and/or other 00018 materials provided with the distribution. 00019 00020 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 00021 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 00022 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00023 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00024 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 00025 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00027 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00030 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00031 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00032 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 A special SPI interface for ST7920 controller 00035 00036 Update for ATOMIC operation done (01 Jun 2013) 00037 U8G_ATOMIC_OR(ptr, val) 00038 U8G_ATOMIC_AND(ptr, val) 00039 U8G_ATOMIC_START(); 00040 U8G_ATOMIC_END(); 00041 00042 00043 */ 00044 00045 #include "u8g.h" 00046 00047 #if defined(ARDUINO) 00048 00049 #if ARDUINO < 100 00050 #include <WProgram.h> 00051 #include "wiring_private.h" 00052 #include "pins_arduino.h" 00053 00054 #else 00055 #include <Arduino.h> 00056 #include "wiring_private.h" 00057 #endif 00058 00059 #if defined(__AVR__) 00060 00061 uint8_t u8g_bitData, u8g_bitNotData; 00062 uint8_t u8g_bitClock, u8g_bitNotClock; 00063 volatile uint8_t *u8g_outData; 00064 volatile uint8_t *u8g_outClock; 00065 00066 static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) 00067 { 00068 u8g_outData = portOutputRegister(digitalPinToPort(dataPin)); 00069 u8g_outClock = portOutputRegister(digitalPinToPort(clockPin)); 00070 u8g_bitData = digitalPinToBitMask(dataPin); 00071 u8g_bitClock = digitalPinToBitMask(clockPin); 00072 00073 u8g_bitNotClock = u8g_bitClock; 00074 u8g_bitNotClock ^= 0x0ff; 00075 00076 u8g_bitNotData = u8g_bitData; 00077 u8g_bitNotData ^= 0x0ff; 00078 } 00079 00080 static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) U8G_NOINLINE; 00081 static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) 00082 { 00083 uint8_t cnt = 8; 00084 uint8_t bitData = u8g_bitData; 00085 uint8_t bitNotData = u8g_bitNotData; 00086 uint8_t bitClock = u8g_bitClock; 00087 uint8_t bitNotClock = u8g_bitNotClock; 00088 volatile uint8_t *outData = u8g_outData; 00089 volatile uint8_t *outClock = u8g_outClock; 00090 00091 00092 U8G_ATOMIC_START(); 00093 bitData |= *outData; 00094 bitNotData &= *outData; 00095 do 00096 { 00097 if ( val & 128 ) 00098 *outData = bitData; 00099 else 00100 *outData = bitNotData; 00101 00102 /* 00103 *outClock |= bitClock; 00104 val <<= 1; 00105 cnt--; 00106 *outClock &= bitNotClock; 00107 */ 00108 00109 val <<= 1; 00110 *outClock &= bitNotClock; 00111 cnt--; 00112 // removed micro delays, because AVRs are too slow and the delay is not required 00113 //u8g_MicroDelay(); 00114 *outClock |= bitClock; 00115 //u8g_MicroDelay(); 00116 } while( cnt != 0 ); 00117 U8G_ATOMIC_END(); 00118 } 00119 00120 #elif defined(__18CXX) || defined(__PIC32MX) 00121 00122 uint16_t dog_bitData, dog_bitNotData; 00123 uint16_t dog_bitClock, dog_bitNotClock; 00124 volatile uint32_t *dog_outData; 00125 volatile uint32_t *dog_outClock; 00126 volatile uint32_t dog_pic32_spi_tmp; 00127 00128 static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) 00129 { 00130 dog_outData = portOutputRegister(digitalPinToPort(dataPin)); 00131 dog_outClock = portOutputRegister(digitalPinToPort(clockPin)); 00132 dog_bitData = digitalPinToBitMask(dataPin); 00133 dog_bitClock = digitalPinToBitMask(clockPin); 00134 00135 dog_bitNotClock = dog_bitClock; 00136 dog_bitNotClock ^= 0x0ffff; 00137 00138 dog_bitNotData = dog_bitData; 00139 dog_bitNotData ^= 0x0ffff; 00140 } 00141 00142 static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) 00143 { 00144 uint8_t cnt = 8; 00145 U8G_ATOMIC_START(); 00146 do 00147 { 00148 if ( val & 128 ) 00149 *dog_outData |= dog_bitData; 00150 else 00151 *dog_outData &= dog_bitNotData; 00152 val <<= 1; 00153 //u8g_MicroDelay(); 00154 //*dog_outClock |= dog_bitClock; 00155 *dog_outClock &= dog_bitNotClock; 00156 cnt--; 00157 u8g_MicroDelay(); 00158 //*dog_outClock &= dog_bitNotClock; 00159 *dog_outClock |= dog_bitClock; 00160 u8g_MicroDelay(); 00161 00162 } while( cnt != 0 ); 00163 U8G_ATOMIC_END(); 00164 } 00165 00166 #else 00167 00168 /* default interface, Arduino DUE (__arm__) */ 00169 00170 uint8_t u8g_data_pin; 00171 uint8_t u8g_clock_pin; 00172 00173 static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) 00174 { 00175 u8g_data_pin = dataPin; 00176 u8g_clock_pin = clockPin; 00177 } 00178 00179 static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) 00180 { 00181 uint8_t cnt = 8; 00182 do 00183 { 00184 if ( val & 128 ) 00185 digitalWrite(u8g_data_pin, HIGH); 00186 else 00187 digitalWrite(u8g_data_pin, LOW); 00188 val <<= 1; 00189 //u8g_MicroDelay(); 00190 digitalWrite(u8g_clock_pin, LOW); 00191 cnt--; 00192 u8g_MicroDelay(); 00193 digitalWrite(u8g_clock_pin, HIGH); 00194 u8g_MicroDelay(); 00195 } while( cnt != 0 ); 00196 } 00197 00198 #endif 00199 00200 00201 static void u8g_com_arduino_st7920_write_byte_seq(uint8_t rs, uint8_t *ptr, uint8_t len) 00202 { 00203 uint8_t i; 00204 00205 if ( rs == 0 ) 00206 { 00207 /* command */ 00208 u8g_com_arduino_do_shift_out_msb_first(0x0f8); 00209 } 00210 else if ( rs == 1 ) 00211 { 00212 /* data */ 00213 u8g_com_arduino_do_shift_out_msb_first(0x0fa); 00214 } 00215 00216 while( len > 0 ) 00217 { 00218 u8g_com_arduino_do_shift_out_msb_first(*ptr & 0x0f0); 00219 u8g_com_arduino_do_shift_out_msb_first(*ptr << 4); 00220 ptr++; 00221 len--; 00222 u8g_10MicroDelay(); 00223 } 00224 00225 for( i = 0; i < 4; i++ ) 00226 u8g_10MicroDelay(); 00227 } 00228 00229 static void u8g_com_arduino_st7920_write_byte(uint8_t rs, uint8_t val) 00230 { 00231 uint8_t i; 00232 00233 if ( rs == 0 ) 00234 { 00235 /* command */ 00236 u8g_com_arduino_do_shift_out_msb_first(0x0f8); 00237 } 00238 else if ( rs == 1 ) 00239 { 00240 /* data */ 00241 u8g_com_arduino_do_shift_out_msb_first(0x0fa); 00242 } 00243 00244 u8g_com_arduino_do_shift_out_msb_first(val & 0x0f0); 00245 u8g_com_arduino_do_shift_out_msb_first(val << 4); 00246 00247 for( i = 0; i < 4; i++ ) 00248 u8g_10MicroDelay(); 00249 00250 } 00251 00252 00253 uint8_t u8g_com_arduino_st7920_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) 00254 { 00255 switch(msg) 00256 { 00257 case U8G_COM_MSG_INIT: 00258 u8g_com_arduino_assign_pin_output_high(u8g); 00259 u8g_com_arduino_digital_write(u8g, U8G_PI_CS, LOW); 00260 // u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, LOW); 00261 u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, HIGH); 00262 u8g_com_arduino_digital_write(u8g, U8G_PI_MOSI, LOW); 00263 u8g_com_arduino_init_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK]); 00264 u8g->pin_list[U8G_PI_A0_STATE] = 0; /* inital RS state: command mode */ 00265 break; 00266 00267 case U8G_COM_MSG_STOP: 00268 break; 00269 00270 case U8G_COM_MSG_RESET: 00271 if ( u8g->pin_list[U8G_PI_RESET] != U8G_PIN_NONE ) 00272 u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); 00273 break; 00274 00275 case U8G_COM_MSG_CHIP_SELECT: 00276 if ( arg_val == 0 ) 00277 { 00278 /* disable, note: the st7920 has an active high chip select */ 00279 u8g_com_arduino_digital_write(u8g, U8G_PI_CS, LOW); 00280 } 00281 else 00282 { 00283 /* enable */ 00284 //u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, HIGH); 00285 u8g_com_arduino_digital_write(u8g, U8G_PI_CS, HIGH); 00286 } 00287 break; 00288 00289 case U8G_COM_MSG_WRITE_BYTE: 00290 u8g_com_arduino_st7920_write_byte( u8g->pin_list[U8G_PI_A0_STATE], arg_val); 00291 //u8g->pin_list[U8G_PI_A0_STATE] = 2; 00292 //u8g_arduino_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val); 00293 break; 00294 00295 case U8G_COM_MSG_WRITE_SEQ: 00296 u8g_com_arduino_st7920_write_byte_seq(u8g->pin_list[U8G_PI_A0_STATE], (uint8_t *)arg_ptr, arg_val); 00297 break; 00298 00299 case U8G_COM_MSG_WRITE_SEQ_P: 00300 { 00301 register uint8_t *ptr = arg_ptr; 00302 while( arg_val > 0 ) 00303 { 00304 u8g_com_arduino_st7920_write_byte(u8g->pin_list[U8G_PI_A0_STATE], u8g_pgm_read(ptr) ); 00305 //u8g->pin_list[U8G_PI_A0_STATE] = 2; 00306 ptr++; 00307 arg_val--; 00308 } 00309 } 00310 break; 00311 00312 case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ 00313 u8g->pin_list[U8G_PI_A0_STATE] = arg_val; 00314 break; 00315 } 00316 return 1; 00317 } 00318 00319 #else /* ARDUINO */ 00320 00321 uint8_t u8g_com_arduino_st7920_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) 00322 { 00323 return 1; 00324 } 00325 00326 #endif /* ARDUINO */ 00327 00328
Generated on Tue Jul 12 2022 17:30:57 by
1.7.2