Advertisement
manitou

i2c.h maple I2C slave

Apr 9th, 2012
433
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.81 KB | None | 0 0
  1. /******************************************************************************
  2.  * The MIT License
  3.  *
  4.  * Copyright (c) 2010 Perry Hung.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person
  7.  * obtaining a copy of this software and associated documentation
  8.  * files (the "Software"), to deal in the Software without
  9.  * restriction, including without limitation the rights to use, copy,
  10.  * modify, merge, publish, distribute, sublicense, and/or sell copies
  11.  * of the Software, and to permit persons to whom the Software is
  12.  * furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be
  15.  * included in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  21.  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  22.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24.  * SOFTWARE.
  25.  *****************************************************************************/
  26.  
  27. /**
  28.  * @file i2c.h
  29.  * @brief Inter-Integrated Circuit (I2C) peripheral support
  30.  */
  31.  
  32. #include "libmaple_types.h"
  33. #include "rcc.h"
  34. #include "nvic.h"
  35. #include "gpio.h"
  36.  
  37. #ifndef _I2C_H_
  38. #define _I2C_H_
  39.  
  40. /** I2C register map type */
  41. typedef struct i2c_reg_map {
  42.     __io uint32 CR1;            /**< Control register 1 */
  43.     __io uint32 CR2;            /**< Control register 2 */
  44.     __io uint32 OAR1;           /**< Own address register 1 */
  45.     __io uint32 OAR2;           /**< Own address register 2 */
  46.     __io uint32 DR;             /**< Data register */
  47.     __io uint32 SR1;            /**< Status register 1 */
  48.     __io uint32 SR2;            /**< Status register 2 */
  49.     __io uint32 CCR;            /**< Clock control register */
  50.     __io uint32 TRISE;          /**< TRISE (rise time) register */
  51. } i2c_reg_map;
  52.  
  53. /** I2C device states */
  54. typedef enum i2c_state {
  55.     I2C_STATE_DISABLED          = 0, /**< Disabled */
  56.     I2C_STATE_IDLE              = 1, /**< Idle */
  57.     I2C_STATE_XFER_DONE         = 2, /**< Done with transfer */
  58.     I2C_STATE_BUSY              = 3, /**< Busy */
  59.     I2C_STATE_ERROR             = -1 /**< Error occurred */
  60. } i2c_state;
  61.  
  62. /**
  63.  * @brief I2C message type
  64.  */
  65. typedef struct i2c_msg {
  66.     uint16 addr;                /**< Address */
  67. #define I2C_MSG_READ            0x1
  68. #define I2C_MSG_10BIT_ADDR      0x2
  69.     uint16 flags;               /**< Bitwise OR of I2C_MSG_READ and
  70.                                      I2C_MSG_10BIT_ADDR */
  71.     uint16 length;              /**< Message length */
  72.     uint16 xferred;             /**< Messages transferred */
  73.     uint8 *data;                /**< Data */
  74. } i2c_msg;
  75.  
  76. /**
  77.  * @brief I2C device type.
  78.  */
  79. typedef struct i2c_dev {
  80.     i2c_reg_map *regs;          /**< Register map */
  81.     gpio_dev *gpio_port;        /**< SDA, SCL pins' GPIO port */
  82.     uint8 sda_pin;              /**< SDA bit on gpio_port */
  83.     uint8 scl_pin;              /**< SCL bit on gpio_port */
  84.     rcc_clk_id clk_id;          /**< RCC clock information */
  85.     nvic_irq_num ev_nvic_line;  /**< Event IRQ number */
  86.     nvic_irq_num er_nvic_line;  /**< Error IRQ number */
  87.     volatile i2c_state state;   /**< Device state */
  88.     uint16 msgs_left;           /**< Messages left */
  89.     i2c_msg *msg;               /**< Messages */
  90.     volatile uint32 timestamp;  /**< For internal use */
  91.     uint32 error_flags;         /**< Error flags, set on I2C error condition */
  92. } i2c_dev;
  93.  
  94. /*
  95.  * Devices
  96.  */
  97.  
  98. extern i2c_dev* const I2C1;
  99. extern i2c_dev* const I2C2;
  100.  
  101. /*
  102.  * Register map base pointers
  103.  */
  104.  
  105. /** I2C1 register map base pointer */
  106. #define I2C1_BASE               ((struct i2c_reg_map*)0x40005400)
  107. /** I2C2 register map base pointer */
  108. #define I2C2_BASE               ((struct i2c_reg_map*)0x40005800)
  109.  
  110. /*
  111.  * Register bit definitions
  112.  */
  113.  
  114. /* Control register 1 */
  115.  
  116. #define I2C_CR1_SWRST           BIT(15)       // Software reset
  117. #define I2C_CR1_ALERT           BIT(13)       // SMBus alert
  118. #define I2C_CR1_PEC             BIT(12)       // Packet error checking
  119. #define I2C_CR1_POS             BIT(11)       // Acknowledge/PEC position
  120. #define I2C_CR1_ACK             BIT(10)       // Acknowledge enable
  121. #define I2C_CR1_START           BIT(8)        // Start generation
  122. #define I2C_CR1_STOP            BIT(9)        // Stop generation
  123. #define I2C_CR1_PE              BIT(0)        // Peripheral Enable
  124.  
  125. /* Control register 2 */
  126.  
  127. #define I2C_CR2_LAST            BIT(12)       // DMA last transfer
  128. #define I2C_CR2_DMAEN           BIT(11)       // DMA requests enable
  129. #define I2C_CR2_ITBUFEN         BIT(10)       // Buffer interrupt enable
  130. #define I2C_CR2_ITEVTEN         BIT(9)        // Event interupt enable
  131. #define I2C_CR2_ITERREN         BIT(8)        // Error interupt enable
  132. #define I2C_CR2_FREQ            0xFFF         // Peripheral input frequency
  133.  
  134. /* Clock control register */
  135.  
  136. #define I2C_CCR_FS              BIT(15)       // Fast mode selection
  137. #define I2C_CCR_DUTY            BIT(14)       // 16/9 duty ratio
  138. #define I2C_CCR_CCR             0xFFF         // Clock control bits
  139.  
  140. /* Status register 1 */
  141.  
  142. #define I2C_SR1_SB              BIT(0)        // Start bit
  143. #define I2C_SR1_ADDR            BIT(1)        // Address sent/matched
  144. #define I2C_SR1_BTF             BIT(2)        // Byte transfer finished
  145. #define I2C_SR1_ADD10           BIT(3)        // 10-bit header sent
  146. #define I2C_SR1_STOPF           BIT(4)        // Stop detection
  147. #define I2C_SR1_RXNE            BIT(6)        // Data register not empty
  148. #define I2C_SR1_TXE             BIT(7)        // Data register empty
  149. #define I2C_SR1_BERR            BIT(8)        // Bus error
  150. #define I2C_SR1_ARLO            BIT(9)        // Arbitration lost
  151. #define I2C_SR1_AF              BIT(10)       // Acknowledge failure
  152. #define I2C_SR1_OVR             BIT(11)       // Overrun/underrun
  153. #define I2C_SR1_PECERR          BIT(12)       // PEC Error in reception
  154. #define I2C_SR1_TIMEOUT         BIT(14)       // Timeout or Tlow error
  155. #define I2C_SR1_SMBALERT        BIT(15)       // SMBus alert
  156.  
  157. /* Status register 2 */
  158.  
  159. #define I2C_SR2_MSL             BIT(0)        // Master/slave
  160. #define I2C_SR2_BUSY            BIT(1)        // Bus busy
  161. #define I2C_SR2_TRA             BIT(2)        // Transmitter/receiver
  162. #define I2C_SR2_GENCALL         BIT(4)        // General call address
  163. #define I2C_SR2_SMBDEFAULT      BIT(5)        // SMBus device default address
  164. #define I2C_SR2_SMBHOST         BIT(6)        // SMBus host header
  165. #define I2C_SR2_DUALF           BIT(7)        // Dual flag
  166. #define I2C_SR2_PEC             0xFF00        // Packet error checking register
  167.  
  168. /*
  169.  * Convenience routines
  170.  */
  171.  
  172. #ifdef __cplusplus
  173. extern "C" {
  174. #endif
  175.  
  176. // thd slave stuff
  177. uint32 i2c_slave_available(i2c_dev *dev);
  178. uint32 i2c_slave_request(i2c_dev *dev);
  179. uint8 i2c_slave_read(i2c_dev *dev);
  180. void i2c_slave_enable(i2c_dev *dev, uint8 i2c_slaveid, uint32 flags);
  181. void i2c_slave_write(i2c_dev *dev, uint8 *data, int count);
  182. void i2c_attachSlaveRxEvent(i2c_dev *dev, void (*)(int));
  183. void i2c_attachSlaveTxEvent(i2c_dev *dev, void (*)(void));
  184.  
  185. void i2c_init(i2c_dev *dev);
  186.  
  187. /* I2C enable options */
  188. #define I2C_FAST_MODE           BIT(0)      // 400 khz
  189. #define I2C_DUTY_16_9           BIT(1)      // 16/9 duty ratio
  190. #define I2C_REMAP               BIT(2)      // Use alternate pin mapping
  191. #define I2C_BUS_RESET           BIT(3)      // Perform a bus reset
  192. void i2c_master_enable(i2c_dev *dev, uint32 flags);
  193.  
  194. #define I2C_ERROR_PROTOCOL      (-1)
  195. #define I2C_ERROR_TIMEOUT       (-2)
  196. int32 i2c_master_xfer(i2c_dev *dev, i2c_msg *msgs, uint16 num, uint32 timeout);
  197.  
  198. void i2c_bus_reset(const i2c_dev *dev);
  199.  
  200. /**
  201.  * @brief Disable an I2C device
  202.  *
  203.  * This function disables the corresponding peripheral and marks dev's
  204.  * state as I2C_STATE_DISABLED.
  205.  *
  206.  * @param dev Device to disable.
  207.  */
  208. static inline void i2c_disable(i2c_dev *dev) {
  209.     dev->regs->CR1 &= ~I2C_CR1_PE;
  210.     dev->state = I2C_STATE_DISABLED;
  211. }
  212.  
  213. /**
  214.  * @brief Turn on an I2C peripheral
  215.  * @param dev Device to enable
  216.  */
  217. static inline void i2c_peripheral_enable(i2c_dev *dev) {
  218.     dev->regs->CR1 |= I2C_CR1_PE;
  219. }
  220.  
  221. /**
  222.  * @brief Turn off an I2C peripheral
  223.  * @param dev Device to turn off
  224.  */
  225. static inline void i2c_peripheral_disable(i2c_dev *dev) {
  226.     dev->regs->CR1 &= ~I2C_CR1_PE;
  227. }
  228.  
  229. /**
  230.  * @brief Fill transmit register
  231.  * @param dev I2C device
  232.  * @param byte Byte to write
  233.  */
  234. static inline void i2c_write(i2c_dev *dev, uint8 byte) {
  235.     dev->regs->DR = byte;
  236. }
  237.  
  238. /**
  239.  * @brief Set input clock frequency, in MHz
  240.  * @param dev I2C device
  241.  * @param freq Frequency in megahertz (2-36)
  242.  */
  243. static inline void i2c_set_input_clk(i2c_dev *dev, uint32 freq) {
  244.     uint32 cr2 = dev->regs->CR2;
  245.     cr2 &= ~I2C_CR2_FREQ;
  246.     cr2 |= freq;
  247.     dev->regs->CR2 = freq;
  248. }
  249.  
  250. /**
  251.  * @brief Set I2C clock control register. See RM008
  252.  * @param dev I2C device
  253.  * @param val Value to use for clock control register (in
  254.  *            Fast/Standard mode)
  255.  */
  256. static inline void i2c_set_clk_control(i2c_dev *dev, uint32 val) {
  257.     uint32 ccr = dev->regs->CCR;
  258.     ccr &= ~I2C_CCR_CCR;
  259.     ccr |= val;
  260.     dev->regs->CCR = ccr;
  261. }
  262.  
  263.  
  264. /**
  265.  * @brief Set SCL rise time
  266.  * @param dev I2C device
  267.  * @param trise Maximum rise time in fast/standard mode (see RM0008
  268.  *              for relevant formula).
  269.  */
  270. static inline void i2c_set_trise(i2c_dev *dev, uint32 trise) {
  271.     dev->regs->TRISE = trise;
  272. }
  273.  
  274.  
  275. /**
  276.  * @brief Generate a start condition on the bus.
  277.  * @param dev I2C device
  278.  */
  279. static inline void i2c_start_condition(i2c_dev *dev) {
  280.     uint32 cr1;
  281.     while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
  282.                                      I2C_CR1_STOP  |
  283.                                      I2C_CR1_PEC)) {
  284.         ;
  285.     }
  286.     dev->regs->CR1 |= I2C_CR1_START;
  287. }
  288.  
  289. /**
  290.  * @brief Generate a stop condition on the bus
  291.  * @param dev I2C device
  292.  */
  293. static inline void i2c_stop_condition(i2c_dev *dev) {
  294.     uint32 cr1;
  295.     while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
  296.                                      I2C_CR1_STOP  |
  297.                                      I2C_CR1_PEC)) {
  298.         ;
  299.     }
  300.     dev->regs->CR1 |= I2C_CR1_STOP;
  301.     while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
  302.                                      I2C_CR1_STOP  |
  303.                                      I2C_CR1_PEC)) {
  304.         ;
  305.     }
  306.  
  307. }
  308.  
  309. /**
  310.  * @brief Enable one or more I2C interrupts
  311.  * @param dev I2C device
  312.  * @param irqs Bitwise or of:
  313.  *             I2C_IRQ_ERROR (error interrupt),
  314.  *             I2C_IRQ_EVENT (event interrupt), and
  315.  *             I2C_IRQ_BUFFER (buffer interrupt).
  316.  */
  317. #define I2C_IRQ_ERROR              I2C_CR2_ITERREN
  318. #define I2C_IRQ_EVENT              I2C_CR2_ITEVTEN
  319. #define I2C_IRQ_BUFFER             I2C_CR2_ITBUFEN
  320. static inline void i2c_enable_irq(i2c_dev *dev, uint32 irqs) {
  321.     dev->regs->CR2 |= irqs;
  322. }
  323.  
  324. /**
  325.  * @brief Disable one or more I2C interrupts
  326.  * @param dev I2C device
  327.  * @param irqs Bitwise or of:
  328.  *             I2C_IRQ_ERROR (error interrupt),
  329.  *             I2C_IRQ_EVENT (event interrupt), and
  330.  *             I2C_IRQ_BUFFER (buffer interrupt).
  331.  */
  332. static inline void i2c_disable_irq(i2c_dev *dev, uint32 irqs) {
  333.     dev->regs->CR2 &= ~irqs;
  334. }
  335.  
  336.  
  337. /**
  338.  * @brief Enable I2C acknowledgment
  339.  * @param dev I2C device
  340.  */
  341. static inline void i2c_enable_ack(i2c_dev *dev) {
  342.     dev->regs->CR1 |= I2C_CR1_ACK;
  343. }
  344.  
  345. /**
  346.  * @brief Disable I2C acknowledgment
  347.  * @param dev I2C device
  348.  */
  349. static inline void i2c_disable_ack(i2c_dev *dev) {
  350.     dev->regs->CR1 &= ~I2C_CR1_ACK;
  351. }
  352.  
  353. #ifdef __cplusplus
  354. }
  355. #endif
  356.  
  357. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement