Guest User

libmaple i2c slave code

a guest
Aug 31st, 2012
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 22.03 KB | None | 0 0
  1. diff --git a/libmaple/i2c.c b/libmaple/i2c.c
  2. index 9c93d3f..2a98b79 100644
  3. --- a/libmaple/i2c.c
  4. +++ b/libmaple/i2c.c
  5. @@ -154,6 +154,7 @@ void i2c_bus_reset(const i2c_dev *dev) {
  6.  void i2c_init(i2c_dev *dev) {
  7.      rcc_reset_dev(dev->clk_id);
  8.      rcc_clk_enable(dev->clk_id);
  9. +    _i2c_irq_priority_fixup(dev);
  10.  }
  11.  
  12.  /* Hack for deprecated bit of STM32F1 functionality */
  13. @@ -198,12 +199,26 @@ void i2c_master_enable(i2c_dev *dev, uint32 flags) {
  14.      nvic_irq_enable(dev->er_nvic_line);
  15.      i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR);
  16.  
  17. +    /* Configure the slave unit */
  18. +    if (flags & I2C_SLAVE_DUAL_ADDRESS) {
  19. +       i2c_slave_dual_address_enable(dev);
  20. +   }
  21. +
  22. +   if (flags & I2C_SLAVE_GENERAL_CALL) {
  23. +       i2c_slave_general_call_enable(dev);
  24. +   }
  25. +
  26. +   /* store all of the flags */
  27. +   dev->config_flags = flags;
  28. +
  29.      /* Make it go! */
  30.      i2c_peripheral_enable(dev);
  31. +    i2c_enable_ack(dev);
  32.  
  33.      dev->state = I2C_STATE_IDLE;
  34.  }
  35.  
  36. +
  37.  /**
  38.   * @brief Process an i2c transaction.
  39.   *
  40. @@ -303,149 +318,297 @@ void _i2c_irq_handler(i2c_dev *dev) {
  41.       */
  42.      dev->timestamp = systick_uptime();
  43.  
  44. -    /*
  45. -     * EV5: Start condition sent
  46. +    /* Add Slave support
  47. +     * Barry Carter 2012
  48.       */
  49. -    if (sr1 & I2C_SR1_SB) {
  50. -        msg->xferred = 0;
  51. -        i2c_enable_irq(dev, I2C_IRQ_BUFFER);
  52. -
  53. -        /*
  54. -         * Master receiver
  55. -         */
  56. -        if (read) {
  57. -            i2c_enable_ack(dev);
  58. +    
  59. +    /* Check to see if MSL master slave bit is set */
  60. +    if ((sr2 & I2C_SR2_MSL) != I2C_SR2_MSL) { /* 0 = slave mode 1 = master */
  61. +
  62. +       dev->state = I2C_STATE_BUSY;
  63. +
  64. +        /* Check for address match */
  65. +        if (sr1 & I2C_SR1_ADDR) {
  66. +           /* Find out which address was matched */
  67. +           /* Check the general call address first */
  68. +           if (sr2 & I2C_SR2_GENCALL) {
  69. +               dev->i2c_slave_msg->addr = 0;
  70. +           }
  71. +           /* We matched the secondary address */
  72. +           else if (sr2 & I2C_SR2_DUALF) {
  73. +               dev->i2c_slave_msg->addr = dev->regs->OAR2 & 0xFE;
  74. +           }
  75. +           /* We matched the primary address */
  76. +           else if ((sr2 & I2C_SR2_DUALF) != I2C_SR2_DUALF) {
  77. +               dev->i2c_slave_msg->addr = dev->regs->OAR1 & 0xFE;
  78. +           }
  79. +           /* Shouldn't get here */
  80. +           else {
  81. +               dev->i2c_slave_msg->addr = -1; /* uh oh */
  82. +           }
  83. +
  84. +           /* if we have buffered io */
  85. +           if ((dev->config_flags & I2C_SLAVE_USE_RX_BUFFER) ||
  86. +               (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER)) {
  87. +
  88. +               /* if receiving then this would be a repeated start
  89. +                *
  90. +                *if we have some bytes already
  91. +                */
  92. +               if (((sr1 & I2C_SR1_TXE) != I2C_SR1_TXE) &&
  93. +                   (dev->i2c_slave_msg->xferred > 0)  &&
  94. +                   (dev->config_flags & I2C_SLAVE_USE_RX_BUFFER)) {
  95. +                   /* Call the callback with the contents of the data */
  96. +                   if (dev->i2c_slave_recv_callback != NULL) {
  97. +                       (*(dev->i2c_slave_recv_callback))(dev->i2c_slave_msg);
  98. +                   }
  99. +               }
  100. +
  101. +               /* Reset the message back to defaults.
  102. +                * We are starting a new message
  103. +                */
  104. +               dev->i2c_slave_msg->flags = 0;
  105. +               dev->i2c_slave_msg->length = 0;
  106. +               dev->i2c_slave_msg->xferred = 0;
  107. +               dev->msgs_left = 0;
  108. +               dev->timestamp = systick_uptime();
  109. +
  110. +               /* We have been addressed with SLA+R so
  111. +                * the master wants us to transmit
  112. +                */
  113. +               if ((sr1 & I2C_SR1_TXE) &&
  114. +                   (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER)) {
  115. +                   /* Call the transmit callback so it can populate the msg
  116. +                    * data with the bytes to go
  117. +                    */
  118. +                   if (dev->i2c_slave_transmit_callback != NULL) {
  119. +                       (*(dev->i2c_slave_transmit_callback))(dev->i2c_slave_msg);
  120. +                   }
  121. +               }
  122. +           }
  123. +
  124. +            sr1 = sr2 = 0;
  125. +        }
  126. +        
  127. +         /* EV3: Master requesting data from slave. Transmit a byte*/
  128. +        if (sr1 & I2C_SR1_TXE) {
  129. +           if (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER) {
  130. +               if (dev->i2c_slave_msg->xferred >= dev->i2c_slave_msg->length) {
  131. +                   /* End of the transmit buffer? If so we NACK */
  132. +                   i2c_disable_ack(dev);
  133. +                   /* We have to either issue a STOP or write something here.
  134. +                    * STOP here seems to screw up some masters,
  135. +                    * For now padding with 0
  136. +                    */
  137. +                   i2c_write(dev, 0);
  138. +                   /*i2c_stop_condition(dev); // This is causing bus lockups way more than it should !? Seems some I2C master devices freak out here*/
  139. +               }
  140. +               else
  141. +               {
  142. +                   /* NACk the last byte */
  143. +                   if (dev->i2c_slave_msg->xferred == dev->i2c_slave_msg->length-1) {
  144. +                       i2c_disable_ack(dev);
  145. +                   }
  146. +                   else {
  147. +                       i2c_enable_ack(dev);
  148. +                   }
  149. +                   i2c_write(dev, dev->i2c_slave_msg->data[dev->i2c_slave_msg->xferred++]);
  150. +               }
  151. +           }
  152. +           else
  153. +           {
  154. +               /* Call the callback to get the data we need.
  155. +                * The callback is expected to write using i2c_write(...)
  156. +                * If the slave is going to terminate the transfer, this function should
  157. +                * also do a NACK on the last byte!
  158. +                */
  159. +               if (dev->i2c_slave_transmit_callback != NULL) (*(dev->i2c_slave_transmit_callback))(dev->i2c_slave_msg);
  160. +           }
  161. +
  162. +           sr1 = sr2 = 0;
  163. +        }
  164. +        
  165. +        /* EV2: Slave received data from a master. Get from DR */
  166. +        if (sr1 & I2C_SR1_RXNE) {
  167. +           if (dev->config_flags & I2C_SLAVE_USE_RX_BUFFER) {
  168. +               /* Fill the buffer with the contents of the data register */
  169. +               dev->i2c_slave_msg->data[dev->i2c_slave_msg->xferred++] = dev->regs->DR;
  170. +               dev->i2c_slave_msg->length++;
  171. +           }
  172. +           else  {
  173. +               /* Call the callback with the contents of the data */
  174. +               dev->i2c_slave_msg->data[0] = dev->regs->DR;
  175. +               if (dev->i2c_slave_recv_callback != NULL) (*(dev->i2c_slave_recv_callback))(dev->i2c_slave_msg);
  176. +           }
  177. +            sr1 = sr2 = 0;
  178.          }
  179.  
  180. -        i2c_send_slave_addr(dev, msg->addr, read);
  181. -        sr1 = sr2 = 0;
  182. -    }
  183. +        /* EV4: Slave has detected a STOP condition on the bus */
  184. +        if (sr1 & I2C_SR1_STOPF) {
  185. +            dev->regs->CR1 |= I2C_CR1_PE;
  186.  
  187. -    /*
  188. -     * EV6: Slave address sent
  189. -     */
  190. -    if (sr1 & I2C_SR1_ADDR) {
  191. -        /*
  192. -         * Special case event EV6_1 for master receiver.
  193. -         * Generate NACK and restart/stop condition after ADDR
  194. -         * is cleared.
  195. -         */
  196. -        if (read) {
  197. -            if (msg->length == 1) {
  198. -                i2c_disable_ack(dev);
  199. -                if (dev->msgs_left > 1) {
  200. -                    i2c_start_condition(dev);
  201. -                    I2C_CRUMB(RX_ADDR_START, 0, 0);
  202. -                } else {
  203. -                    i2c_stop_condition(dev);
  204. -                    I2C_CRUMB(RX_ADDR_STOP, 0, 0);
  205. -                }
  206. -            }
  207. -        } else {
  208. -            /*
  209. -             * Master transmitter: write first byte to fill shift
  210. -             * register.  We should get another TXE interrupt
  211. -             * immediately to fill DR again.
  212. -             */
  213. -            if (msg->length != 1) {
  214. -                i2c_write(dev, msg->data[msg->xferred++]);
  215. -            }
  216. -        }
  217. -        sr1 = sr2 = 0;
  218. -    }
  219. +            if ((dev->config_flags & I2C_SLAVE_USE_RX_BUFFER) ||
  220. +               (dev->config_flags & I2C_SLAVE_USE_RX_BUFFER)) {
  221.  
  222. -    /*
  223. -     * EV8: Master transmitter
  224. -     * Transmit buffer empty, but we haven't finished transmitting the last
  225. -     * byte written.
  226. -     */
  227. -    if ((sr1 & I2C_SR1_TXE) && !(sr1 & I2C_SR1_BTF)) {
  228. -        I2C_CRUMB(TXE_ONLY, 0, 0);
  229. -        if (dev->msgs_left) {
  230. -            i2c_write(dev, msg->data[msg->xferred++]);
  231. -            if (msg->xferred == msg->length) {
  232. -                /*
  233. -                 * End of this message. Turn off TXE/RXNE and wait for
  234. -                 * BTF to send repeated start or stop condition.
  235. -                 */
  236. -                i2c_disable_irq(dev, I2C_IRQ_BUFFER);
  237. -                dev->msgs_left--;
  238. -            }
  239. -        } else {
  240. -            /*
  241. -             * This should be impossible...
  242. -             */
  243. -            ASSERT(0);
  244. -        }
  245. -        sr1 = sr2 = 0;
  246. -    }
  247. +               /* The callback with the data will happen on a NACK of the last data byte.
  248. +                * This is handled in the error IRQ
  249. +                */
  250. +           }
  251.  
  252. -    /*
  253. -     * EV8_2: Master transmitter
  254. -     * Last byte sent, program repeated start/stop
  255. -     */
  256. -    if ((sr1 & I2C_SR1_TXE) && (sr1 & I2C_SR1_BTF)) {
  257. -        I2C_CRUMB(TXE_BTF, 0, 0);
  258. -        if (dev->msgs_left) {
  259. -            I2C_CRUMB(TEST, 0, 0);
  260. -            /*
  261. -             * Repeated start insanity: We can't disable ITEVTEN or else SB
  262. -             * won't interrupt, but if we don't disable ITEVTEN, BTF will
  263. -             * continually interrupt us. What the fuck ST?
  264. -             */
  265. -            i2c_start_condition(dev);
  266. -            while (!(dev->regs->SR1 & I2C_SR1_SB))
  267. -                ;
  268. -            dev->msg++;
  269. -        } else {
  270. -            i2c_stop_condition(dev);
  271. -
  272. -            /*
  273. -             * Turn off event interrupts to keep BTF from firing until
  274. -             * the end of the stop condition. Why on earth they didn't
  275. -             * have a start/stop condition request clear BTF is beyond
  276. -             * me.
  277. -             */
  278. -            i2c_disable_irq(dev, I2C_IRQ_EVENT);
  279. -            I2C_CRUMB(STOP_SENT, 0, 0);
  280. -            dev->state = I2C_STATE_XFER_DONE;
  281. +            sr1 = sr2 = 0;
  282. +            dev->state = I2C_STATE_IDLE;
  283.          }
  284. -        sr1 = sr2 = 0;
  285. -    }
  286.  
  287. -    /*
  288. -     * EV7: Master Receiver
  289. -     */
  290. -    if (sr1 & I2C_SR1_RXNE) {
  291. -        I2C_CRUMB(RXNE_ONLY, 0, 0);
  292. -        msg->data[msg->xferred++] = dev->regs->DR;
  293. -
  294. -        /*
  295. -         * EV7_1: Second to last byte in the reception? Set NACK and generate
  296. -         * stop/restart condition in time for the last byte. We'll get one more
  297. -         * RXNE interrupt before shutting things down.
  298. -         */
  299. -        if (msg->xferred == (msg->length - 1)) {
  300. -            i2c_disable_ack(dev);
  301. -            if (dev->msgs_left > 2) {
  302. -                i2c_start_condition(dev);
  303. -                I2C_CRUMB(RXNE_START_SENT, 0, 0);
  304. -            } else {
  305. -                i2c_stop_condition(dev);
  306. -                I2C_CRUMB(RXNE_STOP_SENT, 0, 0);
  307. -            }
  308. -        } else if (msg->xferred == msg->length) {
  309. -            dev->msgs_left--;
  310. -            if (dev->msgs_left == 0) {
  311. -                /*
  312. -                 * We're done.
  313. -                 */
  314. -                I2C_CRUMB(RXNE_DONE, 0, 0);
  315. -                dev->state = I2C_STATE_XFER_DONE;
  316. -            } else {
  317. -                dev->msg++;
  318. -            }
  319. -        }
  320. +        return;
  321. +    }
  322. +    
  323. +    /* Process the master code */
  324. +    /*if ((sr2 & I2C_SR2_MSL) == I2C_SR2_MSL)*/ { /* 0 = slave mode 1 = master */
  325. +       /*
  326. +        * EV5: Start condition sent
  327. +        */
  328. +       if (sr1 & I2C_SR1_SB) {
  329. +           msg->xferred = 0;
  330. +           i2c_enable_irq(dev, I2C_IRQ_BUFFER);
  331. +
  332. +           /*
  333. +            * Master receiver
  334. +            */
  335. +           if (read) {
  336. +               i2c_enable_ack(dev);
  337. +           }
  338. +
  339. +           i2c_send_slave_addr(dev, msg->addr, read);
  340. +           sr1 = sr2 = 0;
  341. +       }
  342. +
  343. +       /*
  344. +        * EV6: Slave address sent
  345. +        */
  346. +       if (sr1 & I2C_SR1_ADDR) {
  347. +           /*
  348. +            * Special case event EV6_1 for master receiver.
  349. +            * Generate NACK and restart/stop condition after ADDR
  350. +            * is cleared.
  351. +            */
  352. +           if (read) {
  353. +               if (msg->length == 1) {
  354. +                   i2c_disable_ack(dev);
  355. +                   if (dev->msgs_left > 1) {
  356. +                       i2c_start_condition(dev);
  357. +                       I2C_CRUMB(RX_ADDR_START, 0, 0);
  358. +                   } else {
  359. +                       i2c_stop_condition(dev);
  360. +                       I2C_CRUMB(RX_ADDR_STOP, 0, 0);
  361. +                   }
  362. +               }
  363. +           } else {
  364. +               /*
  365. +                * Master transmitter: write first byte to fill shift
  366. +                * register.  We should get another TXE interrupt
  367. +                * immediately to fill DR again.
  368. +                */
  369. +               if (msg->length != 1) {
  370. +                   i2c_write(dev, msg->data[msg->xferred++]);
  371. +               }
  372. +           }
  373. +           sr1 = sr2 = 0;
  374. +       }
  375. +
  376. +       /*
  377. +        * EV8: Master transmitter
  378. +        * Transmit buffer empty, but we haven't finished transmitting the last
  379. +        * byte written.
  380. +        */
  381. +       if ((sr1 & I2C_SR1_TXE) && !(sr1 & I2C_SR1_BTF)) {
  382. +           I2C_CRUMB(TXE_ONLY, 0, 0);
  383. +           if (dev->msgs_left) {
  384. +               i2c_write(dev, msg->data[msg->xferred++]);
  385. +               if (msg->xferred == msg->length) {
  386. +                   /*
  387. +                    * End of this message. Turn off TXE/RXNE and wait for
  388. +                    * BTF to send repeated start or stop condition.
  389. +                    */
  390. +                   i2c_disable_irq(dev, I2C_IRQ_BUFFER);
  391. +                   dev->msgs_left--;
  392. +               }
  393. +           } else {
  394. +               /*
  395. +                * This should be impossible...
  396. +                */
  397. +               ASSERT(0);
  398. +           }
  399. +           sr1 = sr2 = 0;
  400. +       }
  401. +
  402. +       /*
  403. +        * EV8_2: Master transmitter
  404. +        * Last byte sent, program repeated start/stop
  405. +        */
  406. +       if ((sr1 & I2C_SR1_TXE) && (sr1 & I2C_SR1_BTF)) {
  407. +           I2C_CRUMB(TXE_BTF, 0, 0);
  408. +           if (dev->msgs_left) {
  409. +               I2C_CRUMB(TEST, 0, 0);
  410. +               /*
  411. +                * Repeated start insanity: We can't disable ITEVTEN or else SB
  412. +                * won't interrupt, but if we don't disable ITEVTEN, BTF will
  413. +                * continually interrupt us. What the fuck ST?
  414. +                */
  415. +               i2c_start_condition(dev);
  416. +               while (!(dev->regs->SR1 & I2C_SR1_SB))
  417. +                   ;
  418. +               dev->msg++;
  419. +           } else {
  420. +               i2c_stop_condition(dev);
  421. +
  422. +               /*
  423. +                * Turn off event interrupts to keep BTF from firing until
  424. +                * the end of the stop condition. Why on earth they didn't
  425. +                * have a start/stop condition request clear BTF is beyond
  426. +                * me.
  427. +                */
  428. +               i2c_disable_irq(dev, I2C_IRQ_EVENT);
  429. +               I2C_CRUMB(STOP_SENT, 0, 0);
  430. +               dev->state = I2C_STATE_XFER_DONE;
  431. +           }
  432. +           sr1 = sr2 = 0;
  433. +       }
  434. +
  435. +       /*
  436. +        * EV7: Master Receiver
  437. +        */
  438. +       if (sr1 & I2C_SR1_RXNE) {
  439. +           I2C_CRUMB(RXNE_ONLY, 0, 0);
  440. +           msg->data[msg->xferred++] = dev->regs->DR;
  441. +
  442. +           /*
  443. +            * EV7_1: Second to last byte in the reception? Set NACK and generate
  444. +            * stop/restart condition in time for the last byte. We'll get one more
  445. +            * RXNE interrupt before shutting things down.
  446. +            */
  447. +           if (msg->xferred == (msg->length - 1)) {
  448. +               i2c_disable_ack(dev);
  449. +               if (dev->msgs_left > 2) {
  450. +                   i2c_start_condition(dev);
  451. +                   I2C_CRUMB(RXNE_START_SENT, 0, 0);
  452. +               } else {
  453. +                   i2c_stop_condition(dev);
  454. +                   I2C_CRUMB(RXNE_STOP_SENT, 0, 0);
  455. +               }
  456. +           } else if (msg->xferred == msg->length) {
  457. +               dev->msgs_left--;
  458. +               if (dev->msgs_left == 0) {
  459. +                   /*
  460. +                    * We're done.
  461. +                    */
  462. +                   I2C_CRUMB(RXNE_DONE, 0, 0);
  463. +                   dev->state = I2C_STATE_XFER_DONE;
  464. +               } else {
  465. +                   dev->msg++;
  466. +               }
  467. +           }
  468. +       }
  469.      }
  470.  }
  471.  
  472. @@ -456,10 +619,46 @@ void _i2c_irq_handler(i2c_dev *dev) {
  473.  void _i2c_irq_error_handler(i2c_dev *dev) {
  474.      I2C_CRUMB(ERROR_ENTRY, dev->regs->SR1, dev->regs->SR2);
  475.  
  476. -    dev->error_flags = dev->regs->SR2 & (I2C_SR1_BERR |
  477. +    dev->error_flags = dev->regs->SR1 & (I2C_SR1_BERR |
  478.                                           I2C_SR1_ARLO |
  479.                                           I2C_SR1_AF |
  480.                                           I2C_SR1_OVR);
  481. +
  482. +    /* Are we in slave mode? */
  483. +    if ((dev->regs->SR2 & I2C_SR2_MSL) != I2C_SR2_MSL) {
  484. +       /* Check to see if the master device did a NAK on the last bit
  485. +        * This is perfectly valid for a master to do this on the bus.
  486. +        * We ignore this. Any further error processing takes us into dead
  487. +        * loop waiting for the stop condition that will never arrive
  488. +        */
  489. +       if (dev->regs->SR1 & I2C_SR1_AF) {
  490. +           /* Clear flags */
  491. +           dev->regs->SR1 = 0;
  492. +           dev->regs->SR2 = 0;
  493. +           /* We need to write something to CR1 to clear the flag.
  494. +            * This isn't really mentioned but seems important */
  495. +           i2c_enable_ack(dev);
  496. +           dev->state = I2C_STATE_IDLE;
  497. +
  498. +           if (dev->config_flags & I2C_SLAVE_USE_RX_BUFFER && dev->i2c_slave_msg->xferred > 0) {
  499. +               /* Call the callback with the contents of the data */
  500. +               if (dev->i2c_slave_recv_callback != NULL) (*(dev->i2c_slave_recv_callback))(dev->i2c_slave_msg);
  501. +           }
  502. +           return;
  503. +       }
  504. +       /* Catch any other strange errors while in slave mode.
  505. +        * I have seen BERR caused by an over fast master device
  506. +        * as well as several overflows and arbitration failures.
  507. +        * We are going to reset SR flags and carry on at this point which
  508. +        * is not the best thing to do, but stops the bus locking up completely
  509. +        * If we carry on below and send the stop bit, the code spins forever */
  510. +        /* Clear flags */
  511. +        dev->regs->SR1 = 0;
  512. +        dev->regs->SR2 = 0;
  513. +        dev->state = I2C_STATE_IDLE;
  514. +       return;
  515. +    }
  516. +
  517.      /* Clear flags */
  518.      dev->regs->SR1 = 0;
  519.      dev->regs->SR2 = 0;
  520. @@ -507,3 +706,31 @@ static void set_ccr_trise(i2c_dev *dev, uint32 flags) {
  521.      i2c_set_clk_control(dev, ccr);
  522.      i2c_set_trise(dev, trise);
  523.  }
  524. +
  525. +
  526. +/**
  527. + * @brief callback for when the device acts as a slave. If using an rx buffer, this is triggered
  528. + * after the last byte, otherwise it is called for every incoming packet.
  529. + * @param dev I2C device
  530. + * @param msg The dev_msg to pass to the slave init code
  531. + * @param func The function pointer to call
  532. + */
  533. +void i2c_slave_attach_recv_handler(i2c_dev *dev, i2c_msg *msg, i2c_slave_recv_callback_func func) {
  534. +    dev->i2c_slave_recv_callback = func;
  535. +    dev->i2c_slave_msg = msg;
  536. +    msg->xferred = 0;
  537. +}
  538. +
  539. +
  540. +/**
  541. + * @brief callback for when the device acts as a slave. If using a tx buffer, this is triggered
  542. + * after the device is successsfully addressed with SLA+R.
  543. + * @param dev I2C device
  544. + * @param msg The dev_msg to pass to the slave init code
  545. + * @param func The function pointer to call
  546. + */
  547. +void i2c_slave_attach_transmit_handler(i2c_dev *dev, i2c_msg *msg, i2c_slave_transmit_callback_func func) {
  548. +   dev->i2c_slave_transmit_callback = func;
  549. +    dev->i2c_slave_msg = msg;
  550. +    msg->xferred = 0;
  551. +}
  552. diff --git a/libmaple/i2c_private.h b/libmaple/i2c_private.h
  553. index 5b79516..7d25ae4 100644
  554. --- a/libmaple/i2c_private.h
  555. +++ b/libmaple/i2c_private.h
  556. @@ -76,4 +76,5 @@ static inline struct gpio_dev* sda_port(const i2c_dev *dev) {
  557.   * i2c_master_enable(). */
  558.  void _i2c_set_ccr_trise(i2c_dev *dev, uint32 flags);
  559.  
  560. +
  561.  #endif  /* _LIBMAPLE_I2C_PRIVATE_H_ */
  562. diff --git a/libmaple/include/libmaple/i2c.h b/libmaple/include/libmaple/i2c.h
  563. index ff1c313..146c880 100644
  564. --- a/libmaple/include/libmaple/i2c.h
  565. +++ b/libmaple/include/libmaple/i2c.h
  566. @@ -93,6 +93,7 @@ typedef struct i2c_msg {
  567.  
  568.  #define I2C_MSG_READ            0x1
  569.  #define I2C_MSG_10BIT_ADDR      0x2
  570. +
  571.      /**
  572.       * Bitwise OR of:
  573.       * - I2C_MSG_READ (write is default)
  574. @@ -197,6 +198,10 @@ typedef struct i2c_msg {
  575.  #define I2C_DUTY_16_9           0x2           // 16/9 duty ratio
  576.  /* Flag 0x4 is reserved; DO NOT USE. */
  577.  #define I2C_BUS_RESET           0x8           // Perform a bus reset
  578. +#define I2C_SLAVE_USE_RX_BUFFER     0x10          // Use a buffered message when doing a slave recv
  579. +#define I2C_SLAVE_USE_TX_BUFFER     0x20          // Use a buffered message when doing a slave transmit
  580. +#define I2C_SLAVE_DUAL_ADDRESS  0x40          // Enable the dual slave address scheme
  581. +#define I2C_SLAVE_GENERAL_CALL  0x80          // Enable the dual slave address scheme
  582.  void i2c_master_enable(i2c_dev *dev, uint32 flags);
  583.  
  584.  #define I2C_ERROR_PROTOCOL      (-1)
  585. @@ -406,6 +411,53 @@ static inline void i2c_set_trise(i2c_dev *dev, uint32 trise) {
  586.      dev->regs->TRISE = trise;
  587.  }
  588.  
  589. +/* Barry Carter
  590. + * Slave support
  591. + */
  592. +
  593. +/**
  594. + * @brief Enable Dual addressing mode to allow peripheral to have 2 addresses
  595. + * @param dev I2C device
  596. +  */
  597. +static inline void i2c_slave_dual_address_enable(i2c_dev *dev) {
  598. +    dev->regs->OAR2 |= I2C_OAR2_ENDUAL;
  599. +}
  600. +
  601. +/**
  602. + * @brief Enable General Call to allow the  unit to respond on addr 0x00
  603. + * @param dev I2C device
  604. +  */
  605. +static inline void i2c_slave_general_call_enable(i2c_dev *dev) {
  606. +    dev->regs->CR1 |= I2C_CR1_ENGC;
  607. +}
  608. +
  609. +/* callback functions */
  610. +/* Callback handler for data received over the bus */
  611. +void i2c_slave_attach_recv_handler(i2c_dev *dev, i2c_msg *msg, i2c_slave_recv_callback_func func);
  612. +
  613. +/* Callback handler for data being requested over the bus
  614. + * The callback function must call i2c_write to get the data over the bus
  615. + */
  616. +void i2c_slave_attach_transmit_handler(i2c_dev *dev, i2c_msg *msg, i2c_slave_transmit_callback_func func);
  617. +
  618. +/**
  619. + * @brief Set the primary I2c slave address
  620. + * @param dev I2C device
  621. + * @param address the 8 or 10 bit i2c address
  622. +  */
  623. +static inline void i2c_slave_set_own_address(i2c_dev *dev, uint16 address) {
  624. +    dev->regs->OAR1 = address <<1;
  625. +}
  626. +
  627. +/**
  628. + * @brief Set the secondary I2c slave address
  629. + * @param dev I2C device
  630. + * @param address the 8 or 10 bit i2c address
  631. +  */
  632. +static inline void i2c_slave_set_own_address2(i2c_dev *dev, uint16 address) {
  633. +   dev->regs->OAR2 = (address <<1 ) | I2C_OAR2_ENDUAL;
  634. +}
  635. +
  636.  #ifdef __cplusplus
  637.  }
  638.  #endif
  639. diff --git a/libmaple/include/libmaple/i2c_common.h b/libmaple/include/libmaple/i2c_common.h
  640. index 17cabe3..7337240 100644
  641. --- a/libmaple/include/libmaple/i2c_common.h
  642. +++ b/libmaple/include/libmaple/i2c_common.h
  643. @@ -55,6 +55,8 @@ typedef enum i2c_state {
  644.      I2C_STATE_ERROR             = -1 /**< Error occurred */
  645.  } i2c_state;
  646.  
  647. +typedef void (*i2c_slave_recv_callback_func)(struct i2c_msg *);
  648. +typedef void (*i2c_slave_transmit_callback_func)(struct i2c_msg *);
  649.  /**
  650.   * @brief I2C device type.
  651.   */
  652. @@ -88,6 +90,17 @@ typedef struct i2c_dev {
  653.      nvic_irq_num ev_nvic_line;  /**< Event IRQ number */
  654.      nvic_irq_num er_nvic_line;  /**< Error IRQ number */
  655.      volatile i2c_state state;   /**< Device state */
  656. +    uint32 config_flags;       /**< Configuration flags */
  657. +
  658. +    /* Barry Carter
  659. +     * Slave implementation. Callback functions in this struct allow
  660. +     * for a separate callback function for each I2C unit available onboard
  661. +     */
  662. +    i2c_slave_transmit_callback_func i2c_slave_transmit_callback;
  663. +    i2c_slave_recv_callback_func i2c_slave_recv_callback;
  664. +
  665. +    struct i2c_msg *i2c_slave_msg; /* the message that the i2c slave will use */
  666. +
  667.  } i2c_dev;
  668.  
  669.  #endif
Advertisement
Add Comment
Please, Sign In to add comment