Guest User

libmaple i2c slave code

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