00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <p30f6014a.h>
00032
00033 #include "e-puck/library/motor_led/e_epuck_ports.h"
00034 #include "e-puck/library/motor_led/e_init_port.h"
00035 #include "e-puck/library/motor_led/e_led.h"
00036 #include "e-puck/library/motor_led/advance_one_timer/e_motors.h"
00037 #include "e-puck/library/motor_led/advance_one_timer/e_agenda.h"
00038 #include "e-puck/library/camera/fast_2_timer/e_poxxxx.h"
00039 #include "e-puck/library/uart/e_uart_char.h"
00040 #include "e-puck/library/a_d/advance_ad_scan/e_ad_conv.h"
00041 #include "e-puck/library/a_d/advance_ad_scan/e_prox.h"
00042 #include "e-puck/library/a_d/advance_ad_scan/e_acc.h"
00043 #include "e-puck/library/I2C/e_I2C_protocol.h"
00044
00045 #include "libpic30.h"
00046
00047
00048 #include <string.h>
00049
00050 #define ASEBA_ASSERT
00051 #include <vm/vm.h>
00052 #include <common/consts.h>
00053 #include <vm/natives.h>
00054 #include <transport/buffer/vm-buffer.h>
00055
00056 #define LIS_GROUND_SENSORS
00057
00058 #define vmVariablesSize (sizeof(struct EPuckVariables) / sizeof(sint16))
00059 #define vmStackSize 32
00060 #define argsSize 32
00061
00062
00063 unsigned int __attribute((far)) cam_data[60];
00064
00065
00066
00067 #define CAM_RED(pixel) ( 3 * (((pixel) >> 3) & 0x1f))
00068
00069 #define CAM_GREEN(pixel) ((3 * ((((pixel) & 0x7) << 3) | ((pixel) >> 13))) >> 1)
00070
00071 #define CAM_BLUE(pixel) ( 3 * (((pixel) >> 8) & 0x1f))
00072
00073 #define CLAMP(v, vmin, vmax) ((v) < (vmin) ? (vmin) : (v) > (vmax) ? (vmax) : (v))
00074
00075
00076
00077
00078
00079
00080 #define SET_EVENT(event) do {events_flags |= 1 << event;} while(0)
00081 #define CLEAR_EVENT(event) do {events_flags &= ~(1 << event);} while(0)
00082 #define IS_EVENT(event) (events_flags & (1 << event))
00083
00084
00085
00086
00087 #define VM_BYTECODE_SIZE 1024
00088 #define VM_STACK_SIZE 32
00089
00090 int _EEDATA(1) bytecode_version;
00091 unsigned char _EEDATA(1) eeprom_bytecode[VM_BYTECODE_SIZE*2];
00092
00093 struct EPuckVariables
00094 {
00095
00096 sint16 id;
00097
00098 sint16 source;
00099
00100 sint16 args[argsSize];
00101
00102 sint16 leftSpeed;
00103 sint16 rightSpeed;
00104
00105 sint16 leds[8];
00106
00107 sint16 prox[8];
00108 sint16 ambiant[8];
00109
00110 sint16 acc[3];
00111
00112 sint16 camLine;
00113 sint16 camR[60];
00114 sint16 camG[60];
00115 sint16 camB[60];
00116
00117 sint16 freeSpace[128];
00118 } __attribute__ ((far)) ePuckVariables;
00119
00120 char name[] = "e-puck0";
00121
00122 AsebaVMDescription vmDescription = {
00123 name,
00124 {
00125 { 1, "id" },
00126 { 1, "source" },
00127 { argsSize, "args" },
00128 {1, "leftSpeed"},
00129 {1, "rightSpeed"},
00130
00131 {8, "leds"},
00132
00133 {8, "prox"},
00134 {8, "ambiant"},
00135
00136 {3, "acc"},
00137
00138 {1, "camLine"},
00139 {60, "camR"},
00140 {60, "camG"},
00141 {60, "camB"},
00142
00143 { 0, NULL }
00144 }
00145 };
00146
00147 static uint16 vmBytecode[VM_BYTECODE_SIZE];
00148
00149 static sint16 vmStack[VM_STACK_SIZE];
00150
00151 static AsebaVMState vmState = {
00152 0x1,
00153
00154 VM_BYTECODE_SIZE,
00155 vmBytecode,
00156
00157 sizeof(ePuckVariables) / sizeof(sint16),
00158 (sint16*)&ePuckVariables,
00159
00160 VM_STACK_SIZE,
00161 vmStack
00162 };
00163
00164 const AsebaVMDescription* AsebaGetVMDescription(AsebaVMState *vm)
00165 {
00166 return &vmDescription;
00167 }
00168
00169
00170
00171
00172 static unsigned int events_flags = 0;
00173 enum Events
00174 {
00175 EVENT_IR_SENSORS = 0,
00176 EVENT_CAMERA,
00177 EVENTS_COUNT
00178 };
00179
00180 static const AsebaLocalEventDescription localEvents[] = {
00181 {"ir_sensors", "New IR sensors values available"},
00182 {"camera", "New camera picture available"},
00183 { NULL, NULL }
00184 };
00185
00186 const AsebaLocalEventDescription * AsebaGetLocalEventsDescriptions(AsebaVMState *vm)
00187 {
00188 return localEvents;
00189 }
00190
00191 #ifdef LIS_GROUND_SENSORS
00192 void EpuckNative_get_ground_values(AsebaVMState *vm)
00193 {
00194
00195 uint16 dest = AsebaNativePopArg(vm);
00196 uint16 i;
00197 e_i2cp_enable();
00198
00199 for (i = 0; i < 3; i++)
00200 {
00201 unsigned int temp;
00202 temp = e_i2cp_read(0xC0,i*2) << 8;
00203 temp |= e_i2cp_read(0xC0,i*2+1);
00204 vm->variables[dest++] = temp;
00205 }
00206 e_i2cp_disable();
00207 }
00208
00209 AsebaNativeFunctionDescription EpuckNativeDescription_get_ground_values =
00210 {
00211 "get_ground_values",
00212 "read the values of the ground sensors",
00213 {
00214 { 3, "dest" },
00215 { 0, 0 }
00216 }
00217 };
00218 #endif
00219
00220 static const AsebaNativeFunctionDescription* nativeFunctionsDescription[] = {
00221 ASEBA_NATIVES_STD_DESCRIPTIONS,
00222 #ifdef LIS_GROUND_SENSORS
00223 &EpuckNativeDescription_get_ground_values,
00224 #endif
00225 0
00226 };
00227
00228 static AsebaNativeFunctionPointer nativeFunctions[] = {
00229 ASEBA_NATIVES_STD_FUNCTIONS,
00230 #ifdef LIS_GROUND_SENSORS
00231 EpuckNative_get_ground_values,
00232 #endif
00233 };
00234
00235 void AsebaPutVmToSleep(AsebaVMState *vm)
00236 {
00237 }
00238
00239 void AsebaNativeFunction(AsebaVMState *vm, uint16 id)
00240 {
00241 nativeFunctions[id](vm);
00242 }
00243
00244 const AsebaNativeFunctionDescription * const * AsebaGetNativeFunctionsDescriptions(AsebaVMState *vm)
00245 {
00246 return nativeFunctionsDescription;
00247 }
00248
00249 void uartSendUInt8(uint8 value)
00250 {
00251 e_send_uart1_char((char *)&value, 1);
00252 while (e_uart1_sending());
00253 }
00254
00255 void uartSendUInt16(uint16 value)
00256 {
00257 e_send_uart1_char((char *)&value, 2);
00258 while (e_uart1_sending());
00259 }
00260
00261 void AsebaSendBuffer(AsebaVMState *vm, const uint8* data, uint16 length)
00262 {
00263 uartSendUInt16(length - 2);
00264 uartSendUInt16(vmState.nodeId);
00265 uint16 i;
00266 for (i = 0; i < length; i++)
00267 uartSendUInt8(*data++);
00268 }
00269
00270 uint8 uartGetUInt8()
00271 {
00272 char c;
00273 while (!e_ischar_uart1());
00274 e_getchar_uart1(&c);
00275 return c;
00276 }
00277
00278 uint16 uartGetUInt16()
00279 {
00280 uint16 value;
00281
00282 value = uartGetUInt8();
00283 value |= (uartGetUInt8() << 8);
00284 return value;
00285 }
00286
00287 uint16 AsebaGetBuffer(AsebaVMState *vm, uint8* data, uint16 maxLength, uint16* source)
00288 {
00289 BODY_LED = 1;
00290 uint16 ret = 0;
00291 if (e_ischar_uart1())
00292 {
00293 uint16 len = uartGetUInt16() + 2;
00294 *source = uartGetUInt16();
00295
00296 uint16 i;
00297 for (i = 0; i < len; i++)
00298 *data++ = uartGetUInt8();
00299 ret = len;
00300 }
00301 BODY_LED = 0;
00302 return ret;
00303 }
00304
00305
00306 extern int e_ambient_and_reflected_ir[8];
00307 void updateRobotVariables()
00308 {
00309 unsigned i;
00310 static int camline = 640/2-4;
00311
00312 static int leftSpeed = 0, rightSpeed = 0;
00313
00314 if (ePuckVariables.leftSpeed != leftSpeed)
00315 {
00316 leftSpeed = CLAMP(ePuckVariables.leftSpeed, -1000, 1000);
00317 e_set_speed_left(leftSpeed);
00318 }
00319 if (ePuckVariables.rightSpeed != rightSpeed)
00320 {
00321 rightSpeed = CLAMP(ePuckVariables.rightSpeed, -1000, 1000);
00322 e_set_speed_right(rightSpeed);
00323 }
00324
00325
00326 if(e_ambient_and_reflected_ir[7] != 0xFFFF) {
00327 SET_EVENT(EVENT_IR_SENSORS);
00328
00329 for (i = 0; i < 8; i++)
00330 {
00331 e_set_led(i, ePuckVariables.leds[i] ? 1 : 0);
00332 ePuckVariables.ambiant[i] = e_get_ambient_light(i);
00333 ePuckVariables.prox[i] = e_get_calibrated_prox(i);
00334 }
00335 e_ambient_and_reflected_ir[7] = 0xFFFF;
00336 }
00337
00338 for(i = 0; i < 3; i++)
00339 ePuckVariables.acc[i] = e_get_acc(i);
00340
00341
00342 if(e_poxxxx_is_img_ready())
00343 {
00344 for(i = 0; i < 60; i++)
00345 {
00346 ePuckVariables.camR[i] = CAM_RED(cam_data[i]);
00347 ePuckVariables.camG[i] = CAM_GREEN(cam_data[i]);
00348 ePuckVariables.camB[i] = CAM_BLUE(cam_data[i]);
00349 }
00350 if(camline != ePuckVariables.camLine)
00351 {
00352 camline = ePuckVariables.camLine;
00353 e_poxxxx_config_cam(camline,0,4,480,4,8,RGB_565_MODE);
00354
00355
00356 e_poxxxx_set_mirror(1,1);
00357 e_poxxxx_write_cam_registers();
00358 }
00359 e_poxxxx_launch_capture((char *)cam_data);
00360 SET_EVENT(EVENT_CAMERA);
00361 }
00362 }
00363
00364
00365
00366 void AsebaAssert(AsebaVMState *vm, AsebaAssertReason reason)
00367 {
00368 e_set_body_led(1);
00369 while (1);
00370 }
00371
00372 void initRobot()
00373 {
00374
00375 e_init_port();
00376 e_start_agendas_processing();
00377 e_init_motors();
00378 e_init_uart1();
00379 e_init_ad_scan(0);
00380 e_poxxxx_init_cam();
00381 e_poxxxx_config_cam(640/2-4,0,4,480,4,8,RGB_565_MODE);
00382
00383
00384 e_poxxxx_set_mirror(1,1);
00385 e_poxxxx_write_cam_registers();
00386 e_poxxxx_launch_capture((char *)cam_data);
00387
00388
00389 if (RCONbits.POR)
00390 {
00391 RCONbits.POR = 0;
00392 RESET();
00393 }
00394 }
00395
00396
00397 void AsebaWriteBytecode(AsebaVMState *vm) {
00398 int i = 0;
00399 _prog_addressT EE_addr;
00400
00401 _init_prog_address(EE_addr, bytecode_version);
00402 _erase_eedata(EE_addr, 2);
00403 _wait_eedata();
00404
00405 i = ASEBA_PROTOCOL_VERSION;
00406 _write_eedata_word(EE_addr, i);
00407
00408 _wait_eedata();
00409
00410 _init_prog_address(EE_addr, eeprom_bytecode);
00411
00412 for(i = 0; i < 2048; i+=2) {
00413
00414 _erase_eedata(EE_addr, 2);
00415 _wait_eedata();
00416
00417 _write_eedata_word(EE_addr, vm->bytecode[i/2]);
00418 _wait_eedata();
00419
00420 EE_addr += 2;
00421 }
00422 }
00423 void AsebaResetIntoBootloader(AsebaVMState *vm) {
00424 asm __volatile__ ("reset");
00425 }
00426
00427 void initAseba()
00428 {
00429
00430 int selector = SELECTOR0 | (SELECTOR1 << 1) | (SELECTOR2 << 2);
00431 vmState.nodeId = selector + 1;
00432 AsebaVMInit(&vmState);
00433 ePuckVariables.id = selector + 1;
00434 ePuckVariables.camLine = 640/2-4;
00435 name[6] = '0' + selector;
00436 e_led_clear();
00437 e_set_led(selector,1);
00438 }
00439
00440 int main()
00441 {
00442 int i;
00443 _prog_addressT EE_addr;
00444
00445 initRobot();
00446
00447
00448 initAseba();
00449
00450
00451
00452
00453
00454
00455
00456 e_calibrate_ir();
00457 e_acc_calibr();
00458
00459
00460 _init_prog_address(EE_addr, bytecode_version);
00461 _memcpy_p2d16(&i, EE_addr, _EE_WORD);
00462
00463
00464 if(i == ASEBA_PROTOCOL_VERSION)
00465 {
00466 _init_prog_address(EE_addr, eeprom_bytecode);
00467
00468 for( i = 0; i< 2048; i += 2)
00469 {
00470 _memcpy_p2d16(vmState.bytecode + i/2 , EE_addr, 2);
00471 EE_addr += 2;
00472 }
00473
00474
00475 AsebaVMSetupEvent(&vmState, ASEBA_EVENT_INIT);
00476 }
00477
00478 while (1)
00479 {
00480 AsebaProcessIncomingEvents(&vmState);
00481 updateRobotVariables();
00482 AsebaVMRun(&vmState, 1000);
00483
00484 if (AsebaMaskIsClear(vmState.flags, ASEBA_VM_STEP_BY_STEP_MASK) || AsebaMaskIsClear(vmState.flags, ASEBA_VM_EVENT_ACTIVE_MASK))
00485 {
00486 unsigned i;
00487
00488 asm ("ff1r %[word], %[b]" : [b] "=r" (i) : [word] "r" (events_flags) : "cc");
00489 if(i)
00490 {
00491 i--;
00492 CLEAR_EVENT(i);
00493 ePuckVariables.source = vmState.nodeId;
00494 AsebaVMSetupEvent(&vmState, ASEBA_EVENT_LOCAL_EVENTS_START - i);
00495 }
00496 }
00497 }
00498
00499 return 0;
00500 }
00501