Jim Cooke
/
Hat_Board_v5_1
Slight Mod
Fork of Hat_Board_v5 by
Revision 0:34bad5aca893, committed 2014-03-20
- Comitter:
- drnow
- Date:
- Thu Mar 20 02:50:57 2014 +0000
- Child:
- 1:2efeed26d93a
- Commit message:
- works with x
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SI_LIS.cpp Thu Mar 20 02:50:57 2014 +0000 @@ -0,0 +1,166 @@ + +#include "SI_LIS.h" + +I2C i2c(p9, p10); // (SDA,SCL) +int bias1,bias2,bias3,PS1,PS2,PS3,VIS; +unsigned char LowB,HighB; +unsigned int IR; +extern char rx_data[4]; +extern char accel_2_data[2]; +extern char accel_data; + +void restart() +{ + wait_ms(30); + i2c.frequency(400000); + command(RESET); + wait_ms(30); + + write_reg(HW_KEY,HW_KEY_VAL0); + write_reg(PS_LED21,0x41); // values when Si1142 and LED's put into hat + write_reg(PS_LED3,0x00); + + // CHLIST Parameter + write_reg(PARAM_WR, PS1_TASK + PS2_TASK); //use PS1, PS2 to fire LED's + command(PARAM_SET + (CHLIST & 0x1F)); + + // PS Gain: by factor of (2 ^ PS_ADC_GAIN). Max gain: 128 (0x7). + write_reg(PARAM_WR, 0x03); + command(PARAM_SET + (PS_ADC_GAIN & 0x1F)); + + // PS_ADC_COUNTER (Recommend one’s complement of PS_ADC_GAIN.) + write_reg(PARAM_WR, 0x40); + command(PARAM_SET + (PS_ADC_COUNTER & 0x1F)); + + // ADC_OFFSET (adds to reported so there's no confusion with 0xFFFF overrange indicator) reset: 0x80 + write_reg(PARAM_WR, 0x00); + command(PARAM_SET + (ADC_OFFSET & 0x1F)); + + // PS_Encoding (Bit 5: When set, ADC reports least significant 16 bits of 17-bit ADC + // Current Concept: don't set, but gain it up by another 2x + + write_reg(INT_CFG,1); //set bit 0 to 1. Requires clearing interrupt pin + + // IRQ_ENABLE 0x04: Bit 3: PS2_IE Bit 2: PS1_IE + write_reg(IRQ_ENABLE,0x04); + + //IRQ_MODE1: 00: PS1_INT is set whenever a PS1 measurement has completed. + write_reg(IRQ_MODE1,0); + write_reg(IRQ_MODE2,0); + + wait_ms(30); + + write_reg(MEAS_RATE,0x20); //0x84 should be every 10 ms. Need calcs if less than that + wait_ms(30); + write_reg(PS_RATE,0x08); //this should be a multiplier of 1 + wait_ms(30); +} + +void command_test() +{ + write_reg(COMMAND,NOP); +} + +void command(char cmd) +{ + int val; + + val = read_reg(RESPONSE,1); + while(val!=0) { + write_reg(COMMAND,NOP); + val = read_reg(RESPONSE,1); + } + do { + write_reg(COMMAND,cmd); + if(cmd==RESET) break; + val = read_reg(RESPONSE,1); + } while(val==0); +} + +int command2(char cmd) +{ + int val; + int i = 0; + do { + write_reg(COMMAND,cmd); + val = read_reg(RESPONSE,1); + i = i+1; + } while(val==0); + return val; +} + +void command3(char cmd) +{ + write_reg(COMMAND,cmd); +} + +char read_reg2 (/*unsigned*/ char address) // Read a register +{ + char tx[1]; + tx[0] = address; + i2c.write((IR_ADDRESS << 1) & 0xFE, tx, 1); + + i2c.read((IR_ADDRESS << 1) | 0x01, rx_data, 4); + return 0; +} + + +char read_reg (/*unsigned*/ char address, int num_data) // Read a register +{ + char tx[1]; + char rx[1]; + tx[0] = address; + i2c.write((IR_ADDRESS << 1) & 0xFE, tx, num_data); + + i2c.read((IR_ADDRESS << 1) | 0x01, rx, num_data); + return rx[0]; +} + +void write_reg(char address, char num_data) // Write a resigter +{ + char tx[2]; + + tx[0] = address; + tx[1] = num_data; + i2c.write((IR_ADDRESS << 1) & 0xFE, tx, 2); +} + +void Init_Accel (char Reg_Num, char Reg_Val) +{ + char data[2]; + data[0] = Reg_Num; //register to be written to + data[1] = Reg_Val; //data + + i2c.write((LIS_Addr << 1) & 0xFE, data, 2); +} + +void Get_Accel_Register (char Reg_Num) +{ + char data; + char reg; + + reg = Reg_Num; + + i2c.write((LIS_Addr << 1) & 0xFE , ®, 1 ); // Write register number + i2c.read ((LIS_Addr << 1) | 0x01, &data, 1 ); // Receive Byte from Slave + accel_data = data; +} + +void Get_Accel_Register_2 (char Reg_Num) // Read 2 registers +/* +In order to read multiple bytes, it is necessary to assert the most significant bit of the subaddress +field. In other words, SUB(7) must be equal to 1 while SUB(6-0) represents the +address of first register to be read. +*/ +{ + char reg; + reg = Reg_Num | 0x80; // set bit 7 high + i2c.write((LIS_Addr << 1) & 0xFE, ®, 1); + i2c.read((LIS_Addr << 1) | 0x01, accel_2_data, 2); +} + +void i2c_start() // also set by photodiode setup/reset +{ + i2c.frequency(400000); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SI_LIS.h Thu Mar 20 02:50:57 2014 +0000 @@ -0,0 +1,163 @@ + +#ifndef SI_LIS_h +#define SI_LIS_h + +#include "mbed.h" + +#define IR_ADDRESS 0x5A +#define LIS_Addr 0x18 +#define HW_KEY_VAL0 0x17 //Value to write into the HW Key register + +// Register Addresses + +#define PART_ID 0x00 +#define REV_ID 0x01 +#define SEQ_ID 0x02 //Si114x-A11 (MAJOR_SEQ=1, MINOR_SEQ=1) +#define INT_CFG 0x03 +#define IRQ_ENABLE 0x04 +#define IRQ_MODE1 0x05 +#define IRQ_MODE2 0x06 +#define HW_KEY 0x07 + +#define MEAS_RATE 0x08 +#define ALS_RATE 0x09 +#define PS_RATE 0x0A + +#define ALS_LOW_TH0 0x0B +#define ALS_LOW_TH1 0x0C +#define ALS_HI_TH0 0x0D +#define ALS_HI_TH1 0x0E + +#define PS_LED21 0x0F +#define PS_LED3 0x10 + +#define PS1_TH0 0x11 +#define PS1_TH1 0x12 +#define PS2_TH0 0x13 +#define PS2_TH1 0x14 +#define PS3_TH0 0x15 + +#define PS3_TH1 0x16 +#define PARAM_WR 0x17 +#define COMMAND 0x18 + +#define RESPONSE 0x20 +#define IRQ_STATUS 0x21 + +#define ALS_VIS_DATA0 0x22 +#define ALS_VIS_DATA1 0x23 +#define ALS_IR_DATA0 0x24 +#define ALS_IR_DATA1 0x25 + +#define PS1_DATA0 0x26 +#define PS1_DATA1 0x27 +#define PS2_DATA0 0x28 +#define PS2_DATA1 0x29 +#define PS3_DATA0 0x2A +#define PS3_DATA1 0x2B + + +#define AUX_DATA0 0x2C +#define AUX_DATA1 0x2D + +#define PARAM_RD 0x2E +#define CHIP_STAT 0x30 +#define ANA_IN_KEY 0x3B + +// Command Register Values + +#define PARAM_QUERY 0x80 //Value is ORed with Parameter Offset +#define PARAM_SET 0xA0 //Value is ORed with Parameter Offset +#define PARAM_AND 0xC0 //Value is ORed with Parameter Offset +#define PARAM_OR 0xE0 //Value is ORed with Parameter Offset +#define NOP 0x00 +#define RESET 0x01 +#define BUSADDR 0x02 +#define PS_FORCE 0x05 +#define ALS_FORCE 0x06 +#define PSALS_FORCE 0x07 +#define PS_PAUSE 0x09 +#define ALS_PAUSE 0x0A +#define PSALS_PAUSE 0x0B +#define PS_AUTO 0x0D +#define ALS_AUTO 0x0E +#define PSALS_AUTO 0x0F + +// Ram Addresses + +#define I2C_ADDR 0x00 +#define CHLIST 0x01 +#define PSLED12_SELECT 0x02 +#define PSLED3_SELECT 0x03 +#define FILTER_EN 0x04 +#define PS_ENCODING 0x05 +#define ALS_ENCODING 0x06 +#define PS1_ADCMUX 0x07 +#define PS2_ADCMUX 0x08 +#define PS3_ADCMUX 0x09 +#define PS_ADC_COUNTER 0x0A +#define PS_ADC_GAIN 0x0B +#define PS_ADC_MISC 0x0C +#define ALS1_ADCMUX 0x0D +#define ALS2_ADCMUX 0x0E +#define ALS3_ADCMUX 0x0F +#define ALS_VIS_ADC_COUNTER 0x10 +#define ALS_VIS_ADC_GAIN 0x11 +#define ALS_VIS_ADC_MISC 0x12 +#define ALS_HYST 0x16 +#define PS_HYST 0x17 +#define PS_HISTORY 0x18 +#define ALS_HISTORY 0x19 +#define ADC_OFFSET 0x1A +#define SLEEP_CTRL 0x1B +#define LED_REC 0x1C +#define ALS_IR_ADC_COUNTER 0x1D +#define ALS_IR_ADC_GAIN 0x1E +#define ALS_IR_ADC_MISC 0x1F + +// Measurement Channel List + +#define PS1_TASK 0x01 +#define PS2_TASK 0x02 +#define PS3_TASK 0x04 +#define ALS_VIS_TASK 0x10 +#define ALS_IR_TASK 0x20 +#define AUX_TASK 0x40 + +// SI1142 Sensor. + +// Restart device. +void restart(void); + +// Wait for the device to respond, then send it a specific command. +void command(char cmd); + +// Send a test command. +void command_test(); + +// Send a non-RESET command. +int command2(char cmd); + +// Send a non-RESET command another way. +void command3(char cmd); + +/** + * Read a register from the device. + */ +char read_reg(/*unsigned*/ char address, int num_data); + +// Read 4 registers in a row +char read_reg2(/*unsigned*/ char address); + +// Write to a register on the device. +void write_reg(char address, char num_data); + +void Init_Accel (char Reg_Num, char Reg_Val); + +void Get_Accel_Register (char Reg_Num); + +void Get_Accel_Register_2 (char Reg_Num); // Read 2 registers + +void i2c_start(); + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Mar 20 02:50:57 2014 +0000 @@ -0,0 +1,131 @@ +//Hat Board Test by James Cooke 3/18/2014 +//Goal of program: read and output data from LIS3DH accelerometer +//Started with Si_4088_PC working program: able to get data from Si1142 on new hat board + +// Check PS_ADC_COUNTER. It's probably wrong. + +#include "mbed.h" +#include "SI_LIS.h" +#include <time.h> + +DigitalOut myled3(LED3); +DigitalOut myled4(LED4); +Serial pc(USBTX,USBRX); +DigitalIn int_pin(p8); +Timer t; + +int reading_IR,reading_660,LSB,MSB; +char rx_data[4]; +char accel_2_data[2]; +char temp_val; +char accel_data; // for getting 8-bit value from accelerometer +short int temp_dataX; // short int: 16 bits. This allows easy negative results +short int temp_dataY; // short int: 16 bits. This allows easy negative results +short int temp_dataZ; // short int: 16 bits. This allows easy negative results + +/* From AccelWaveForms +In Loop: + Get_Accel_Register(0x2A, LIS_Addr); //Y Data Low + LSB = Accel_Data; + Get_Accel_Register(0x2B, LIS_Addr); //Y Data High + MSB = Accel_Data; + temp_dataY = (MSB * 256) + LSB; + + Get_Accel_Register(0x2C, LIS_Addr); //Z Data Low + LSB = Accel_Data; + Get_Accel_Register(0x2D, LIS_Addr); //Z Data High + MSB = Accel_Data; + temp_dataZ = (MSB * 256) + LSB; +*/ + +int main() +{ + unsigned char LowB_IR,HighB_IR,LowB_660,HighB_660; + char Reg_Val = 0x00; + char Reg_Num; + + myled4 = 0; // ODD: if this line not included, there is a compiler "internal error" + pc.baud(230400); + i2c_start(); //sets i2c bus at 400,000. Also set by photodiode setup/reset + + Reg_Num = 0x20; // CTRL_REG1 + Reg_Val = 0x57; // Nib 1 of 0101: Normal mode, 100 Hz; Nib 2 of 0111: Normal mode, XYZ enabled + Init_Accel (Reg_Num, Reg_Val); + + wait(0.050); // Delay needed, or 2nd write doesn't work + + Reg_Num = 0x21; // CTRL_REG2 + Reg_Val = 0xA0; // 7-6 10: Normal filter mode; 5-4 10: Cut off freq; 3-0 0000: bypass interrupts + // High-pass filter bits 5-4: @ 100 Hz: 00 - 2Hz 01 - 1Hz 10- 0.5Hz 11- 0.2Hz + Init_Accel (Reg_Num, Reg_Val); + wait(0.050); // Delay needed? + + pc.printf ("Hello\n"); + + Get_Accel_Register (0x0F); + pc.printf ("I am: %x",accel_data); //in hex + + while (1) { + Get_Accel_Register(0x28); //X Data Low + LSB = accel_data; + Get_Accel_Register(0x29); //X Data High + MSB = accel_data; + temp_dataX = (MSB * 256) + LSB; + pc.printf ("%d ",temp_dataX); + + Get_Accel_Register_2 (0x28); + LSB = accel_2_data[0]; + MSB = accel_2_data[1]; + temp_dataX = (MSB * 256) + LSB; + pc.printf ("%d\n",temp_dataX); + +/* +void Get_Accel_Register_2 (char Reg_Num) // Read 2 registers +{ + char reg; + reg = Reg_Num; + i2c.write((LIS_Addr << 1) & 0xFE, ®, 1); + i2c.read((LIS_Addr << 1) | 0x01, accel_2_data, 2); +} +*/ + wait(0.02); + } + /* + restart(); + wait_ms(30); + command (PS_AUTO); //start measuring + wait (0.5); + + while(1) { + if(!int_pin) { + + myled3 = !myled3; // LED on mbed, to follow along + + // t.reset(); + // t.start(); + write_reg(IRQ_STATUS,0x04); // clear the interrupt. + + read_reg2(PS1_DATA0); + LowB_IR = rx_data[0]; + HighB_IR = rx_data[1]; + + LowB_660 = rx_data[2]; + HighB_660 = rx_data[3]; + + reading_IR = (HighB_IR * 256) + LowB_IR; + reading_660 = (HighB_660 * 256) + LowB_660; + + pc.printf ("%d,%d\n", reading_IR,reading_660); + } + } + */ + +} +/* +Notes on RJ-45: Pin 1: Vcc Pin 2: GND Pin 3: SDA > 9 on 4088 + Pin 4: SCL >> 10 on 4088 Pin 6: INT > 8 on 4088 + +Bluetooth: Tx on 4088: Pin 37 >> RX Rx on 4088: Pin 31 >> TX +PC COMM port on Square board: 12 + +*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Mar 20 02:50:57 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/8e73be2a2ac1 \ No newline at end of file