Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2010, Loughborough University - Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 */ 00031 00032 /** 00033 * \file 00034 * This file provides functions to control various chips on the 00035 * Sensinode N740s: 00036 * 00037 * - The 74HC595D is an 8-bit serial in-parallel out shift register. 00038 * LEDs are connected to this chip. It also serves other functions such as 00039 * enabling/disabling the Accelerometer (see n740.h). 00040 * - The 74HC4053D is a triple, 2-channel analog mux/de-mux. 00041 * It switches I/O between the USB and the D-Connector. 00042 * It also controls P0_0 input source (Light Sensor / External I/O) 00043 * 00044 * Mux/De-mux: Connected to P0_3 (set to output in models.c 00045 * Changing the state of the mux/demux can have catastrophic (tm) results 00046 * on our software. If we are not careful, we risk entering a state where 00047 * UART1 RX interrupts are being generated non-stop. Only change its state 00048 * via the function in this file. 00049 * 00050 * Shift Register: 00051 * For the shift register we can: 00052 * - write a new instruction 00053 * - remember and retrieve the last instruction sent 00054 * 00055 * The chip is connected to CPU pins as follows: 00056 * - P0_2: Serial Data Input 00057 * - P1_3: Shift Register Clock Input 00058 * - P1_1: Storage Register Clock 00059 * 00060 * This file can be placed in any bank. 00061 * 00062 * \author 00063 * George Oikonomou - <oikonomou@users.sourceforge.net> 00064 */ 00065 00066 #include "dev/n740.h" 00067 #include "dev/uart1.h" 00068 00069 /* 00070 * This variable stores the most recent instruction sent to the ser-par chip. 00071 * We declare it as static and return its value through n740_ser_par_get(). 00072 */ 00073 static __data uint8_t ser_par_status; 00074 00075 /*---------------------------------------------------------------------------*/ 00076 /* Init the serial-parallel chip: 00077 * - Set I/O direction for all 3 pins (P0_2, P1_1 and P1_3) to output 00078 */ 00079 void 00080 n740_ser_par_init() 00081 { 00082 /* bus_init and uart1_init also touch the I/O direction for those pins */ 00083 P1DIR |= 0x0A; 00084 P0DIR |= 0x04; 00085 } 00086 /*---------------------------------------------------------------------------*/ 00087 /* 00088 * Send a command to the N740 serial-parallel chip. Each command is a single 00089 * byte, each bit controls a different feature on the sensor. 00090 */ 00091 void 00092 n740_ser_par_set(uint8_t data) 00093 { 00094 uint8_t i; 00095 uint8_t mask = 1; 00096 uint8_t temp = 0; 00097 00098 DISABLE_INTERRUPTS(); 00099 /* bit-by-bit */ 00100 for(i = 0; i < 8; i++) { 00101 temp = (data & mask); 00102 /* Is the bit set? */ 00103 if(i && temp) { 00104 /* If it was set, we want to send 1 */ 00105 temp >>= i; 00106 } 00107 /* Send the bit */ 00108 P0_2 = temp; 00109 /* Shift */ 00110 P1_3 = 1; 00111 P1_3 = 0; 00112 mask <<= 1; 00113 } 00114 /* Move to Par-Out */ 00115 P1_1 = 1; 00116 P1_1 = 0; 00117 ENABLE_INTERRUPTS(); 00118 00119 /* Right, we're done. Save the new status in ser_par_status */ 00120 ser_par_status = data; 00121 } 00122 /*---------------------------------------------------------------------------*/ 00123 /* This function returns the last value sent to the ser-par chip on the N740. 00124 * 00125 * The caveat here is that we must always use n740_set_ser_par() to send 00126 * commands to the ser-par chip, never write directly. 00127 * 00128 * If any other function sends a command directly, ser_par_status and the 00129 * actual status will end up out of sync. 00130 */ 00131 uint8_t 00132 n740_ser_par_get() 00133 { 00134 return ser_par_status; 00135 } 00136 /*---------------------------------------------------------------------------*/ 00137 void 00138 n740_analog_switch(uint8_t state) 00139 { 00140 /* Turn off the UART RX interrupt before switching */ 00141 DISABLE_INTERRUPTS(); 00142 UART1_RX_INT(0); 00143 00144 /* Switch */ 00145 P0_3 = state; 00146 00147 /* If P0_3 now points to the USB and nothing is flowing down P1_7, 00148 * enable the interrupt again */ 00149 if(P1_7 == 1 && P0_3 == N740_ANALOG_SWITCH_USB) { 00150 UART1_RX_INT(1); 00151 } 00152 ENABLE_INTERRUPTS(); 00153 } 00154 /*---------------------------------------------------------------------------*/ 00155 /* 00156 * Activate the the 74HC4053D analog switch U5 on the N740 and at the same 00157 * time set relevant pins to Peripheral I/O mode. This stops communications 00158 * with the serial flash and enables UART1 I/O 00159 */ 00160 void 00161 n740_analog_activate() 00162 { 00163 uint8_t ser_par = n740_ser_par_get(); 00164 ser_par &= ~N740_SER_PAR_U5_ENABLE; /* Turn on */ 00165 00166 N740_PINS_PER_IO(); 00167 00168 n740_ser_par_set(ser_par); 00169 } 00170 /*---------------------------------------------------------------------------*/ 00171 /* 00172 * De-Activate the the 74HC4053D analog switch U5 on the N740 and at the same 00173 * time set relevant pins to GP I/O mode. This effectively prepares us to 00174 * start talking with the serial flash chip 00175 */ 00176 void 00177 n740_analog_deactivate() 00178 { 00179 uint8_t ser_par = n740_ser_par_get(); 00180 ser_par |= N740_SER_PAR_U5_ENABLE; /* Turn off */ 00181 00182 n740_ser_par_set(ser_par); 00183 00184 N740_PINS_GPIO(); 00185 } 00186 /*---------------------------------------------------------------------------*/