1 | #include "stm32f10x_conf.h"
|
2 | //#include "stm32f10x.h"
|
3 |
|
4 | void Init(void){
|
5 | // Hardware initialiser
|
6 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // enable I2C;
|
7 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // enable alternate functions (why?);
|
8 |
|
9 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // GPIO C enable
|
10 | GPIO_InitTypeDef gpioInit;
|
11 | gpioInit.GPIO_Mode = GPIO_Mode_Out_OD;
|
12 | gpioInit.GPIO_Speed = GPIO_Speed_2MHz;
|
13 | gpioInit.GPIO_Pin = GPIO_Pin_13;
|
14 | GPIO_Init(GPIOC, &gpioInit);
|
15 | GPIO_WriteBit(GPIOC, ((uint16_t)0x2000), Bit_SET);
|
16 |
|
17 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIO B enable
|
18 | GPIO_InitTypeDef gpioInit1;
|
19 | gpioInit1.GPIO_Mode = GPIO_Mode_AF_OD;
|
20 | gpioInit1.GPIO_Speed = GPIO_Speed_50MHz;
|
21 | gpioInit1.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // route I2C pins
|
22 | GPIO_Init(GPIOB, &gpioInit1);
|
23 |
|
24 | NVIC_InitTypeDef NVICinit; // configure NVIC
|
25 | NVICinit.NVIC_IRQChannel = I2C1_EV_IRQn; // add I2C_event interrupt
|
26 | NVICinit.NVIC_IRQChannelPreemptionPriority = 0;
|
27 | NVICinit.NVIC_IRQChannelSubPriority = 0;
|
28 | NVICinit.NVIC_IRQChannelCmd = ENABLE;
|
29 | NVIC_Init(&NVICinit);
|
30 |
|
31 | NVICinit.NVIC_IRQChannel = I2C1_ER_IRQn; // add I2C_error interrupt
|
32 | NVICinit.NVIC_IRQChannelPreemptionPriority = 0;
|
33 | NVICinit.NVIC_IRQChannelSubPriority = 0;
|
34 | NVICinit.NVIC_IRQChannelCmd = ENABLE;
|
35 | NVIC_Init(&NVICinit);
|
36 |
|
37 | I2C_DeInit(I2C1); // init I2C module
|
38 | I2C_InitTypeDef I2Cinit;
|
39 | I2Cinit.I2C_Ack = I2C_Ack_Enable;
|
40 | I2Cinit.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
|
41 | I2Cinit.I2C_ClockSpeed = 100000;
|
42 | I2Cinit.I2C_DutyCycle = I2C_DutyCycle_2;
|
43 | I2Cinit.I2C_Mode = I2C_Mode_I2C;
|
44 | I2Cinit.I2C_OwnAddress1 = 0;
|
45 | I2C_Init(I2C1, &I2Cinit);
|
46 |
|
47 | I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE); // enable event, error and buffer interrupts
|
48 | I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
|
49 | I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
|
50 |
|
51 | I2C_Cmd(I2C1, ENABLE);
|
52 | }
|
53 |
|
54 | volatile uint8_t I2C_errorcode = 0, I2C_addr = 0, I2C_num_bytes = 0;
|
55 | volatile uint8_t* I2C_reading_pointer;
|
56 | static uint8_t OLED_init[29]= { // Initialization Sequence
|
57 | 0x00, // Commands will be sent
|
58 | 0xAE, // Display OFF (sleep mode)
|
59 | 0x20, 0b00, // Set Memory Addressing Mode
|
60 | // 00=Horizontal Addressing Mode; 01=Vertical Addressing Mode;
|
61 | // 10=Page Addressing Mode (RESET); 11=Invalid
|
62 | 0xB0, // Set Page Start Address for Page Addressing Mode, 0-7
|
63 | 0xC8, // Set COM Output Scan Direction
|
64 | 0x00, // --set low column address
|
65 | 0x10, // --set high column address
|
66 | 0x40, // --set start line address
|
67 | 0x81, 0x3F, // Set contrast control register
|
68 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped.
|
69 | 0xA6, // Set display mode. A6=Normal; A7=Inverse
|
70 | 0xA8, 63, // Set multiplex ratio(1 to 64)
|
71 | 0xA4, // Output RAM to Display
|
72 | // 0xA4=Output follows RAM content; 0xA5,Output ignores RAM content
|
73 | 0xD3, 0x00, // Set display offset. 00 = no offset
|
74 | 0xD5, // --set display clock divide ratio/oscillator frequency
|
75 | 0xF0, // --set divide ratio
|
76 | 0xD9, 0x22, // Set pre-charge period
|
77 | 0xDA, 0x12, // Set com pins hardware configuration
|
78 | 0xDB, // --set vcomh
|
79 | 0x20, // 0x20,0.77xVcc
|
80 | 0x8D, 0x14, // Set DC-DC enable
|
81 | 0xAF //?
|
82 | };
|
83 |
|
84 | void I2C1_EV_IRQHandler(){ // Self-containing I2C interrupt
|
85 | if(I2C1->SR1 & I2C_SR1_SB){ // triggered by start condition ->
|
86 | I2C1->DR = I2C_addr; // send I2C adress
|
87 | }else if((I2C1->SR1 & I2C_SR1_ADDR)||(I2C1->SR1 & I2C_SR1_TXE)){ // if not, then send data
|
88 | if(I2C_num_bytes){ // in case its available
|
89 | I2C1->DR = *I2C_reading_pointer;
|
90 | I2C_reading_pointer++;
|
91 | I2C_num_bytes--;
|
92 | }
|
93 | } // if not - send stop condition
|
94 | else if((I2C1->SR1 & I2C_SR1_BTF)){
|
95 | I2C1->CR1 |= ((uint16_t)0x0200); // EmBitz does not recognize CR1_STOP_Set
|
96 | I2C_errorcode = 0;
|
97 | }
|
98 | }
|
99 |
|
100 | void I2C1_ER_IRQHandler(){
|
101 | if(I2C1->SR1 & I2C_SR1_AF)
|
102 | I2C_errorcode = 1; // No devise with that adress
|
103 | else{
|
104 | I2C_errorcode = 2; // Something strange occured, inspect SR1
|
105 | }
|
106 | }
|
107 |
|
108 | void I2C_initiate_transmission(){ // it`s fire and forget
|
109 | while(I2C1->SR2 & I2C_SR2_BUSY){} // wait for the bus to become free (maybe not required)
|
110 | I2C1->CR1 |= ((uint16_t)0x0100); // send start condition; EmBitz doesnt recognize it also
|
111 | I2C_errorcode = -1; // lock the I2C variables
|
112 | }
|
113 |
|
114 |
|
115 | int main(void)
|
116 | {
|
117 | Init();
|
118 |
|
119 |
|
120 | I2C_reading_pointer = OLED_init;
|
121 | I2C_num_bytes = 29;
|
122 | I2C_addr = 0x78;
|
123 |
|
124 | I2C_initiate_transmission();
|
125 |
|
126 | while(I2C_errorcode != 0){}
|
127 |
|
128 | uint8_t foo[2] = {0x40,0xff};
|
129 |
|
130 | I2C_reading_pointer = foo;
|
131 | I2C_num_bytes = 2;
|
132 |
|
133 | I2C_initiate_transmission();
|
134 |
|
135 | while(1)
|
136 | {
|
137 |
|
138 | }
|
139 | }
|