Advertisement
Guest User

libmaple i2c slave code

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