1 #include "i2c_interface.h" 13 #include "RTT/SEGGER_RTT.h" 15 #define I2C_TX_BUFFER_SIZE 2 16 #define I2C_RX_BUFFER_SIZE 5 22 static volatile uint8_t rx_buffer[I2C_RX_BUFFER_SIZE];
26 static volatile uint8_t tx_buffer[I2C_TX_BUFFER_SIZE];
31 static volatile bool error = FALSE;
33 static virtual_timer_t i2c_vt;
38 static I2CConfig i2c_slave_cfg = {
45 static I2CSlaveMsgCB i2c_error, i2c_reply, i2c_address_match;
77 const I2CSlaveMsg i2c_request = {
88 I2CSlaveMsg i2c_response = {
97 static int32_t float_to_int32(
float x){
99 memcpy(&result, &x,
sizeof(result));
103 static float int32_to_float(int32_t x){
105 memcpy(&result, &x,
sizeof(result));
113 static void i2c_reply(I2CDriver* i2cp) {
120 void i2c_error(I2CDriver* i2cp)
126 static void rx_special_cases(uint8_t addr) {
127 static int32_t tmp_right_wheel_dist = 0;
128 static int32_t tmp_left_wheel_dist = 0;
129 static int32_t tmp_goal_mean_dist = 0;
132 static int32_t tmp_cur_x;
133 static int32_t tmp_cur_y;
135 printf(
"rx_buffer = %x %d %d\n", rx_buffer[0], rx_buffer[1], rx_buffer[2]);
138 case STORE_DATA_IN_FLASH_ADDR:
141 case RESET_ORIENTATION_ADDR:
142 chBSemSignal(&reset_orientation_sem);
144 case CUR_POS_X_LOW_ADDR:
145 tmp_cur_x = (rx_buffer[2] << 8) | rx_buffer[1];
147 case CUR_POS_X_HIGH_ADDR:
148 tmp_cur_x |= (rx_buffer[2] << 24) | (rx_buffer[1] << 16);
149 cur_pos.x = int32_to_float(tmp_cur_x);
151 case CUR_POS_Y_LOW_ADDR:
152 tmp_cur_y = (rx_buffer[2] << 8) | rx_buffer[1];
154 case CUR_POS_Y_HIGH_ADDR:
155 tmp_cur_y |= (rx_buffer[2] << 24) | (rx_buffer[1] << 16);
156 cur_pos.y = int32_to_float(tmp_cur_y);
158 case CUR_RIGHT_WHEEL_DIST_LOW_ADDR:
159 tmp_right_wheel_dist = (rx_buffer[2] << 8) | rx_buffer[1];
161 case CUR_RIGHT_WHEEL_DIST_HIGH_ADDR:
162 tmp_right_wheel_dist |= (rx_buffer[2] << 24) | (rx_buffer[1] << 16);
165 case CUR_LEFT_WHEEL_DIST_LOW_ADDR:
166 tmp_left_wheel_dist = (rx_buffer[2] << 8) | rx_buffer[1];
168 case CUR_LEFT_WHEEL_DIST_HIGH_ADDR:
169 tmp_left_wheel_dist |= (rx_buffer[2] << 24) | (rx_buffer[1] << 16);
172 case CUR_HEADING_ADDR:
173 tmp = (rx_buffer[2] << 8) | rx_buffer[1];
175 while (tmp2 < HEADING_MIN_VALUE) {
176 tmp2 += HEADING_RANGE;
178 while (tmp2 > HEADING_MAX_VALUE) {
179 tmp2 -= HEADING_RANGE;
181 heading_offset = tmp - tmp2;
184 case GOAL_MEAN_DIST_LOW_ADDR:
185 tmp_goal_mean_dist = (rx_buffer[2] << 8) | rx_buffer[1];
187 case GOAL_MEAN_DIST_HIGH_ADDR:
188 tmp_goal_mean_dist |= (rx_buffer[2] << 24) | (rx_buffer[1] << 16);
189 goal.mean_dist = tmp_goal_mean_dist;
190 dist_command_received = TRUE;
192 case GOAL_HEADING_ADDR:
194 if (((rx_buffer[2] << 8) | rx_buffer[1]) <= 360) {
196 goal.heading = ((rx_buffer[2] << 8) | rx_buffer[1]) * 16;
199 printf(
"Invalid GOAL_HEADING received : rx_buffer = 0x%x; %d; %d\n",
200 rx_buffer[0], rx_buffer[1], rx_buffer[2]);
208 static void tx_special_cases(uint8_t addr, uint16_t *value) {
209 static int32_t saved_left_wheel_dist = 0;
210 static int32_t saved_right_wheel_dist = 0;
211 static int32_t saved_cur_x;
212 static int32_t saved_cur_y;
215 case CUR_POS_X_LOW_ADDR:
216 saved_cur_x = float_to_int32(
cur_pos.x);
217 *value = saved_cur_x & 0x0000FFFFU;
219 case CUR_POS_X_HIGH_ADDR:
220 *value = (saved_cur_x & 0xFFFF0000U) >> 16U;
222 case CUR_POS_Y_LOW_ADDR:
223 saved_cur_y = float_to_int32(
cur_pos.y);
224 *value = saved_cur_y & 0x0000FFFFU;
226 case CUR_POS_Y_HIGH_ADDR:
227 *value = (saved_cur_y & 0xFFFF0000) >> 16U;
229 case CUR_RIGHT_WHEEL_DIST_LOW_ADDR:
231 *value = saved_right_wheel_dist & 0x0000FFFF;
233 case CUR_RIGHT_WHEEL_DIST_HIGH_ADDR:
234 *value = (saved_right_wheel_dist & 0xFFFF0000) >> 16U;
236 case CUR_LEFT_WHEEL_DIST_LOW_ADDR:
238 *value = saved_left_wheel_dist & 0x0000FFFF;
240 case CUR_LEFT_WHEEL_DIST_HIGH_ADDR:
241 *value = (saved_left_wheel_dist & 0xFFFF0000) >> 16U;
243 case CUR_HEADING_ADDR:
246 case GOAL_HEADING_ADDR:
247 *value = goal.heading / 16;
256 #include "i2c_interface_gen.c" 261 extern void i2c_slave_init(I2CDriver* i2cp)
268 chVTObjectInit(&i2c_vt);
274 for (i = 0; i < I2C_RX_BUFFER_SIZE; ++i) {
275 rx_buffer[i] = NO_DATA;
279 ((I2CDriver*)i2cp)->slaveTimeout = MS2ST(100);
280 i2cStart(i2cp, &i2c_slave_cfg);
281 i2cSlaveConfigure(i2cp, &i2c_request, &i2c_response);
282 i2cMatchAddress(i2cp, I2C_SLAVE_ADDRESS);
int32_t store_data_in_flash(void)
Save configuration data in flash.
volatile robot_settings_t settings
Global variable used to store the configuration in use.