Advertisement
Guest User

libmaple i2c slave code

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