Post It

Dependencies:   LM75B

Fork of EM027BS013 by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EPD_hardware_driver.cpp Source File

EPD_hardware_driver.cpp

Go to the documentation of this file.
00001 /**
00002  * \file
00003  *
00004  * \brief The initialization and configuration of COG hardware driver
00005  *
00006  * Copyright (c) 2012-2014 Pervasive Displays Inc. All rights reserved.
00007  *
00008  *  Authors: Pervasive Displays Inc.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *  1. Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *  2. Redistributions in binary form must reproduce the above copyright
00017  *     notice, this list of conditions and the following disclaimer in
00018  *     the documentation and/or other materials provided with the
00019  *     distribution.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00024  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00025  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00027  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00028  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00029  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00031  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032  */
00033 
00034 //#include <math.h>
00035 #include "EPD_hardware_driver.h"
00036 
00037 static  uint16_t EPD_Counter;
00038 static uint8_t spi_flag = FALSE;
00039 
00040 #include "mbed.h"
00041 #include "LM75B.h"
00042 static Ticker systemTicker;
00043 static SPI* expSPI = NULL;
00044 static LM75B* expLM75B = NULL;
00045 void SysTick_Handler(void);
00046 
00047 extern PinName SEC03;
00048 extern PinName SEC04;
00049 extern PinName SEC05;
00050 extern PinName SEC09;
00051 extern PinName SEC10;
00052 
00053 
00054 /**
00055  * \brief Set up EPD Timer for 1 mSec interrupts
00056  *
00057  * \note
00058  * desired value: 1mSec
00059  * actual value:  1.000mSec
00060  */
00061 static void initialize_EPD_timer(void) {
00062     //------------------Timer A1----------------------------------------
00063     //set up Timer_A CCR1 as master timer using ACLK    
00064 //  TA0CCTL2 &= ~(CCIFG | CCIE); // reset CCIFG Interrupt Flag
00065 //  TA0CTL = TASSEL_2 + MC_0 + TACLR + ID_3;
00066 //  TA0CCTL2 = OUTMOD_4;
00067     EPD_Counter = 0;
00068 }
00069 
00070 /**
00071  * \brief Start Timer
00072  */
00073 void start_EPD_timer(void) {
00074     initialize_EPD_timer();
00075 //  TA0R = 0;
00076 //  TA0CCR0 = 990 * 2; // 1ms
00077 //  TA0CCTL2 |= CCIE;
00078 //  TA0CTL |= MC_1;
00079     EPD_Counter = 0;
00080     systemTicker.attach_us(&SysTick_Handler, 1000);
00081 }
00082 
00083 /**
00084  * \brief Stop Timer
00085  */
00086 void stop_EPD_timer(void) {
00087 //  TA0CCTL2 &= ~CCIE;
00088 //  TA0CTL &= ~MC_1;
00089     systemTicker.detach();
00090 }
00091 
00092 /**
00093  * \brief Get current Timer after starting a new one
00094  */
00095 uint32_t get_current_time_tick(void) {
00096     return EPD_Counter;
00097 }
00098 /**
00099  * \brief Set current Timer after starting a new one
00100  */
00101 void set_current_time_tick(uint32_t count) {
00102      EPD_Counter=count;
00103 }
00104 /**
00105  * \brief Interrupt Service Routine for system tick counter
00106  */
00107 void SysTick_Handler(void) {
00108     EPD_Counter++;
00109 }
00110 
00111 ///**
00112 // * \brief Interrupt Service Routine for Timer A0
00113 // */
00114 //#pragma vector=TIMER0_A1_VECTOR
00115 //__interrupt void Timer_A0(void) {
00116 //  switch (__even_in_range(TA0IV, 10)) {
00117 //  case 2:
00118 //      //LPM3_EXIT;
00119 //      break;
00120 
00121 //  case 4:
00122 //      EPD_Counter++;
00123 //      LPM3_EXIT;
00124 //      break;
00125 //  }
00126 
00127 //}
00128 
00129 /**
00130  * \brief Delay mini-seconds
00131  * \param ms The number of mini-seconds
00132  */
00133 void delay_ms(unsigned int ms) {
00134 //  while (ms--) {
00135 //      __delay_cycles(SMCLK_FREQ / 1000);
00136 //  }
00137     wait_ms(ms);
00138 }
00139 
00140 /**
00141  * \brief Delay mini-seconds
00142  * \param ms The number of mini-seconds
00143  */
00144 void sys_delay_ms(unsigned int ms) {
00145 //  delay_ms(ms);
00146     wait_ms(ms);
00147 }
00148 
00149 static void Wait_10us(void) {
00150 //  __delay_cycles(SMCLK_FREQ / 100000);
00151     wait_us(10);
00152 }
00153 
00154 //******************************************************************
00155 //* PWM  Configuration/Control //PWM output : PD3
00156 //******************************************************************
00157 
00158 /**
00159  * \brief The PWM signal starts toggling
00160  */
00161 void PWM_start_toggle(void) {
00162 
00163 }
00164 
00165 /**
00166  * \brief The PWM signal stops toggling.
00167  */
00168 void PWM_stop_toggle(void) {
00169 
00170 }
00171 
00172 /**
00173  * \brief PWM toggling.
00174  *
00175  * \param ms The interval of PWM toggling (mini seconds)
00176  */
00177 void PWM_run(uint16_t ms) {
00178 //  start_EPD_timer();
00179 //  do {
00180 //      EPD_pwm_high();
00181 //      __delay_cycles(30);
00182 //      EPD_pwm_low();
00183 //      __delay_cycles(30);
00184 //  } while (get_current_time_tick() < ms); //wait Delay Time
00185 //  stop_EPD_timer();
00186     mbed_die();
00187 }
00188 
00189 //******************************************************************
00190 //* SPI  Configuration
00191 //******************************************************************
00192 
00193 /**
00194  * \brief Configure SPI
00195  */
00196 void epd_spi_init(void) {
00197     if (spi_flag)
00198         return;
00199     spi_flag = TRUE;
00200 //  //config  i/o
00201 //  config_gpio_dir_o(SPICLK_PORT, SPICLK_PIN);
00202 //  config_gpio_dir_o(SPIMOSI_PORT, SPIMOSI_PIN);
00203 //  config_gpio_dir_i(SPIMISO_PORT, SPIMISO_PIN);
00204 
00205 //  BITSET(SPISEL, SPICLK_PIN + SPIMOSI_PIN + SPIMISO_PIN);
00206 //  BITSET(SPISEL2, SPICLK_PIN + SPIMOSI_PIN + SPIMISO_PIN);
00207 //  //comfig SPI
00208 //  SPICTL0 = UCCKPH | UCMST | UCSYNC | UCMSB;
00209 //  SPICTL1 = UCSSEL_2 + UCSWRST;
00210 //  SPIBR0 = 2; //16MHz/2=8MHz
00211 //  SPIBR1 = 0;
00212 
00213 //  BITSET(REN (SPIMISO_PORT), SPIMISO_PIN);
00214 //  BITCLR(SPICTL1, UCSWRST);
00215     
00216     expSPI = new SPI(SEC04, SEC05, SEC03);   // mosi, miso, sclk
00217     expSPI->frequency(COG_SPI_baudrate);
00218 }
00219 
00220 /**
00221  * \brief Initialize SPI
00222  */
00223 void epd_spi_attach(void) {
00224     EPD_flash_cs_high();
00225     EPD_cs_high();
00226     epd_spi_init();
00227 }
00228 
00229 /**
00230  * \brief Disable SPI and change to GPIO
00231  */
00232 void epd_spi_detach(void) {
00233 //  BITCLR(SPISEL, SPICLK_PIN + SPIMOSI_PIN + SPIMISO_PIN);
00234 //  BITCLR(SPISEL2, SPICLK_PIN + SPIMOSI_PIN + SPIMISO_PIN);
00235 //  //config_gpio_dir_o(SPICLK_PORT,SPICLK_PIN);
00236 //  //config_gpio_dir_o(SPIMOSI_PORT,SPIMOSI_PIN);
00237 //  //config_gpio_dir_o(SPIMISO_PORT,SPIMISO_PIN);
00238 //  SPIMISO_low();
00239 //  SPIMOSI_low();
00240 //  SPICLK_low();
00241     if (expSPI != NULL) {
00242         delete expSPI;
00243         expSPI = NULL;
00244     }
00245     spi_flag = FALSE;
00246 }
00247 
00248 /**
00249  * \brief SPI synchronous write
00250  */
00251 void epd_spi_write(unsigned char Data) {
00252 //  SPITXBUF = Data;
00253 //  while (!(SPIIFG & SPITXIFG))
00254 //      ;
00255     expSPI->write(Data);
00256 }
00257 
00258 /**
00259  * \brief SPI synchronous read
00260  */
00261 uint8_t epd_spi_read(unsigned char RDATA) {
00262 //  SPITXBUF = RDATA;
00263 //  while ((SPISTAT & UCBUSY))
00264 //      ;
00265 //  RDATA = SPIRXBUF;
00266 //  return RDATA;
00267     return expSPI->write(RDATA) & 0xff;
00268 }
00269 
00270 /**
00271  * \brief Send data to SPI with time out feature
00272  *
00273  * \param data The data to be sent out
00274  */
00275 uint8_t epd_spi_write_ex(unsigned char Data) {
00276 //  uint8_t cnt = 200;
00277 //  uint8_t flag = 1;
00278 //  SPITXBUF = Data;
00279 //  while (!(SPIIFG & SPITXIFG)) {
00280 //      if ((cnt--) == 0) {
00281 //          flag = 0;
00282 //          break;
00283 //      }
00284 //  }
00285 //  return flag;
00286 
00287     // Not used
00288     mbed_die();
00289     return 0;
00290 }
00291 
00292 #if (defined COG_V230_G2)
00293 /**
00294 * \brief SPI command
00295 *
00296 * \param register_index The Register Index as SPI Data to COG
00297 * \param register_data The Register Data for sending command data to COG
00298 * \return the SPI read value
00299 */
00300 uint8_t SPI_R(uint8_t Register, uint8_t Data) {
00301     uint8_t result;
00302     EPD_cs_low ();
00303     epd_spi_write (0x70); // header of Register Index
00304     epd_spi_write (Register);
00305 
00306     EPD_cs_high ();
00307     Wait_10us ();
00308     EPD_cs_low ();
00309 
00310     epd_spi_write (0x73); // header of Register Data of read command
00311     result=epd_spi_read (Data);
00312 
00313     EPD_cs_high ();
00314 
00315     return result;
00316 }
00317 #endif
00318 
00319 /**
00320 * \brief SPI command if register data is larger than two bytes
00321 *
00322 * \param register_index The Register Index as SPI command to COG
00323 * \param register_data The Register Data for sending command data to COG
00324 * \param length The number of bytes of Register Data which depends on which
00325 * Register Index is selected.
00326 */
00327 void epd_spi_send (unsigned char register_index, unsigned char *register_data,
00328                unsigned length) {
00329     EPD_cs_low ();
00330     epd_spi_write (0x70); // header of Register Index
00331     epd_spi_write (register_index);
00332 
00333     EPD_cs_high ();
00334     Wait_10us ();
00335     EPD_cs_low ();
00336 
00337     epd_spi_write (0x72); // header of Register Data of write command
00338     while(length--) {
00339         epd_spi_write (*register_data++);
00340     }
00341     EPD_cs_high ();
00342 }
00343 
00344 /**
00345 * \brief SPI command
00346 *
00347 * \param register_index The Register Index as SPI command to COG
00348 * \param register_data The Register Data for sending command data to COG
00349 */
00350 void epd_spi_send_byte (uint8_t register_index, uint8_t register_data) {
00351     EPD_cs_low ();
00352     epd_spi_write (0x70); // header of Register Index
00353     epd_spi_write (register_index);
00354 
00355     EPD_cs_high ();
00356     Wait_10us ();
00357     EPD_cs_low ();
00358     epd_spi_write (0x72); // header of Register Data
00359     epd_spi_write (register_data);
00360     EPD_cs_high ();
00361 }
00362 
00363 //******************************************************************
00364 //* Temperature sensor  Configuration
00365 //******************************************************************
00366 #ifdef __Internal_Temperature_Sensor
00367 // ADC10 interrupt service routine
00368 #pragma vector=ADC10_VECTOR
00369 __interrupt void ADC10_ISR(void) {
00370     __bic_SR_register_on_exit(CPUOFF);
00371     // Clear CPUOFF bit from 0(SR)
00372 }
00373 /**
00374  * \brief Get temperature value from ADC
00375  *
00376  * \return the Celsius temperature
00377  */
00378 int16_t get_temperature(void) {
00379     const uint8_t DegCOffset=0;
00380     long temp;
00381     float IntDegC;
00382 
00383     ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4
00384     ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON+ADC10IE;
00385     ADC10CTL0 |= ENC + ADC10SC;// Sampling and conversion start
00386     __bis_SR_register(CPUOFF + GIE);// LPM0, ADC10_ISR will force exit
00387     // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
00388     temp = ADC10MEM;
00389 
00390     ADC10CTL0 |= ENC + ADC10SC;// Sampling and conversion start
00391     __bis_SR_register(CPUOFF + GIE);// LPM0, ADC10_ISR will force exit
00392     temp = ADC10MEM;
00393     ADC10CTL0 |= ENC + ADC10SC;// Sampling and conversion start
00394     __bis_SR_register(CPUOFF + GIE);// LPM0, ADC10_ISR will force exit
00395     temp += ADC10MEM;
00396     temp=temp/2;
00397 
00398     IntDegC =(long)((long)(temp*423)/1024)-(278+DegCOffset);//(long)((long)(temp - 673) * 423) / 1024;
00399 
00400     __no_operation();// SET BREAKPOINT HERE
00401 
00402     return (int8_t) IntDegC;
00403 }
00404 #elif defined __External_Temperature_Sensor
00405 
00406 /**
00407  * \brief Get temperature value from ADC
00408  *
00409  * \return the Celsius temperature
00410  */
00411 int16_t get_temperature(void) {
00412 //  float IntDegC;
00413 //  const uint8_t DegCOffset = 2;
00414 //  long temp;
00415 //  ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
00416 //  __bis_SR_register(CPUOFF + GIE);
00417 //  // LPM0, ADC10_ISR will force exit
00418 //  temp = ADC10MEM;
00419 
00420 //  ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
00421 //  __bis_SR_register(CPUOFF + GIE);
00422 //  // LPM0, ADC10_ISR will force exit
00423 //  temp = ADC10MEM;
00424 //  ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
00425 //  __bis_SR_register(CPUOFF + GIE);
00426 //  // LPM0, ADC10_ISR will force exit
00427 //  temp = ADC10MEM;
00428 //  ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
00429 //  __bis_SR_register(CPUOFF + GIE);
00430 //  // LPM0, ADC10_ISR will force exit
00431 //  temp = ADC10MEM;
00432 
00433 //  //org
00434 //  /*
00435 //   temp = (ADC10MEM*5)/2;
00436 //   voltage = (float)((float)temp*2.5)/1024.0;         //(2.5/1024)*ADC=Mcu voltage,Temperature voltage=Mcu voltage*2
00437 //   IntDegC=100.0- (((voltage*1000)/10.77)-111.3);     //100-((Temperature voltage-1.199)*1000)/10.77=IntDegC
00438 //   __no_operation();                    // SET BREAKPOINT HERE
00439 //   */
00440 //  //adj
00441 //  // IntDegC=(203-DegCOffset)-((long)((7*temp)/128)+(temp/2));
00442 //  IntDegC = (201 - DegCOffset) - ((long) ((5 * temp) / 128) + (temp / 2));
00443 //  return (int16_t) IntDegC;
00444 
00445     float f = *expLM75B;
00446     return (int)f;
00447 }
00448 
00449 #endif
00450 
00451 /**
00452  * \brief Initialize the temperature sensor
00453  */
00454 void initialize_temperature(void) {
00455 #ifdef __External_Temperature_Sensor
00456 
00457     //Create an LM75B object at 0x92/0x93 (ADDRESS_1)
00458         expLM75B = new LM75B(SEC10, SEC09, LM75B::ADDRESS_1); // Requires JP8 and JP9 in 1-2 position to avoid interference from LM75 on ARM University BB
00459   
00460     //Try to open the LM75B
00461     if (!expLM75B->open()) {
00462 //      mbed_die();
00463     }
00464 //  ADC10CTL0 = SREF_1 + ADC10SHT_3 + ADC10ON + ADC10IE + REFON + REF2_5V; // ADC10ON, interrupt enabled
00465 //  ADC10CTL1 = INCH_4 + ADC10DIV_3; // input A1.4
00466 
00467 #endif
00468 }
00469 
00470 /**
00471  * \brief Initialize the EPD hardware setting
00472  */
00473 void EPD_display_hardware_init(void) {
00474     EPD_initialize_gpio();
00475     EPD_Vcc_turn_off();
00476     epd_spi_init();
00477     initialize_temperature();
00478     EPD_cs_low();
00479     EPD_pwm_low();
00480     EPD_rst_low();
00481     EPD_discharge_low();
00482     EPD_border_low();
00483     //initialize_EPD_timer();
00484 }
00485