TSL3301

Dependencies:   BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG mbed

Fork of DISCO-F746NG_TSL3301 by Yaroslav Krainyk

Committer:
oZGi
Date:
Tue Mar 20 12:06:47 2018 +0000
Revision:
2:6d7063605e3a
Parent:
1:979d4820e32a
Child:
3:cb16c3af98de
1;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
codebreaker7 0:96ad87d71144 1 #include "mbed.h"
oZGi 2:6d7063605e3a 2 #include "TS_DISCO_F746NG.h"
oZGi 2:6d7063605e3a 3 #include "LCD_DISCO_F746NG.h"
oZGi 2:6d7063605e3a 4
oZGi 2:6d7063605e3a 5 LCD_DISCO_F746NG lcd;
oZGi 2:6d7063605e3a 6 int line = 1;
codebreaker7 0:96ad87d71144 7
codebreaker7 0:96ad87d71144 8 DigitalIn miso(D8);
codebreaker7 0:96ad87d71144 9 DigitalOut mosi(D7);
codebreaker7 0:96ad87d71144 10 DigitalOut clk(D6);
codebreaker7 0:96ad87d71144 11
codebreaker7 0:96ad87d71144 12 unsigned char lcam_buffer[102];
oZGi 2:6d7063605e3a 13 unsigned char max_area;
codebreaker7 0:96ad87d71144 14
codebreaker7 0:96ad87d71144 15 void lcam_pulse(void) {
codebreaker7 0:96ad87d71144 16 clk = 1;
codebreaker7 0:96ad87d71144 17 clk = 0;
codebreaker7 0:96ad87d71144 18 }
codebreaker7 0:96ad87d71144 19
codebreaker7 0:96ad87d71144 20 void lcam_pulse_clock(uint8_t times){
codebreaker7 0:96ad87d71144 21 for(unsigned char i = 0; i < times; i++)
codebreaker7 0:96ad87d71144 22 {
codebreaker7 0:96ad87d71144 23 lcam_pulse();
codebreaker7 0:96ad87d71144 24 }
codebreaker7 0:96ad87d71144 25 }
codebreaker7 0:96ad87d71144 26
codebreaker7 0:96ad87d71144 27 void lcam_send(uint8_t value){
codebreaker7 0:96ad87d71144 28 // Start bit
codebreaker7 0:96ad87d71144 29 mosi = 0;
codebreaker7 0:96ad87d71144 30 lcam_pulse();
codebreaker7 0:96ad87d71144 31 // Send 8 bits to camera
codebreaker7 0:96ad87d71144 32 for(unsigned char i = 0; i < 8; i++)
codebreaker7 0:96ad87d71144 33 {
codebreaker7 0:96ad87d71144 34 mosi = ((value >> i) & 1);
codebreaker7 0:96ad87d71144 35 lcam_pulse();
codebreaker7 0:96ad87d71144 36 }
codebreaker7 0:96ad87d71144 37 // Stop bit
codebreaker7 0:96ad87d71144 38 mosi = 1;
codebreaker7 0:96ad87d71144 39 lcam_pulse();
codebreaker7 0:96ad87d71144 40 }
codebreaker7 0:96ad87d71144 41
codebreaker7 0:96ad87d71144 42 void lcam_reset(void){
codebreaker7 0:96ad87d71144 43 wait_ms(1);
codebreaker7 0:96ad87d71144 44
codebreaker7 0:96ad87d71144 45 // 10 clock impulsions with SDIN held high to clear the receiver logic
codebreaker7 0:96ad87d71144 46 mosi = 1;
codebreaker7 0:96ad87d71144 47 lcam_pulse_clock(10);
codebreaker7 0:96ad87d71144 48 // 3 reset instructions to clear the control logic
codebreaker7 0:96ad87d71144 49 lcam_send(0x1b);
codebreaker7 0:96ad87d71144 50 lcam_send(0x1b);
codebreaker7 0:96ad87d71144 51 lcam_send(0x1b);
codebreaker7 0:96ad87d71144 52 // 30 clock impulsions to assure the state of SDOUT
codebreaker7 0:96ad87d71144 53 lcam_pulse_clock(30);
codebreaker7 0:96ad87d71144 54
codebreaker7 0:96ad87d71144 55 // register write mode
codebreaker7 0:96ad87d71144 56 lcam_send(0X5F);
codebreaker7 0:96ad87d71144 57 // Clear mode register (single chip, not sleep)
codebreaker7 0:96ad87d71144 58 lcam_send(0x00);
codebreaker7 0:96ad87d71144 59 }
codebreaker7 0:96ad87d71144 60
codebreaker7 0:96ad87d71144 61 void lcam_setup(void){
codebreaker7 0:96ad87d71144 62 lcam_reset();
codebreaker7 0:96ad87d71144 63
codebreaker7 0:96ad87d71144 64 // set inputs and outputs
codebreaker7 0:96ad87d71144 65 //clk = 1;
codebreaker7 0:96ad87d71144 66 //pin_mode(LCAM_PORT, LCAM_SDIN, 1);
codebreaker7 0:96ad87d71144 67 //pin_mode(LCAM_PORT, LCAM_SDOUT, 0);
codebreaker7 0:96ad87d71144 68 // make sure the clock is cleared
codebreaker7 0:96ad87d71144 69 clk = 0;
codebreaker7 0:96ad87d71144 70
codebreaker7 0:96ad87d71144 71 // Left offset
codebreaker7 0:96ad87d71144 72 lcam_send(0x40);
codebreaker7 0:96ad87d71144 73 lcam_send(0);
codebreaker7 0:96ad87d71144 74 // Left gain
codebreaker7 0:96ad87d71144 75 lcam_send(0x41);
codebreaker7 0:96ad87d71144 76 lcam_send(15);
codebreaker7 0:96ad87d71144 77 // Middle offset
codebreaker7 0:96ad87d71144 78 lcam_send(0x42);
codebreaker7 0:96ad87d71144 79 lcam_send(0);
codebreaker7 0:96ad87d71144 80 // Middle gain
codebreaker7 0:96ad87d71144 81 lcam_send(0x43);
codebreaker7 0:96ad87d71144 82 lcam_send(15);
codebreaker7 0:96ad87d71144 83 // Right offset
codebreaker7 0:96ad87d71144 84 lcam_send(0x44);
codebreaker7 0:96ad87d71144 85 lcam_send(0);
codebreaker7 0:96ad87d71144 86 // Right gain
codebreaker7 0:96ad87d71144 87 lcam_send(0x45);
codebreaker7 0:96ad87d71144 88 lcam_send(15);
codebreaker7 0:96ad87d71144 89 }
codebreaker7 0:96ad87d71144 90
codebreaker7 0:96ad87d71144 91 void lcam_startintegration(void){
codebreaker7 0:96ad87d71144 92 // Send start integration command
codebreaker7 0:96ad87d71144 93 lcam_send(0x08);
codebreaker7 0:96ad87d71144 94 // delayed until the pixel reset cycle has been completed (22-clock delay)
codebreaker7 0:96ad87d71144 95 lcam_pulse_clock(22);
codebreaker7 0:96ad87d71144 96 }
codebreaker7 0:96ad87d71144 97
codebreaker7 0:96ad87d71144 98 void lcam_endintegration(void){
codebreaker7 0:96ad87d71144 99 // Sample int command
codebreaker7 0:96ad87d71144 100 lcam_send(0x10);
codebreaker7 0:96ad87d71144 101 // pixel reset sequence is initiated, requires 22 clocks
codebreaker7 0:96ad87d71144 102 lcam_pulse_clock(22);
codebreaker7 0:96ad87d71144 103 }
codebreaker7 0:96ad87d71144 104
codebreaker7 0:96ad87d71144 105 void lcam_integrate(unsigned int microseconds){
codebreaker7 0:96ad87d71144 106 lcam_startintegration();
codebreaker7 0:96ad87d71144 107 wait_us(microseconds);
codebreaker7 0:96ad87d71144 108 lcam_endintegration();
codebreaker7 0:96ad87d71144 109 }
codebreaker7 0:96ad87d71144 110
codebreaker7 0:96ad87d71144 111 unsigned char* lcam_getdata(void){
codebreaker7 0:96ad87d71144 112 return lcam_buffer;
codebreaker7 0:96ad87d71144 113 }
codebreaker7 0:96ad87d71144 114
codebreaker7 0:96ad87d71144 115 void lcam_read(void){
codebreaker7 0:96ad87d71144 116 unsigned char i, pixel_bit, pixel;
codebreaker7 0:96ad87d71144 117 // Read pixel command
codebreaker7 0:96ad87d71144 118 lcam_send(0x02);
codebreaker7 0:96ad87d71144 119 // 44-clock cycle delay until the first pixel data is output
codebreaker7 0:96ad87d71144 120 lcam_pulse_clock(44);
codebreaker7 0:96ad87d71144 121 // Read the 102 pixels from the camera
codebreaker7 0:96ad87d71144 122 for(i = 0; i < 102; i++)
codebreaker7 0:96ad87d71144 123 {
codebreaker7 0:96ad87d71144 124 pixel = 0;
codebreaker7 0:96ad87d71144 125 // pulse the pixel start bit (SDOUT = 0)
codebreaker7 0:96ad87d71144 126 lcam_pulse();
codebreaker7 0:96ad87d71144 127 // read a byte, bit by bit
codebreaker7 0:96ad87d71144 128 for(pixel_bit = 0; pixel_bit < 8; pixel_bit++)
codebreaker7 0:96ad87d71144 129 {
codebreaker7 0:96ad87d71144 130 clk = 1;
codebreaker7 0:96ad87d71144 131 // read pin while clock is at 1
codebreaker7 0:96ad87d71144 132 pixel |= (((miso) & 1) << pixel_bit);
codebreaker7 0:96ad87d71144 133 clk = 0;
codebreaker7 0:96ad87d71144 134 }
codebreaker7 0:96ad87d71144 135 // store byte to buffer
codebreaker7 0:96ad87d71144 136 lcam_buffer[i] = pixel;
codebreaker7 0:96ad87d71144 137 // pulse the pixel stop bit (SDOUT = 1)
codebreaker7 0:96ad87d71144 138 lcam_pulse();
codebreaker7 0:96ad87d71144 139 }
codebreaker7 0:96ad87d71144 140 }
codebreaker7 0:96ad87d71144 141
oZGi 2:6d7063605e3a 142 unsigned char lcam_getpic(void)
oZGi 2:6d7063605e3a 143 {
oZGi 2:6d7063605e3a 144 unsigned char i, value, highest = 0, max_region = 0;
oZGi 2:6d7063605e3a 145 unsigned int average = 0;
oZGi 2:6d7063605e3a 146 for(i = 0; i < 25; i++)
oZGi 2:6d7063605e3a 147 {
oZGi 2:6d7063605e3a 148 // take 4-byte average and divide by 4 (shift to right by 2)
oZGi 2:6d7063605e3a 149 value = ((lcam_buffer[i*4] + lcam_buffer[i*4+1] + lcam_buffer[i*4+2] + lcam_buffer[i*4+3]) >> 2);
oZGi 2:6d7063605e3a 150 if(value > highest)
oZGi 2:6d7063605e3a 151 {
oZGi 2:6d7063605e3a 152 highest = value;
oZGi 2:6d7063605e3a 153 max_region = i;
oZGi 2:6d7063605e3a 154 }
oZGi 2:6d7063605e3a 155 average += value;
oZGi 2:6d7063605e3a 156 }
oZGi 2:6d7063605e3a 157
oZGi 2:6d7063605e3a 158 average /= 25;
oZGi 2:6d7063605e3a 159
oZGi 2:6d7063605e3a 160 if(highest > average + 30)
oZGi 2:6d7063605e3a 161 {
oZGi 2:6d7063605e3a 162 return max_region;
oZGi 2:6d7063605e3a 163 }
oZGi 2:6d7063605e3a 164 else
oZGi 2:6d7063605e3a 165 {
oZGi 2:6d7063605e3a 166 return 0;
oZGi 2:6d7063605e3a 167 }
oZGi 2:6d7063605e3a 168 }
oZGi 2:6d7063605e3a 169
codebreaker7 0:96ad87d71144 170 int main() {
codebreaker7 1:979d4820e32a 171 lcam_setup();
codebreaker7 0:96ad87d71144 172 while(1) {
oZGi 2:6d7063605e3a 173 if (line == 10){
oZGi 2:6d7063605e3a 174 line = 1;
oZGi 2:6d7063605e3a 175 }
oZGi 2:6d7063605e3a 176
oZGi 2:6d7063605e3a 177 lcd.Clear(LCD_COLOR_WHITE);
oZGi 2:6d7063605e3a 178 lcd.SetBackColor(LCD_COLOR_WHITE);
oZGi 2:6d7063605e3a 179 lcd.SetTextColor(LCD_COLOR_RED);
oZGi 2:6d7063605e3a 180
oZGi 2:6d7063605e3a 181 lcam_integrate(10);
oZGi 2:6d7063605e3a 182
oZGi 2:6d7063605e3a 183 lcam_read();
oZGi 2:6d7063605e3a 184
oZGi 2:6d7063605e3a 185 max_area = lcam_getpic();
oZGi 2:6d7063605e3a 186
oZGi 2:6d7063605e3a 187 lcd.DisplayStringAt(0, LINE(line), (uint8_t *)max_area, CENTER_MODE);
oZGi 2:6d7063605e3a 188 line +=1;
oZGi 2:6d7063605e3a 189 wait_ms(200);
codebreaker7 0:96ad87d71144 190 }
codebreaker7 0:96ad87d71144 191 }