1 /**
2 * @file i2c-board.c
3 *
4 * @brief Target board I2C driver implementation
5 *
6 * @copyright Copyright (c) 2020 The Things Industries B.V.
7 *
8 * Revised BSD License
9 * Copyright The Things Industries B.V 2020. All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * * Neither the name of the Things Industries B.V nor the
19 * names of its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE THINGS INDUSTRIES B.V BE LIABLE FOR ANY
26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <peripheral_clk_config.h>
35 #include <hal_gpio.h>
36 #include <hal_i2c_m_sync.h>
37
38 #include "board.h"
39 #include "i2c-board.h"
40
41 struct i2c_m_sync_desc I2C_INSTANCE;
42
I2cMcuInit(I2c_t * obj,I2cId_t i2cId,PinNames scl,PinNames sda)43 void I2cMcuInit( I2c_t* obj, I2cId_t i2cId, PinNames scl, PinNames sda )
44 {
45 obj->I2cId = i2cId;
46
47 // Clock initialization
48 hri_gclk_write_PCHCTRL_reg( GCLK, SERCOM1_GCLK_ID_CORE,
49 CONF_GCLK_SERCOM1_CORE_SRC | ( 1 << GCLK_PCHCTRL_CHEN_Pos ) );
50 hri_gclk_write_PCHCTRL_reg( GCLK, SERCOM1_GCLK_ID_SLOW,
51 CONF_GCLK_SERCOM1_SLOW_SRC | ( 1 << GCLK_PCHCTRL_CHEN_Pos ) );
52
53 hri_mclk_set_APBCMASK_SERCOM1_bit( MCLK );
54
55 // I2c initialization
56 i2c_m_sync_init( &I2C_INSTANCE, SERCOM1 );
57
58 gpio_set_pin_function( sda, PINMUX_PA16C_SERCOM1_PAD0 );
59 gpio_set_pin_function( scl, PINMUX_PA17C_SERCOM1_PAD1 );
60
61 i2c_m_sync_enable( &I2C_INSTANCE );
62 }
63
I2cMcuDeInit(I2c_t * obj)64 void I2cMcuDeInit( I2c_t* obj )
65 {
66 // Left empty
67 }
68
I2cMcuFormat(I2c_t * obj,I2cMode mode,I2cDutyCycle dutyCycle,bool I2cAckEnable,I2cAckAddrMode AckAddrMode,uint32_t I2cFrequency)69 void I2cMcuFormat( I2c_t* obj, I2cMode mode, I2cDutyCycle dutyCycle, bool I2cAckEnable, I2cAckAddrMode AckAddrMode,
70 uint32_t I2cFrequency )
71 {
72 // configured via hpl_sercom_config.h
73 return;
74 }
75
I2cMcuWriteBuffer(I2c_t * obj,uint8_t deviceAddr,uint8_t * buffer,uint16_t size)76 LmnStatus_t I2cMcuWriteBuffer( I2c_t *obj, uint8_t deviceAddr, uint8_t *buffer, uint16_t size )
77 {
78 i2c_m_sync_set_slaveaddr( &I2C_INSTANCE, deviceAddr, I2C_M_SEVEN );
79 if( io_write( &I2C_INSTANCE.io, buffer, size ) == size )
80 {
81 return 1; // ok
82 }
83 else
84 {
85 return 0; // something went wrong
86 }
87 }
88
I2cMcuReadBuffer(I2c_t * obj,uint8_t deviceAddr,uint8_t * buffer,uint16_t size)89 LmnStatus_t I2cMcuReadBuffer( I2c_t *obj, uint8_t deviceAddr, uint8_t *buffer, uint16_t size )
90 {
91 i2c_m_sync_set_slaveaddr( &I2C_INSTANCE, deviceAddr, I2C_M_SEVEN );
92 if( io_read( &I2C_INSTANCE.io, buffer, size ) == size )
93 {
94 return 1; // ok
95 }
96 else
97 {
98 return 0; // something went wrong
99 }
100 }
101
I2cMcuWriteMemBuffer(I2c_t * obj,uint8_t deviceAddr,uint16_t addr,uint8_t * buffer,uint16_t size)102 LmnStatus_t I2cMcuWriteMemBuffer( I2c_t* obj, uint8_t deviceAddr, uint16_t addr, uint8_t* buffer, uint16_t size )
103 {
104 i2c_m_sync_set_slaveaddr( &I2C_INSTANCE, deviceAddr, I2C_M_SEVEN );
105 if( i2c_m_sync_cmd_write( &I2C_INSTANCE, addr, buffer, size ) == size )
106 {
107 return 1; // ok
108 }
109 else
110 {
111 return 0; // something went wrong
112 }
113 }
114
I2cMcuReadMemBuffer(I2c_t * obj,uint8_t deviceAddr,uint16_t addr,uint8_t * buffer,uint16_t size)115 LmnStatus_t I2cMcuReadMemBuffer( I2c_t* obj, uint8_t deviceAddr, uint16_t addr, uint8_t* buffer, uint16_t size )
116 {
117 i2c_m_sync_set_slaveaddr( &I2C_INSTANCE, deviceAddr, I2C_M_SEVEN );
118 if( i2c_m_sync_cmd_read( &I2C_INSTANCE, addr, buffer, size ) == size )
119 {
120 return 1; // ok
121 }
122 else
123 {
124 return 0; // something went wrong
125 }
126 }