main.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. /*
  2. * This program is free software: you can redistribute it and/or modify
  3. * it under the terms of the GNU Lesser General Public License as published by
  4. * the Free Software Foundation, either version 3 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * This library is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU Lesser General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU Lesser General Public License
  13. * along with this library. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include <unicore-mx/stm32/rcc.h>
  16. #include <unicore-mx/stm32/gpio.h>
  17. #include <string.h>
  18. #include <stdio.h>
  19. #define DMB() __asm__ volatile ("dmb")
  20. #define FLASH_BASE (0x40022000)
  21. #define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00))
  22. #define LED_GREEN_PIN GPIO5
  23. #define LED_GREEN_PORT GPIOA
  24. #define LED_RED_PIN GPIO4
  25. #define LED_RED_PORT GPIOA
  26. #define I2C3_SDA_PIN GPIO1
  27. #define I2C3_SDA_PORT GPIOC
  28. #define I2C3_SCL_PIN GPIO0
  29. #define I2C3_SCL_PORT GPIOC
  30. #define I2C3_AF (7)
  31. #define I2C3_BASE 0x40007800
  32. #define I2C3 I2C3_BASE
  33. #define I2C I2C3
  34. #define I2C3_CR1 (*(volatile uint32_t *)(I2C3))
  35. #define I2C3_CR2 (*(volatile uint32_t *)(I2C3 + 0x04))
  36. #define I2C3_OAR1 (*(volatile uint32_t *)(I2C3 + 0x08))
  37. #define I2C3_OAR2 (*(volatile uint32_t *)(I2C3 + 0x0c))
  38. #define I2C3_TIMINGR (*(volatile uint32_t *)(I2C3 + 0x10))
  39. #define I2C3_SR1 (*(volatile uint32_t *)(I2C3 + 0x14))
  40. #define I2C3_ISR (*(volatile uint32_t *)(I2C3 + 0x18))
  41. #define I2C3_ICR (*(volatile uint32_t *)(I2C3 + 0x1C))
  42. #define I2C3_TXDR (*(volatile uint32_t *)(I2C3 + 0x28))
  43. #define I2C3_RXDR (*(volatile uint32_t *)(I2C3 + 0x24))
  44. #define I2C_CR1_ENABLE (1 << 0)
  45. #define I2C_CR1_DNF (1 << 8)
  46. #define I2C_CR1_ANFOFF (1 << 12)
  47. #define I2C_CR1_NOSTRETCH (1 << 17)
  48. #define I2C_CR2_START (1 << 13)
  49. #define I2C_CR2_STOP (1 << 14)
  50. #define I2C_CR2_RD_WRN (1 << 10)
  51. #define I2C_CR2_NBYTES_SHIFT (16)
  52. #define I2C_CR2_RELOAD (1 << 24)
  53. #define I2C_CR2_AUTOEND (1 << 25)
  54. #define I2C_CR1_ACK (1 << 10)
  55. #define I2C_CR2_FREQ_MASK (0x3ff)
  56. #define I2C_CCR_MASK (0xfff)
  57. #define I2C_ISR_TXIS (1 << 1)
  58. #define I2C_ISR_TXE (1 << 0)
  59. #define I2C_ISR_RXNE (1 << 2)
  60. #define I2C_ISR_NACKF (1 << 4)
  61. #define I2C_ISR_TCR (1 << 7)
  62. #define I2C_ICR_ARLOCF (1 << 9)
  63. #define I2C_ICR_BERRCF (1 << 8)
  64. #define I2C_ICR_ADDRCF (1 << 3)
  65. #define I2C_ICR_NACKF (1 << 4)
  66. #define I2C_ICR_STOPF (1 << 5)
  67. #define I2C_ICR_ALLCF (I2C_ICR_NACKF | I2C_ICR_ARLOCF | I2C_ICR_BERRCF | I2C_ICR_ADDRCF )
  68. #define RCC_CFGR_PLLDIV2 (0x01 << 22)
  69. #define RCC_CFGR_PLLMUL4 (0x01 << 18)
  70. #define RCC_PRESCALER_DIV_NONE 0
  71. #define ROM_SRC 0x50
  72. #define ROM_DST 0x51
  73. #define ROM_TEST_NACK 0x52
  74. #define ROM_PAGE_SIZE (32)
  75. #define ROM_SIZE (8192)
  76. #define ROM_PAGES (ROM_SIZE / ROM_PAGE_SIZE)
  77. static void wait_a_bit(void)
  78. {
  79. volatile int i;
  80. for (i = 0; i < 30000; i++) { /* Wait a bit. */
  81. __asm__("nop");
  82. }
  83. }
  84. static void i2c_acquire(void)
  85. {
  86. rcc_periph_clock_enable(RCC_I2C3);
  87. I2C3_CR1 |= I2C_CR1_ENABLE;
  88. }
  89. static void i2c_release(void)
  90. {
  91. I2C3_CR1 &= ~(I2C_CR1_ENABLE);
  92. rcc_periph_clock_disable(RCC_I2C3);
  93. }
  94. static void i2c_setup(void)
  95. {
  96. /* 400KHz */
  97. uint32_t presc = 0, scll = 0x2E, sclh = 0x11, sdadel = 0x01, scldel = 0x0b;
  98. /* 100KHz */
  99. //uint32_t presc = 1, scll = 0x56, sclh = 0x3e, sdadel = 0x01, scldel = 0x0a;
  100. rcc_periph_clock_enable(RCC_GPIOC);
  101. gpio_set_output_options(GPIOC, GPIO_OTYPE_OD, GPIO_OSPEED_HIGH, I2C3_SDA_PIN);
  102. gpio_mode_setup(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP,
  103. I2C3_SDA_PIN | I2C3_SCL_PIN);
  104. gpio_set_af(GPIOC, I2C3_AF, I2C3_SDA_PIN | I2C3_SCL_PIN);
  105. i2c_acquire();
  106. /* Disable */
  107. I2C3_CR1 &= ~(I2C_CR1_ENABLE);
  108. /* configure analog noise filter */
  109. I2C3_CR1 |= I2C_CR1_ANFOFF;
  110. /* configure digital noise filter */
  111. I2C3_CR1 |= I2C_CR1_DNF;
  112. /* set timing registers */
  113. I2C3_TIMINGR = (presc << 28) | (scldel << 20) | (sdadel << 16) | (sclh << 8) | scll;
  114. /* configure clock stretching */
  115. I2C3_CR1 &= ~(I2C_CR1_NOSTRETCH);
  116. /* Clear interrupt */
  117. I2C3_ICR |= I2C_ICR_ALLCF;
  118. i2c_release();
  119. }
  120. static void gpio_setup(void)
  121. {
  122. /* Enable GPIO clock. */
  123. rcc_periph_clock_enable(RCC_GPIOA);
  124. /* set pins to output mode, push pull */
  125. gpio_mode_setup(LED_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_GREEN_PIN);
  126. gpio_mode_setup(LED_RED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_RED_PIN);
  127. }
  128. static void wait_sent(void)
  129. {
  130. volatile uint32_t sr1;
  131. do {
  132. sr1 = I2C3_ISR;
  133. } while ((sr1 & (I2C_ISR_TXE)) == 0);
  134. }
  135. static void wait_reload(void)
  136. {
  137. volatile uint32_t sr1;
  138. do {
  139. sr1 = I2C3_ISR;
  140. } while ((sr1 & (I2C_ISR_TCR)) == 0);
  141. }
  142. static void wait_start(void)
  143. {
  144. volatile uint32_t cr2;
  145. do {
  146. cr2 = I2C3_CR2;
  147. } while ((cr2 & (I2C_CR2_START)) != 0);
  148. }
  149. static void wait_stop(void)
  150. {
  151. volatile uint32_t cr2;
  152. do {
  153. cr2 = I2C3_CR2;
  154. } while ((cr2 & (I2C_CR2_STOP)) != 0);
  155. }
  156. static void wait_rxd(void)
  157. {
  158. volatile uint32_t sr1;
  159. do {
  160. sr1 = I2C3_ISR;
  161. } while ((sr1 & (I2C_ISR_RXNE)) == 0);
  162. }
  163. static void clear_err(void)
  164. {
  165. I2C3_ICR |= I2C_ICR_ALLCF;
  166. }
  167. static void clear_stop(void)
  168. {
  169. I2C3_ICR |= I2C_ICR_STOPF;
  170. }
  171. static int eeprom_write_page(uint8_t rom, uint16_t address, const uint8_t *buf)
  172. {
  173. volatile uint32_t sr1, sr2, cr2;
  174. int i;
  175. if (rom != ROM_DST)
  176. return 0;
  177. clear_err();
  178. I2C3_CR2 = ((ROM_PAGE_SIZE + 2) << I2C_CR2_NBYTES_SHIFT) | I2C_CR2_AUTOEND;
  179. I2C3_CR2 |= (rom << 1);
  180. I2C3_CR2 |= I2C_CR2_START;
  181. wait_start();
  182. I2C3_TXDR = ((uint8_t)((address >> 8) & (0xFF)));
  183. wait_sent();
  184. I2C3_TXDR = ((uint8_t)((address & 0xFF)));
  185. for (i = 0; i < ROM_PAGE_SIZE; i++) {
  186. wait_sent();
  187. I2C3_TXDR = buf[i];
  188. }
  189. wait_a_bit();
  190. clear_stop();
  191. return i;
  192. }
  193. static int eeprom_read_page(uint8_t rom, uint16_t address, uint8_t *buf)
  194. {
  195. volatile uint32_t sr1, sr2;
  196. int i;
  197. clear_err();
  198. I2C3_CR2 = (2 << I2C_CR2_NBYTES_SHIFT) | I2C_CR2_RELOAD;
  199. I2C3_CR2 |= (rom << 1);
  200. I2C3_CR2 |= I2C_CR2_START;
  201. wait_start();
  202. I2C3_TXDR = ((uint8_t)((address & 0xFF00) >> 8));
  203. wait_sent();
  204. clear_err();
  205. I2C3_CR2 = (rom << 1);
  206. I2C3_CR2 |= I2C_CR2_RD_WRN;
  207. I2C3_CR2 |= (ROM_PAGE_SIZE << I2C_CR2_NBYTES_SHIFT);
  208. I2C3_CR2 |= I2C_CR2_START;
  209. I2C3_TXDR = ((uint8_t)((address & 0xFF)));
  210. //wait_sent();
  211. wait_start();
  212. clear_err();
  213. for (i = 0; i < ROM_PAGE_SIZE; i++) {
  214. //I2C3_TXDR = 0xFF;
  215. //wait_sent();
  216. wait_rxd();
  217. buf[i] = I2C3_RXDR;
  218. }
  219. I2C3_CR2 |= I2C_CR2_STOP;
  220. clear_stop();
  221. return i;
  222. }
  223. static int eeprom_read_cur(uint8_t rom, uint8_t *buf)
  224. {
  225. int i;
  226. retry:
  227. clear_err();
  228. I2C3_CR2 = (ROM_PAGE_SIZE << I2C_CR2_NBYTES_SHIFT);
  229. I2C3_CR2 |= (rom << 1) | I2C_CR2_RD_WRN;
  230. I2C3_CR2 |= I2C_CR2_START;
  231. wait_start();
  232. if (I2C3_ISR & I2C_ISR_NACKF) {
  233. wait_a_bit();
  234. clear_stop();
  235. goto retry;
  236. }
  237. for (i = 0; i < ROM_PAGE_SIZE; i++) {
  238. wait_rxd();
  239. buf[i] = I2C3_RXDR;
  240. }
  241. return i;
  242. }
  243. static void flash_set_waitstates(unsigned int waitstates)
  244. {
  245. if (waitstates && ((FLASH_ACR & 1) == 0))
  246. FLASH_ACR |= 1;
  247. if (!waitstates && ((FLASH_ACR & 1) == 1))
  248. FLASH_ACR &= 1;
  249. while ((FLASH_ACR & 1) != waitstates)
  250. ;
  251. }
  252. static void clock_pll_on(void)
  253. {
  254. uint32_t reg32;
  255. uint32_t cpu_freq, hsi_freq, hpre, ppre1, ppre2, flash_waitstates;
  256. /* Enable Power controller */
  257. rcc_periph_clock_enable(RCC_PWR);
  258. /* Select clock parameters (CPU Speed = 32MHz) */
  259. cpu_freq = 32000000;
  260. hsi_freq = 16000000;
  261. hpre = RCC_PRESCALER_DIV_NONE;
  262. ppre1 = RCC_PRESCALER_DIV_NONE;
  263. ppre2 = RCC_PRESCALER_DIV_NONE;
  264. flash_waitstates = 1;
  265. flash_set_waitstates(flash_waitstates);
  266. /* Enable internal high-speed oscillator. */
  267. RCC_CR |= RCC_CR_HSI16ON;
  268. DMB();
  269. while ((RCC_CR & RCC_CR_HSI16RDY) == 0) {};
  270. /* Select HSI as SYSCLK source. */
  271. reg32 = RCC_CFGR;
  272. reg32 &= ~((1 << 1) | (1 << 0));
  273. RCC_CFGR = (reg32 | RCC_CFGR_SW_HSI16);
  274. DMB();
  275. /*
  276. * Set prescalers for AHB, ADC, ABP1, ABP2.
  277. */
  278. reg32 = RCC_CFGR;
  279. reg32 &= ~(0xF << 4);
  280. RCC_CFGR = (reg32 | (hpre << 4));
  281. DMB();
  282. reg32 = RCC_CFGR;
  283. reg32 &= ~(0x07 << 8);
  284. RCC_CFGR = (reg32 | (ppre1 << 8));
  285. DMB();
  286. reg32 &= ~(0x07 << 11);
  287. RCC_CFGR = (reg32 | (ppre2 << 11));
  288. DMB();
  289. reg32 &= ~(0x0F << 18);
  290. RCC_CFGR = (reg32 | RCC_CFGR_PLLMUL4);
  291. DMB();
  292. reg32 &= ~(0x03 << 22);
  293. RCC_CFGR = (reg32 | RCC_CFGR_PLLDIV2);
  294. DMB();
  295. /* Enable PLL oscillator and wait for it to stabilize. */
  296. RCC_CR |= RCC_CR_PLLON;
  297. DMB();
  298. while ((RCC_CR & RCC_CR_PLLRDY) == 0) {};
  299. /* Select PLL as SYSCLK source. */
  300. reg32 = RCC_CFGR;
  301. reg32 &= ~((1 << 1) | (1 << 0));
  302. RCC_CFGR = (reg32 | RCC_CFGR_SW_PLL);
  303. DMB();
  304. /* Wait for PLL clock to be selected. */
  305. while (((RCC_CFGR >> 2) & 0x03) != RCC_CFGR_SW_PLL)
  306. ;
  307. }
  308. static uint8_t cache[ROM_PAGE_SIZE];
  309. static uint8_t vcache[ROM_PAGE_SIZE];
  310. int main(void)
  311. {
  312. int i;
  313. clock_pll_on();
  314. gpio_setup();
  315. gpio_set(LED_RED_PORT, LED_RED_PIN);
  316. i2c_setup();
  317. wait_a_bit();
  318. wait_a_bit();
  319. wait_a_bit();
  320. i2c_acquire();
  321. #if 0
  322. /* TEST - fill the DST */
  323. for (i = 0; i < ROM_PAGES; i++) {
  324. memset(cache, (uint8_t)i, 32);
  325. eeprom_write_page(ROM_DST,i * ROM_PAGE_SIZE,cache);
  326. }
  327. #endif
  328. memset(cache, 0, 32);
  329. for (i = 0; i < ROM_PAGES; i++) {
  330. /* Green: Read */
  331. gpio_set(LED_RED_PORT, LED_GREEN_PIN);
  332. gpio_clear(LED_GREEN_PORT, LED_GREEN_PIN);
  333. eeprom_read_page(ROM_SRC, i * ROM_PAGE_SIZE, cache);
  334. eeprom_read_page(ROM_DST, i * ROM_PAGE_SIZE, vcache);
  335. if(memcmp(vcache, cache, ROM_PAGE_SIZE) == 0) {
  336. /* Skip sector, already matching. */
  337. continue;
  338. }
  339. /* Red: Write */
  340. gpio_set(LED_GREEN_PORT, LED_GREEN_PIN);
  341. gpio_clear(LED_RED_PORT, LED_RED_PIN);
  342. eeprom_write_page(ROM_DST, i * ROM_PAGE_SIZE, cache);
  343. /* Both: verify */
  344. gpio_clear(LED_GREEN_PORT, LED_GREEN_PIN);
  345. eeprom_read_page(ROM_DST, i * ROM_PAGE_SIZE, vcache);
  346. if(memcmp(vcache, cache, ROM_PAGE_SIZE) != 0) {
  347. while(1) {
  348. /* blink red: panic */
  349. gpio_toggle(LED_RED_PORT, LED_RED_PIN);
  350. for (i = 0; i < 10; i++)
  351. wait_a_bit();
  352. }
  353. }
  354. gpio_set(LED_GREEN_PORT, LED_GREEN_PIN);
  355. gpio_set(LED_RED_PORT, LED_RED_PIN);
  356. }
  357. i2c_release();
  358. while (1) {
  359. /* blink green: success */
  360. gpio_set(LED_RED_PORT, LED_RED_PIN);
  361. gpio_toggle(LED_GREEN_PORT, LED_GREEN_PIN);
  362. for (i = 0; i < 10; i++)
  363. wait_a_bit();
  364. }
  365. return 0;
  366. }