iforce2d Chris / Mbed 2 deprecated ubxDistanceMeter

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers u8g_com_arduino_st7920_spi.c Source File

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