-
Notifications
You must be signed in to change notification settings - Fork 0
/
sccb_trial.c
267 lines (206 loc) · 5.38 KB
/
sccb_trial.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/*
* main.c
*
* Created on: 12 Feb 2017
* Author: rafpe
*/
#include "stm32f4xx.h"
#include "stm32f407xx.h"
#define OV7670_ADDRESS 0x21
#define OV7670_ADDRESS_W 0x42
#define OV7670_ADDRESS_R 0x43
/*
* PB6 => I2C1_SCL
* PB7 => I2C1_SDA
*/
// SCCB Data / I2C SDA
#define SCCB_DATA_LOW GPIOB->BSRR = GPIO_BSRR_BR_7;
#define SCCB_DATA_HIGH GPIOB->BSRR = GPIO_BSRR_BS_7;
#define SCCB_DATA_STATUS GPIOB->IDR & GPIO_IDR_IDR_7
// SCCB CLOCK / I2C Clock
#define SCCB_CLOCK_LOW GPIOB->BSRR = GPIO_BSRR_BR_6;
#define SCCB_CLOCK_HIGH GPIOB->BSRR = GPIO_BSRR_BS_6;
uint32_t reg1,reg2;
volatile uint32_t delay100_us;
void rcc_init(void);
void mc02_init(void);
void gpio_setup(void);
void delayus_100(uint32_t delay);
static void SCCB_Start(void);
static void SCCB_Stop(void);
static void NACK(void);
void SCCB_Write(uint8_t data);
uint8_t SCCB_Read(void);
int main(void)
{
rcc_init(); // Peripherial init
mc02_init(); // SYSCLK to PC9
gpio_setup();
SysTick_Config(1600);
// Create start condition on SCCB/I2C interface
SCCB_Start();
// Write data (Address of slave device for Write) on SCCB/I2C interface
SCCB_Write(OV7670_ADDRESS_W);
delayus_100(1);
// Write data (Address of register in Camera Module)on SCCB/I2C interface
SCCB_Write(0x6B);
// Create stop condition on SCCB/I2C interface
SCCB_Stop();
// Delay for SCCB/I2C
delayus_100(1);
// Create start condition on SCCB/I2C interface
SCCB_Start();
// Write data (Address of slave device for Read) on SCCB/I2C interface
SCCB_Write(OV7670_ADDRESS_R);
delayus_100(5);
// Received data from Camera Module (SCCB/I2C)
uint8_t test = SCCB_Read();
// No acknowlage on SCCB/I2C interface
NACK();
// Create stop condition on SCCB/I2C interface
SCCB_Stop();
while(1)
{
}
}
void SysTick_Handler(void)
{
if(delay100_us > 0) delay100_us--;
}
void rcc_init(void)
{
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN| // Enable clock: GPIOB
RCC_AHB1ENR_GPIOCEN; // Enable clock: GPIOC
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // Enable clock: I2C1
__DSB(); // Data Synchronization Barrier
}
void mc02_init(void)
{
/*
* Enable SYSCLK output to PC9
*/
GPIOC->MODER |= GPIO_MODER_MODER9_1 ; // AF: PC9 => MCO2
}
void gpio_setup(void)
{
GPIOB->MODER |= GPIO_MODER_MODER6_0 | // OUTPUT: PB6 => I2C1_SCL
GPIO_MODER_MODER7_0; // OUTPUT: PB7 => I2C1_SDA
GPIOB->OTYPER |= GPIO_OTYPER_OT_6|
GPIO_OTYPER_OT_7;
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6|
GPIO_OSPEEDER_OSPEEDR7;
// GPIOB->PUPDR |= GPIO_PUPDR_PUPDR6_0|
// GPIO_PUPDR_PUPDR7_0;
}
void delayus_100(uint32_t delay)
{
delay100_us = delay;
while (delay100_us)
{
}
}
static void SCCB_Start(void)
{
// Configure SIO_D of SCCB/I2C interface as output for write
GPIOB->MODER |= GPIO_MODER_MODER7_0; // OUTPUT: PB7 => I2C1_SDA
SCCB_DATA_HIGH;
delayus_100(5);
SCCB_CLOCK_HIGH;
delayus_100(5);
SCCB_DATA_LOW;
delayus_100(5);
SCCB_CLOCK_LOW;
delayus_100(5);
}
static void SCCB_Stop(void)
{
// Configure SIO_D of SCCB/I2C interface as output for write
GPIOB->MODER |= GPIO_MODER_MODER7_0; // OUTPUT: PB7 => I2C1_SDA
SCCB_DATA_LOW;
delayus_100(5);
SCCB_CLOCK_HIGH;
delayus_100(5);
SCCB_DATA_HIGH;
delayus_100(5);
}
void SCCB_Write(uint8_t data)
{
uint8_t i;
// Configure SIO_D of SCCB/I2C interface as output for write
GPIOB->MODER |= GPIO_MODER_MODER7_0; // OUTPUT: PB7 => I2C1_SDA
// Write data bit by bit on SCCB/I2C
for(i=0;i<8;i++)
{
if((data & 0x80) == 0x80) // If bit in Data is high, write high on SCCB/I2C
{
SCCB_DATA_HIGH;
}
else // If bit in Data is low, write low on SCCB/I2C
{
SCCB_DATA_LOW;
}
data <<= 1; // Rotate Data for write next bit
// Create clock pulse on SCCB/I2C
// ___ On SIO_C pin (SCCB clock)
// \___
SCCB_CLOCK_HIGH;
delayus_100(5);
SCCB_CLOCK_LOW;
delayus_100(5);
}
// Read acknowladge from Camera Module to confirm received data
delayus_100(1);
// Configure SIO_D of SCCB/I2C interface as input for read;
GPIOB->MODER &= ~GPIO_MODER_MODER7; // INPUT: PB7 => I2C1_SDA
delayus_100(5);
SCCB_CLOCK_HIGH;
delayus_100(5);
// If acknowladge is OK return SUCCESS else if is incorrect return ERROR
uint8_t nasz_ack = GPIOB->IDR & GPIO_IDR_IDR_7;
// Pulse on SCCB/I2C fall down from high
SCCB_CLOCK_LOW;
delayus_100(5);
// Configure SIO_D of SCCB/I2C interface back to output for write
GPIOB->MODER |= GPIO_MODER_MODER7_0; // OUTPUT: PB7 => I2C1_SDA
// return (Ack);
}
uint8_t SCCB_Read(void)
{
uint8_t Data, i;
// Write to Data zero for correct return data
Data = 0;
// Configure SIO_D of SCCB/I2C interface as input for read;
GPIOB->MODER &= ~GPIO_MODER_MODER7; // INPUT: PB7 => I2C1_SDA
// Delay for SCCB/I2C interface
delayus_100(5);
// Read data from SCCBI/I2C interface
for(i=8;i>0;i--)
{
delayus_100(5); // Delay for SCCB/I2C
SCCB_CLOCK_HIGH; // Clock high
delayus_100(5);
Data = Data << 1; // Rotate Data << 1
if(SCCB_DATA_STATUS)
{
Data = Data + 1; // Read DATA pin value
}
SCCB_CLOCK_LOW; // Clock low on SIO_C
delayus_100(5);
}
// Return received data from SCCBI/I2C interface
return(Data);
}
//
static void NACK(void)
{
// Configure SIO_D of SCCB/I2C interface back to output for write
GPIOB->MODER |= GPIO_MODER_MODER7_0; // OUTPUT: PB7 => I2C1_SDA
SCCB_DATA_HIGH;;
delayus_100(5);
SCCB_CLOCK_HIGH;
delayus_100(5);
SCCB_CLOCK_LOW;
delayus_100(5);
SCCB_DATA_LOW;
delayus_100(5);
}