From eedbf4685e777480e5bfe578a61f167308fe951a Mon Sep 17 00:00:00 2001 From: skrillberg Date: Fri, 27 Apr 2018 16:51:13 -0700 Subject: [PATCH 1/5] Added mimsy2 bsp support and changed sconscript file to include a mimsy2-cc2538 build opti --- SConscript | 24 +- bsp/boards/mimsy2-cc2538/README.md | 7 + bsp/boards/mimsy2-cc2538/SConscript | 42 + bsp/boards/mimsy2-cc2538/accel_auto_cal.h | 38 + bsp/boards/mimsy2-cc2538/accel_mimsy.c | 454 ++ bsp/boards/mimsy2-cc2538/accel_mimsy.h | 17 + bsp/boards/mimsy2-cc2538/adc_sensor.c | 62 + bsp/boards/mimsy2-cc2538/adc_sensor.h | 23 + bsp/boards/mimsy2-cc2538/board.c | 315 ++ bsp/boards/mimsy2-cc2538/board_info.h | 117 + bsp/boards/mimsy2-cc2538/cc2538rf.h | 93 + bsp/boards/mimsy2-cc2538/cc2538sf23.lds | 62 + bsp/boards/mimsy2-cc2538/cc2538sf53.lds | 62 + bsp/boards/mimsy2-cc2538/compass_vec_cal.h | 35 + bsp/boards/mimsy2-cc2538/cryptoengine.c | 159 + bsp/boards/mimsy2-cc2538/data_builder.c | 1263 +++++ bsp/boards/mimsy2-cc2538/data_builder.h | 259 + bsp/boards/mimsy2-cc2538/debugpins.c | 135 + bsp/boards/mimsy2-cc2538/dmpKey.h | 494 ++ bsp/boards/mimsy2-cc2538/dmpmap.h | 264 + .../mimsy2-cc2538/eMPL-hal/eMPL_outputs.c | 322 ++ .../mimsy2-cc2538/eMPL-hal/eMPL_outputs.h | 44 + bsp/boards/mimsy2-cc2538/eMPL_outputs.c | 322 ++ bsp/boards/mimsy2-cc2538/eMPL_outputs.h | 44 + bsp/boards/mimsy2-cc2538/eui64.c | 40 + bsp/boards/mimsy2-cc2538/fast_no_motion.h | 46 + bsp/boards/mimsy2-cc2538/flash_mimsy.c | 95 + bsp/boards/mimsy2-cc2538/flash_mimsy.h | 64 + bsp/boards/mimsy2-cc2538/fusion_9axis.h | 38 + bsp/boards/mimsy2-cc2538/gyro_tc.h | 43 + bsp/boards/mimsy2-cc2538/hal_outputs.c | 486 ++ bsp/boards/mimsy2-cc2538/hal_outputs.h | 45 + .../headers/MPU9250_RegisterMap.h | 219 + bsp/boards/mimsy2-cc2538/headers/hw_aes.h | 4379 +++++++++++++++++ .../mimsy2-cc2538/headers/hw_ana_regs.h | 86 + bsp/boards/mimsy2-cc2538/headers/hw_cctest.h | 266 + .../mimsy2-cc2538/headers/hw_flash_ctrl.h | 449 ++ bsp/boards/mimsy2-cc2538/headers/hw_gpio.h | 1299 +++++ bsp/boards/mimsy2-cc2538/headers/hw_gptimer.h | 1031 ++++ bsp/boards/mimsy2-cc2538/headers/hw_i2cm.h | 357 ++ bsp/boards/mimsy2-cc2538/headers/hw_i2cs.h | 285 ++ bsp/boards/mimsy2-cc2538/headers/hw_ints.h | 153 + bsp/boards/mimsy2-cc2538/headers/hw_ioc.h | 1117 +++++ bsp/boards/mimsy2-cc2538/headers/hw_memmap.h | 85 + bsp/boards/mimsy2-cc2538/headers/hw_nvic.h | 1767 +++++++ bsp/boards/mimsy2-cc2538/headers/hw_pka.h | 792 +++ .../mimsy2-cc2538/headers/hw_rfcore_ffsm.h | 440 ++ .../mimsy2-cc2538/headers/hw_rfcore_sfr.h | 614 +++ .../mimsy2-cc2538/headers/hw_rfcore_xreg.h | 2434 +++++++++ .../mimsy2-cc2538/headers/hw_smwdthrosc.h | 264 + bsp/boards/mimsy2-cc2538/headers/hw_soc_adc.h | 267 + bsp/boards/mimsy2-cc2538/headers/hw_ssi.h | 491 ++ .../mimsy2-cc2538/headers/hw_sys_ctrl.h | 961 ++++ bsp/boards/mimsy2-cc2538/headers/hw_types.h | 84 + bsp/boards/mimsy2-cc2538/headers/hw_uart.h | 1361 +++++ bsp/boards/mimsy2-cc2538/headers/hw_udma.h | 744 +++ .../mimsy2-cc2538/headers/hw_udmachctl.h | 243 + bsp/boards/mimsy2-cc2538/headers/hw_usb.h | 802 +++ bsp/boards/mimsy2-cc2538/heading_from_gyro.h | 33 + bsp/boards/mimsy2-cc2538/i2c.c | 203 + bsp/boards/mimsy2-cc2538/i2c_mimsy.c | 155 + bsp/boards/mimsy2-cc2538/i2c_mimsy.h | 53 + bsp/boards/mimsy2-cc2538/inchworm.c | 308 ++ bsp/boards/mimsy2-cc2538/inchworm.h | 28 + bsp/boards/mimsy2-cc2538/include/log.h | 372 ++ bsp/boards/mimsy2-cc2538/include/mlinclude.h | 38 + bsp/boards/mimsy2-cc2538/include/mlmath.h | 95 + bsp/boards/mimsy2-cc2538/include/mlos.h | 103 + bsp/boards/mimsy2-cc2538/include/mltypes.h | 262 + bsp/boards/mimsy2-cc2538/include/mpu.h | 386 ++ .../mimsy2-cc2538/include/stdint_invensense.h | 44 + bsp/boards/mimsy2-cc2538/inv_math.h | 8 + bsp/boards/mimsy2-cc2538/inv_mpu.c | 3296 +++++++++++++ bsp/boards/mimsy2-cc2538/inv_mpu.h | 137 + .../mimsy2-cc2538/inv_mpu_dmp_motion_driver.c | 1390 ++++++ .../mimsy2-cc2538/inv_mpu_dmp_motion_driver.h | 97 + bsp/boards/mimsy2-cc2538/invensense.h | 28 + bsp/boards/mimsy2-cc2538/invensense_adv.h | 27 + bsp/boards/mimsy2-cc2538/led_mimsy.c | 61 + bsp/boards/mimsy2-cc2538/led_mimsy.h | 8 + bsp/boards/mimsy2-cc2538/leds.c | 213 + bsp/boards/mimsy2-cc2538/log.h | 372 ++ bsp/boards/mimsy2-cc2538/mag_disturb.h | 37 + bsp/boards/mimsy2-cc2538/math.h | 691 +++ bsp/boards/mimsy2-cc2538/message_layer.c | 59 + bsp/boards/mimsy2-cc2538/message_layer.h | 35 + bsp/boards/mimsy2-cc2538/ml_math_func.c | 781 +++ bsp/boards/mimsy2-cc2538/ml_math_func.h | 132 + bsp/boards/mimsy2-cc2538/mlinclude.h | 38 + .../mimsy2-cc2538/mllite/data_builder.c | 1263 +++++ .../mimsy2-cc2538/mllite/data_builder.h | 259 + bsp/boards/mimsy2-cc2538/mllite/hal_outputs.c | 486 ++ bsp/boards/mimsy2-cc2538/mllite/hal_outputs.h | 45 + bsp/boards/mimsy2-cc2538/mllite/invensense.h | 28 + .../mimsy2-cc2538/mllite/message_layer.c | 59 + .../mimsy2-cc2538/mllite/message_layer.h | 35 + .../mimsy2-cc2538/mllite/ml_math_func.c | 781 +++ .../mimsy2-cc2538/mllite/ml_math_func.h | 132 + bsp/boards/mimsy2-cc2538/mllite/mlmath.c | 68 + bsp/boards/mimsy2-cc2538/mllite/mpl.c | 72 + bsp/boards/mimsy2-cc2538/mllite/mpl.h | 24 + .../mimsy2-cc2538/mllite/results_holder.c | 522 ++ .../mimsy2-cc2538/mllite/results_holder.h | 81 + .../mimsy2-cc2538/mllite/start_manager.c | 105 + .../mimsy2-cc2538/mllite/start_manager.h | 27 + .../mimsy2-cc2538/mllite/storage_manager.c | 204 + .../mimsy2-cc2538/mllite/storage_manager.h | 32 + bsp/boards/mimsy2-cc2538/mlmath.c | 68 + bsp/boards/mimsy2-cc2538/mlmath.h | 95 + bsp/boards/mimsy2-cc2538/mlos.h | 103 + bsp/boards/mimsy2-cc2538/mltypes.h | 262 + bsp/boards/mimsy2-cc2538/motion_no_motion.h | 28 + bsp/boards/mimsy2-cc2538/mpl.c | 72 + bsp/boards/mimsy2-cc2538/mpl.h | 24 + bsp/boards/mimsy2-cc2538/mpl/accel_auto_cal.h | 38 + .../mimsy2-cc2538/mpl/compass_vec_cal.h | 35 + bsp/boards/mimsy2-cc2538/mpl/fast_no_motion.h | 46 + bsp/boards/mimsy2-cc2538/mpl/fusion_9axis.h | 38 + bsp/boards/mimsy2-cc2538/mpl/gyro_tc.h | 43 + .../mimsy2-cc2538/mpl/heading_from_gyro.h | 33 + bsp/boards/mimsy2-cc2538/mpl/inv_math.h | 8 + bsp/boards/mimsy2-cc2538/mpl/invensense_adv.h | 27 + bsp/boards/mimsy2-cc2538/mpl/mag_disturb.h | 37 + .../mimsy2-cc2538/mpl/motion_no_motion.h | 28 + bsp/boards/mimsy2-cc2538/mpl/no_gyro_fusion.h | 34 + .../mimsy2-cc2538/mpl/quaternion_supervisor.h | 27 + bsp/boards/mimsy2-cc2538/mpu.h | 386 ++ bsp/boards/mimsy2-cc2538/no_gyro_fusion.h | 34 + .../mimsy2-cc2538/quaternion_supervisor.h | 27 + bsp/boards/mimsy2-cc2538/radio.c | 531 ++ bsp/boards/mimsy2-cc2538/results_holder.c | 522 ++ bsp/boards/mimsy2-cc2538/results_holder.h | 81 + bsp/boards/mimsy2-cc2538/sctimer.c | 95 + bsp/boards/mimsy2-cc2538/sensors.c | 121 + bsp/boards/mimsy2-cc2538/servo.c | 133 + bsp/boards/mimsy2-cc2538/source/adc.c | 279 ++ bsp/boards/mimsy2-cc2538/source/adc.h | 150 + bsp/boards/mimsy2-cc2538/source/aes.c | 352 ++ bsp/boards/mimsy2-cc2538/source/aes.h | 172 + bsp/boards/mimsy2-cc2538/source/bl_commands.h | 421 ++ bsp/boards/mimsy2-cc2538/source/ccm.c | 640 +++ bsp/boards/mimsy2-cc2538/source/ccm.h | 97 + bsp/boards/mimsy2-cc2538/source/cpu.c | 554 +++ bsp/boards/mimsy2-cc2538/source/cpu.h | 79 + bsp/boards/mimsy2-cc2538/source/debug.c | 72 + bsp/boards/mimsy2-cc2538/source/debug.h | 70 + .../mimsy2-cc2538/source/ecc_curveinfo.h | 115 + bsp/boards/mimsy2-cc2538/source/flash.c | 475 ++ bsp/boards/mimsy2-cc2538/source/flash.h | 104 + bsp/boards/mimsy2-cc2538/source/gpio.c | 1377 ++++++ bsp/boards/mimsy2-cc2538/source/gpio.h | 169 + bsp/boards/mimsy2-cc2538/source/gptimer.c | 1128 +++++ bsp/boards/mimsy2-cc2538/source/gptimer.h | 193 + bsp/boards/mimsy2-cc2538/source/i2c_lib.c | 899 ++++ bsp/boards/mimsy2-cc2538/source/i2c_lib.h | 181 + bsp/boards/mimsy2-cc2538/source/interrupt.c | 829 ++++ bsp/boards/mimsy2-cc2538/source/interrupt.h | 99 + bsp/boards/mimsy2-cc2538/source/ioc.c | 865 ++++ bsp/boards/mimsy2-cc2538/source/ioc.h | 139 + bsp/boards/mimsy2-cc2538/source/pka.c | 1987 ++++++++ bsp/boards/mimsy2-cc2538/source/pka.h | 170 + bsp/boards/mimsy2-cc2538/source/rom.h | 117 + bsp/boards/mimsy2-cc2538/source/sha256.c | 465 ++ bsp/boards/mimsy2-cc2538/source/sha256.h | 96 + bsp/boards/mimsy2-cc2538/source/sleepmode.c | 303 ++ bsp/boards/mimsy2-cc2538/source/sleepmode.h | 101 + bsp/boards/mimsy2-cc2538/source/ssi.c | 774 +++ bsp/boards/mimsy2-cc2538/source/ssi.h | 137 + bsp/boards/mimsy2-cc2538/source/sys_ctrl.c | 996 ++++ bsp/boards/mimsy2-cc2538/source/sys_ctrl.h | 162 + bsp/boards/mimsy2-cc2538/source/systick.c | 273 + bsp/boards/mimsy2-cc2538/source/systick.h | 82 + bsp/boards/mimsy2-cc2538/source/uarthal.c | 1515 ++++++ bsp/boards/mimsy2-cc2538/source/uarthal.h | 219 + bsp/boards/mimsy2-cc2538/source/udma.c | 1250 +++++ bsp/boards/mimsy2-cc2538/source/udma.h | 658 +++ bsp/boards/mimsy2-cc2538/source/watchdog.c | 139 + bsp/boards/mimsy2-cc2538/source/watchdog.h | 84 + bsp/boards/mimsy2-cc2538/start_manager.c | 105 + bsp/boards/mimsy2-cc2538/start_manager.h | 27 + bsp/boards/mimsy2-cc2538/startup_gcc.c | 365 ++ bsp/boards/mimsy2-cc2538/startup_iar.c | 459 ++ bsp/boards/mimsy2-cc2538/stdint_invensense.h | 44 + bsp/boards/mimsy2-cc2538/storage_manager.c | 204 + bsp/boards/mimsy2-cc2538/storage_manager.h | 32 + bsp/boards/mimsy2-cc2538/uart.c | 162 + bsp/boards/mimsy2-cc2538/uart_mimsy.c | 91 + bsp/boards/mimsy2-cc2538/uart_mimsy.h | 2 + bsp/boards/mimsy2-cc2538/uartstdio.c | 1812 +++++++ bsp/boards/mimsy2-cc2538/uartstdio.h | 104 + 190 files changed, 65582 insertions(+), 5 deletions(-) create mode 100644 bsp/boards/mimsy2-cc2538/README.md create mode 100644 bsp/boards/mimsy2-cc2538/SConscript create mode 100644 bsp/boards/mimsy2-cc2538/accel_auto_cal.h create mode 100644 bsp/boards/mimsy2-cc2538/accel_mimsy.c create mode 100644 bsp/boards/mimsy2-cc2538/accel_mimsy.h create mode 100644 bsp/boards/mimsy2-cc2538/adc_sensor.c create mode 100644 bsp/boards/mimsy2-cc2538/adc_sensor.h create mode 100644 bsp/boards/mimsy2-cc2538/board.c create mode 100644 bsp/boards/mimsy2-cc2538/board_info.h create mode 100644 bsp/boards/mimsy2-cc2538/cc2538rf.h create mode 100644 bsp/boards/mimsy2-cc2538/cc2538sf23.lds create mode 100644 bsp/boards/mimsy2-cc2538/cc2538sf53.lds create mode 100644 bsp/boards/mimsy2-cc2538/compass_vec_cal.h create mode 100644 bsp/boards/mimsy2-cc2538/cryptoengine.c create mode 100644 bsp/boards/mimsy2-cc2538/data_builder.c create mode 100644 bsp/boards/mimsy2-cc2538/data_builder.h create mode 100644 bsp/boards/mimsy2-cc2538/debugpins.c create mode 100644 bsp/boards/mimsy2-cc2538/dmpKey.h create mode 100644 bsp/boards/mimsy2-cc2538/dmpmap.h create mode 100644 bsp/boards/mimsy2-cc2538/eMPL-hal/eMPL_outputs.c create mode 100644 bsp/boards/mimsy2-cc2538/eMPL-hal/eMPL_outputs.h create mode 100644 bsp/boards/mimsy2-cc2538/eMPL_outputs.c create mode 100644 bsp/boards/mimsy2-cc2538/eMPL_outputs.h create mode 100644 bsp/boards/mimsy2-cc2538/eui64.c create mode 100644 bsp/boards/mimsy2-cc2538/fast_no_motion.h create mode 100644 bsp/boards/mimsy2-cc2538/flash_mimsy.c create mode 100644 bsp/boards/mimsy2-cc2538/flash_mimsy.h create mode 100644 bsp/boards/mimsy2-cc2538/fusion_9axis.h create mode 100644 bsp/boards/mimsy2-cc2538/gyro_tc.h create mode 100644 bsp/boards/mimsy2-cc2538/hal_outputs.c create mode 100644 bsp/boards/mimsy2-cc2538/hal_outputs.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/MPU9250_RegisterMap.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_aes.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_ana_regs.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_cctest.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_flash_ctrl.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_gpio.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_gptimer.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_i2cm.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_i2cs.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_ints.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_ioc.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_memmap.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_nvic.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_pka.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_rfcore_ffsm.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_rfcore_sfr.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_rfcore_xreg.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_smwdthrosc.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_soc_adc.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_ssi.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_sys_ctrl.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_types.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_uart.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_udma.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_udmachctl.h create mode 100644 bsp/boards/mimsy2-cc2538/headers/hw_usb.h create mode 100644 bsp/boards/mimsy2-cc2538/heading_from_gyro.h create mode 100644 bsp/boards/mimsy2-cc2538/i2c.c create mode 100644 bsp/boards/mimsy2-cc2538/i2c_mimsy.c create mode 100644 bsp/boards/mimsy2-cc2538/i2c_mimsy.h create mode 100644 bsp/boards/mimsy2-cc2538/inchworm.c create mode 100644 bsp/boards/mimsy2-cc2538/inchworm.h create mode 100644 bsp/boards/mimsy2-cc2538/include/log.h create mode 100644 bsp/boards/mimsy2-cc2538/include/mlinclude.h create mode 100644 bsp/boards/mimsy2-cc2538/include/mlmath.h create mode 100644 bsp/boards/mimsy2-cc2538/include/mlos.h create mode 100644 bsp/boards/mimsy2-cc2538/include/mltypes.h create mode 100644 bsp/boards/mimsy2-cc2538/include/mpu.h create mode 100644 bsp/boards/mimsy2-cc2538/include/stdint_invensense.h create mode 100644 bsp/boards/mimsy2-cc2538/inv_math.h create mode 100644 bsp/boards/mimsy2-cc2538/inv_mpu.c create mode 100644 bsp/boards/mimsy2-cc2538/inv_mpu.h create mode 100644 bsp/boards/mimsy2-cc2538/inv_mpu_dmp_motion_driver.c create mode 100644 bsp/boards/mimsy2-cc2538/inv_mpu_dmp_motion_driver.h create mode 100644 bsp/boards/mimsy2-cc2538/invensense.h create mode 100644 bsp/boards/mimsy2-cc2538/invensense_adv.h create mode 100644 bsp/boards/mimsy2-cc2538/led_mimsy.c create mode 100644 bsp/boards/mimsy2-cc2538/led_mimsy.h create mode 100644 bsp/boards/mimsy2-cc2538/leds.c create mode 100644 bsp/boards/mimsy2-cc2538/log.h create mode 100644 bsp/boards/mimsy2-cc2538/mag_disturb.h create mode 100644 bsp/boards/mimsy2-cc2538/math.h create mode 100644 bsp/boards/mimsy2-cc2538/message_layer.c create mode 100644 bsp/boards/mimsy2-cc2538/message_layer.h create mode 100644 bsp/boards/mimsy2-cc2538/ml_math_func.c create mode 100644 bsp/boards/mimsy2-cc2538/ml_math_func.h create mode 100644 bsp/boards/mimsy2-cc2538/mlinclude.h create mode 100644 bsp/boards/mimsy2-cc2538/mllite/data_builder.c create mode 100644 bsp/boards/mimsy2-cc2538/mllite/data_builder.h create mode 100644 bsp/boards/mimsy2-cc2538/mllite/hal_outputs.c create mode 100644 bsp/boards/mimsy2-cc2538/mllite/hal_outputs.h create mode 100644 bsp/boards/mimsy2-cc2538/mllite/invensense.h create mode 100644 bsp/boards/mimsy2-cc2538/mllite/message_layer.c create mode 100644 bsp/boards/mimsy2-cc2538/mllite/message_layer.h create mode 100644 bsp/boards/mimsy2-cc2538/mllite/ml_math_func.c create mode 100644 bsp/boards/mimsy2-cc2538/mllite/ml_math_func.h create mode 100644 bsp/boards/mimsy2-cc2538/mllite/mlmath.c create mode 100644 bsp/boards/mimsy2-cc2538/mllite/mpl.c create mode 100644 bsp/boards/mimsy2-cc2538/mllite/mpl.h create mode 100644 bsp/boards/mimsy2-cc2538/mllite/results_holder.c create mode 100644 bsp/boards/mimsy2-cc2538/mllite/results_holder.h create mode 100644 bsp/boards/mimsy2-cc2538/mllite/start_manager.c create mode 100644 bsp/boards/mimsy2-cc2538/mllite/start_manager.h create mode 100644 bsp/boards/mimsy2-cc2538/mllite/storage_manager.c create mode 100644 bsp/boards/mimsy2-cc2538/mllite/storage_manager.h create mode 100644 bsp/boards/mimsy2-cc2538/mlmath.c create mode 100644 bsp/boards/mimsy2-cc2538/mlmath.h create mode 100644 bsp/boards/mimsy2-cc2538/mlos.h create mode 100644 bsp/boards/mimsy2-cc2538/mltypes.h create mode 100644 bsp/boards/mimsy2-cc2538/motion_no_motion.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl.c create mode 100644 bsp/boards/mimsy2-cc2538/mpl.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/accel_auto_cal.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/compass_vec_cal.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/fast_no_motion.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/fusion_9axis.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/gyro_tc.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/heading_from_gyro.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/inv_math.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/invensense_adv.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/mag_disturb.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/motion_no_motion.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/no_gyro_fusion.h create mode 100644 bsp/boards/mimsy2-cc2538/mpl/quaternion_supervisor.h create mode 100644 bsp/boards/mimsy2-cc2538/mpu.h create mode 100644 bsp/boards/mimsy2-cc2538/no_gyro_fusion.h create mode 100644 bsp/boards/mimsy2-cc2538/quaternion_supervisor.h create mode 100644 bsp/boards/mimsy2-cc2538/radio.c create mode 100644 bsp/boards/mimsy2-cc2538/results_holder.c create mode 100644 bsp/boards/mimsy2-cc2538/results_holder.h create mode 100644 bsp/boards/mimsy2-cc2538/sctimer.c create mode 100644 bsp/boards/mimsy2-cc2538/sensors.c create mode 100644 bsp/boards/mimsy2-cc2538/servo.c create mode 100644 bsp/boards/mimsy2-cc2538/source/adc.c create mode 100644 bsp/boards/mimsy2-cc2538/source/adc.h create mode 100644 bsp/boards/mimsy2-cc2538/source/aes.c create mode 100644 bsp/boards/mimsy2-cc2538/source/aes.h create mode 100644 bsp/boards/mimsy2-cc2538/source/bl_commands.h create mode 100644 bsp/boards/mimsy2-cc2538/source/ccm.c create mode 100644 bsp/boards/mimsy2-cc2538/source/ccm.h create mode 100644 bsp/boards/mimsy2-cc2538/source/cpu.c create mode 100644 bsp/boards/mimsy2-cc2538/source/cpu.h create mode 100644 bsp/boards/mimsy2-cc2538/source/debug.c create mode 100644 bsp/boards/mimsy2-cc2538/source/debug.h create mode 100644 bsp/boards/mimsy2-cc2538/source/ecc_curveinfo.h create mode 100644 bsp/boards/mimsy2-cc2538/source/flash.c create mode 100644 bsp/boards/mimsy2-cc2538/source/flash.h create mode 100644 bsp/boards/mimsy2-cc2538/source/gpio.c create mode 100644 bsp/boards/mimsy2-cc2538/source/gpio.h create mode 100644 bsp/boards/mimsy2-cc2538/source/gptimer.c create mode 100644 bsp/boards/mimsy2-cc2538/source/gptimer.h create mode 100644 bsp/boards/mimsy2-cc2538/source/i2c_lib.c create mode 100644 bsp/boards/mimsy2-cc2538/source/i2c_lib.h create mode 100644 bsp/boards/mimsy2-cc2538/source/interrupt.c create mode 100644 bsp/boards/mimsy2-cc2538/source/interrupt.h create mode 100644 bsp/boards/mimsy2-cc2538/source/ioc.c create mode 100644 bsp/boards/mimsy2-cc2538/source/ioc.h create mode 100644 bsp/boards/mimsy2-cc2538/source/pka.c create mode 100644 bsp/boards/mimsy2-cc2538/source/pka.h create mode 100644 bsp/boards/mimsy2-cc2538/source/rom.h create mode 100644 bsp/boards/mimsy2-cc2538/source/sha256.c create mode 100644 bsp/boards/mimsy2-cc2538/source/sha256.h create mode 100644 bsp/boards/mimsy2-cc2538/source/sleepmode.c create mode 100644 bsp/boards/mimsy2-cc2538/source/sleepmode.h create mode 100644 bsp/boards/mimsy2-cc2538/source/ssi.c create mode 100644 bsp/boards/mimsy2-cc2538/source/ssi.h create mode 100644 bsp/boards/mimsy2-cc2538/source/sys_ctrl.c create mode 100644 bsp/boards/mimsy2-cc2538/source/sys_ctrl.h create mode 100644 bsp/boards/mimsy2-cc2538/source/systick.c create mode 100644 bsp/boards/mimsy2-cc2538/source/systick.h create mode 100644 bsp/boards/mimsy2-cc2538/source/uarthal.c create mode 100644 bsp/boards/mimsy2-cc2538/source/uarthal.h create mode 100644 bsp/boards/mimsy2-cc2538/source/udma.c create mode 100644 bsp/boards/mimsy2-cc2538/source/udma.h create mode 100644 bsp/boards/mimsy2-cc2538/source/watchdog.c create mode 100644 bsp/boards/mimsy2-cc2538/source/watchdog.h create mode 100644 bsp/boards/mimsy2-cc2538/start_manager.c create mode 100644 bsp/boards/mimsy2-cc2538/start_manager.h create mode 100644 bsp/boards/mimsy2-cc2538/startup_gcc.c create mode 100644 bsp/boards/mimsy2-cc2538/startup_iar.c create mode 100644 bsp/boards/mimsy2-cc2538/stdint_invensense.h create mode 100644 bsp/boards/mimsy2-cc2538/storage_manager.c create mode 100644 bsp/boards/mimsy2-cc2538/storage_manager.h create mode 100644 bsp/boards/mimsy2-cc2538/uart.c create mode 100644 bsp/boards/mimsy2-cc2538/uart_mimsy.c create mode 100644 bsp/boards/mimsy2-cc2538/uart_mimsy.h create mode 100644 bsp/boards/mimsy2-cc2538/uartstdio.c create mode 100644 bsp/boards/mimsy2-cc2538/uartstdio.h diff --git a/SConscript b/SConscript index b209b17163..ca7f2d286c 100644 --- a/SConscript +++ b/SConscript @@ -165,7 +165,7 @@ elif env['toolchain']=='iar': elif env['toolchain']=='iar-proj': - if env['board'] not in ['telosb','gina','wsn430v13b','wsn430v14','z1','openmotestm','agilefox','openmote-cc2538','openmote-b','iot-lab_M3']: + if env['board'] not in ['telosb','gina','wsn430v13b','wsn430v14','z1','openmotestm','agilefox','openmote-cc2538','mimsy2-cc2538','openmote-b','iot-lab_M3']: raise SystemError('toolchain {0} can not be used for board {1}'.format(env['toolchain'],env['board'])) env['IAR_EW430_INSTALLDIR'] = os.environ['IAR_EW430_INSTALLDIR'] @@ -195,10 +195,10 @@ elif env['toolchain']=='iar-proj': elif env['toolchain']=='armgcc': - if env['board'] not in ['silabs-ezr32wg','openmote-cc2538','openmote-b','iot-lab_M3','iot-lab_A8-M3','openmotestm', 'samr21_xpro']: + if env['board'] not in ['silabs-ezr32wg','openmote-cc2538','mimsy2-cc2538','openmote-b','iot-lab_M3','iot-lab_A8-M3','openmotestm', 'samr21_xpro']: raise SystemError('toolchain {0} can not be used for board {1}'.format(env['toolchain'],env['board'])) - if env['board'] in ['openmote-cc2538','openmote-b']: + if env['board'] in ['openmote-cc2538','openmote-b','mimsy2-cc2538']: if env['revision'] == "A1": linker_file = 'cc2538sf23.lds' print "*** OPENMOTE CC2538 REV. A1 ***\n" @@ -216,6 +216,8 @@ elif env['toolchain']=='armgcc': env.Append(CCFLAGS = '-mthumb') env.Append(CCFLAGS = '-g3') env.Append(CCFLAGS = '-Wstrict-prototypes') + #if env['board'] == "mimsy2-cc2538": + # env.Append(CCFLAGS = '-lm') #added to hopefully prevent a linker overlap between .ARM.exidx and .data if env['revision'] == "A1": env.Append(CCFLAGS = '-DREVA1=1') @@ -228,10 +230,18 @@ elif env['toolchain']=='armgcc': # linker env.Append(LINKFLAGS = '-Tbsp/boards/'+env['board']+'/' + linker_file) env.Append(LINKFLAGS = '-nostartfiles') + #if env['board'] == "mimsy2-cc2538": + #env.Replace(LIBLINKPREFIX = 'lib') + #env.Replace(LIBLINKSUFFIX = '.a') + #env.Replace(LIBS = 'm') + #env.Append(LIBLINKSUFFIXES='.a') + #env.Append(LIBPATH='#C:\Program Files (x86)\GNU Tools ARM Embedded\5.4 2016q3\arm-none-eabi\lib\armv7-m') env.Append(LINKFLAGS = '-Wl,-Map,${TARGET.base}.map') env.Append(LINKFLAGS = '-mcpu=cortex-m3') env.Append(LINKFLAGS = '-mthumb') env.Append(LINKFLAGS = '-g3') + + if env['revision'] == "A1": env.Append(LINKFLAGS = '-DREVA1=1') @@ -732,7 +742,7 @@ def BootloadFunc(): suffix = '.phonyupload', src_suffix = '.ihex', ) - elif env['board'] in ['openmote-cc2538','openmote-b'] : + elif env['board'] in ['openmote-cc2538','openmote-b','mimsy2-cc2538'] : return Builder( action = OpenMoteCC2538_bootload, suffix = '.phonyupload', @@ -777,7 +787,7 @@ def buildLibs(projectDir): '00std': [ ], '01bsp': [ 'libbsp'], '02drv': [ 'libkernel','libdrivers','libbsp'], - '03oos': ['libopenstack','libopenapps','libopenstack','libkernel','libdrivers','libbsp'], # this order needed for mspgcc + '03oos': ['libm','libopenstack','libopenapps','libopenstack','libkernel','libdrivers','libbsp'], # this order needed for mspgcc } returnVal = None @@ -864,6 +874,7 @@ def project_finder(localEnv): source = source, LIBS = libs, ) + targetAction = localEnv.PostBuildExtras(exe) Alias(targetName, [targetAction]) @@ -1052,3 +1063,6 @@ buildEnv.SConscript( exports = {'env': buildEnv}, variant_dir = projectsVarDir, ) + +buildEnv.Append(LIBPATH = '#C:\Program Files (x86)\GNU Tools ARM Embedded\5.4 2016q3\arm-none-eabi\lib\armv7-m') +buildEnv.Append(LIBS = "libm") \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/README.md b/bsp/boards/mimsy2-cc2538/README.md new file mode 100644 index 0000000000..4a652188d2 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/README.md @@ -0,0 +1,7 @@ +The OpenWSN BSP (Board Support Package) for the CC2538 platform is based on the +CC2538 Foundation Firmware provided by Texas Instruments (available at: +http://www.ti.com/tool/cc2538-sw). The current version of the CC2538 Foundation +Firmware is Rev. A which dates from May 6, 2013. Information regarding the +CC2538 Foundation Firmware can be found in the CC2538 Peripheral Driver Library +User's Guide (available at: http://www.ti.com/lit/pdf/swru325) which also +dates from May 6, 2013. diff --git a/bsp/boards/mimsy2-cc2538/SConscript b/bsp/boards/mimsy2-cc2538/SConscript new file mode 100644 index 0000000000..64f3e095db --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/SConscript @@ -0,0 +1,42 @@ +import os + +Import('env') + +localEnv = env.Clone() + +adxl346 = localEnv.SConscript( + os.path.join('#','bsp','chips','adxl346','SConscript'), + variant_dir = 'adxl346', + exports = {'env': env}, +) + +max44009 = localEnv.SConscript( + os.path.join('#','bsp','chips','max44009','SConscript'), + variant_dir = 'max44009', + exports = {'env': env}, +) + +sht21 = localEnv.SConscript( + os.path.join('#','bsp','chips','sht21','SConscript'), + variant_dir = 'sht21', + exports = {'env': env}, +) + +source = \ + [file for file in Glob('*.c') if file.name.find('iar')==-1] + \ + Glob('source/*.c') + +localEnv.Append( + CPPPATH = [ + os.path.join('#','bsp','boards','mimsy2-cc2538'), + os.path.join('#','bsp','boards','mimsy2-cc2538','headers'), + os.path.join('#','bsp','boards','mimsy2-cc2538','source'), + os.path.join('#','bsp','chips','adxl346'), + os.path.join('#','bsp','chips','max44009'), + os.path.join('#','bsp','chips','sht21'), + ], +) + +board = localEnv.Object(source=source) + adxl346 + max44009 + sht21 + +Return('board') diff --git a/bsp/boards/mimsy2-cc2538/accel_auto_cal.h b/bsp/boards/mimsy2-cc2538/accel_auto_cal.h new file mode 100644 index 0000000000..cb69d65726 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/accel_auto_cal.h @@ -0,0 +1,38 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/******************************************************************************* + * + * $Id$ + * + ******************************************************************************/ + +#ifndef MLDMP_ACCEL_AUTO_CALIBRATION_H__ +#define MLDMP_ACCEL_AUTO_CALIBRATION_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_in_use_auto_calibration(void); +inv_error_t inv_disable_in_use_auto_calibration(void); +inv_error_t inv_stop_in_use_auto_calibration(void); +inv_error_t inv_start_in_use_auto_calibration(void); +inv_error_t inv_in_use_auto_calibration_is_enabled(unsigned char *is_enabled); +inv_error_t inv_init_in_use_auto_calibration(void); +void inv_init_accel_maxmin(void); +void inv_record_good_accel_maxmin(void); +int inv_get_accel_bias_stage(void); + +#ifdef __cplusplus +} +#endif + +#endif // MLDMP_ACCEL_AUTO_CALIBRATION_H__ + diff --git a/bsp/boards/mimsy2-cc2538/accel_mimsy.c b/bsp/boards/mimsy2-cc2538/accel_mimsy.c new file mode 100644 index 0000000000..5b660a1a97 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/accel_mimsy.c @@ -0,0 +1,454 @@ +#include "i2c_mimsy.h" +#include "i2c.h" +#include "MPU9250_RegisterMap.h" +#include "flash_mimsy.h" //TODO: mive imu_data type to a new mimsy.h file +#include "gptimer.h" +#include "hw_gptimer.h" +#include "hw_memmap.h" + +//invensense related includes + +#include "inv_mpu.h" +#include "inv_mpu_dmp_motion_driver.h" +//#include "invensense.h" +#include "invensense_adv.h" +#include "eMPL_outputs.h" +#include "mltypes.h" +#include "mpu.h" +#include "log.h" +//#include "ml_math_func.h" +#include + +//defines + +#define DEFAULT_MPU_HZ (20) +#define IMU_ADDRESS 0x69 +union IMURaw { + + uint16_t words[7]; + uint8_t bytes[14]; + + +}; + +//invensense related structures################################################ + +struct platform_data_s { + const signed char orientation[9]; +}; + +//orientation for upright rocket + +static struct platform_data_s gyro_pdata = { + .orientation = { 0, 0, -1, + -1, 0, 0, + 0, 1, 0} +}; + + +//orientation for flat rocket +/*static struct platform_data_s gyro_pdata = { + .orientation = { 1, 0, 0, + 0, -1, 0, + 0, 0, -1} +};*/ + + +struct rx_s { + unsigned char header[3]; + unsigned char cmd; +}; +struct hal_s { + unsigned char lp_accel_mode; + unsigned char sensors; + unsigned char dmp_on; + unsigned char wait_for_tap; + volatile unsigned char new_gyro; + unsigned char motion_int_mode; + unsigned long no_dmp_hz; + unsigned long next_pedo_ms; + unsigned long next_temp_ms; + unsigned long next_compass_ms; + unsigned int report; + unsigned short dmp_features; + struct rx_s rx; +}; +static struct hal_s hal = {0}; +static long alt_inv_q29_mult(long a, long b); +static long alt_inv_q30_mult(long a, long b); +static void alt_inv_q_mult(const long *q1, const long *q2, long *qProd); +void alt_inv_q_invert(const long *q, long *qInverted); + +//unsigned short alt_inv_orientation_matrix_to_scalar(const signed char *mtx); + + +//functions #################################################################### +//TODO: add an imu init function +//mimsy init function; inits board timers, resets imu, wakes imu, sets clock source +//enables sensors + +//phony callback function for dmp +static void tap_cb(unsigned char direction, unsigned char count) +{ + + return; +} + +//phony callback function for dmp +static void android_orient_cb(unsigned char orientation) +{ + switch (orientation) { + + default: + return; + } +} + + + + +void mimsyIMUInit(void){ + //board_timer_init(); + uint8_t readbyte; + + + // i2c_init(); + uint8_t address; + address=0x69; + + i2c_write_byte(address,MPU9250_PWR_MGMT_1); //reset + i2c_write_byte(address,0x80); + + i2c_write_byte(address,MPU9250_PWR_MGMT_1); //wake + i2c_write_byte(address,0x00); + + uint8_t bytes[2]={MPU9250_PWR_MGMT_1,0x01} ; + i2c_write_bytes(address,bytes,2); //set gyro clock source + + + bytes[0]=0x6C; + bytes[1]=0x03; + uint8_t *byteptr=&readbyte; + + i2c_write_byte(address,MPU9250_PWR_MGMT_2); + i2c_read_byte(address,byteptr); + + i2c_write_byte(address,MPU9250_PWR_MGMT_2); //sens enable + i2c_write_byte(address,0x00); + + i2c_write_byte(address,MPU9250_PWR_MGMT_2); + i2c_read_byte(address,byteptr); + + +} + +void mimsySetAccelFsr(int fsr){ + mpu_set_accel_fsr(fsr); +} + +void mimsySetGyroFsr(int fsr){ + mpu_set_gyro_fsr(fsr); +} + +//gyro reads based on invensense drivers +void mimsyIMURead6DofInv(IMUData *data){ + +} +//TODO: start adding invensense driver-based functions + +//reads IMU data from Mimsy's MPU9250 +void mimsyIMURead6Dof( IMUData *data){ + uint8_t address=IMU_ADDRESS; + uint8_t readbyte; + uint8_t *byteptr=&readbyte; + + //Accel X + i2c_read_register(address,MPU9250_ACCEL_XOUT_H,byteptr); + (*data).fields.accelX=((uint16_t) readbyte)<<8; + + i2c_read_register(address,MPU9250_ACCEL_XOUT_L,byteptr); + (*data).fields.accelX=((uint16_t) readbyte)| (*data).fields.accelX; + + //Accel Y + i2c_read_register(address,MPU9250_ACCEL_YOUT_H,byteptr); + (*data).fields.accelY=((uint16_t) readbyte)<<8; + + i2c_read_register(address,MPU9250_ACCEL_YOUT_L,byteptr); + (*data).fields.accelY=((uint16_t) readbyte)| (*data).fields.accelY; + + //Accel Z + i2c_read_register(address,MPU9250_ACCEL_ZOUT_H,byteptr); + (*data).fields.accelZ=((uint16_t) readbyte)<<8; + + i2c_read_register(address,MPU9250_ACCEL_ZOUT_L,byteptr); + (*data).fields.accelZ=((uint16_t) readbyte)| (*data).fields.accelZ; + + //Gyro X + i2c_read_register(address,MPU9250_GYRO_XOUT_H,byteptr); + (*data).fields.gyroX=((uint16_t) readbyte)<<8; + + i2c_read_register(address,MPU9250_GYRO_XOUT_L,byteptr); + (*data).fields.gyroX=((uint16_t) readbyte)| (*data).fields.gyroX; + + //Gyro Y + i2c_read_register(address,MPU9250_GYRO_YOUT_H,byteptr); + (*data).fields.gyroY=((uint16_t) readbyte)<<8; + + i2c_read_register(address,MPU9250_GYRO_YOUT_L,byteptr); + (*data).fields.gyroY=((uint16_t) readbyte)| (*data).fields.gyroY; + + //Gyro Z + i2c_read_register(address,MPU9250_GYRO_ZOUT_H,byteptr); + (*data).fields.gyroZ=((uint16_t) readbyte)<<8; + + i2c_read_register(address,MPU9250_GYRO_ZOUT_L,byteptr); + (*data).fields.gyroZ=((uint16_t) readbyte)| (*data).fields.gyroZ; + + + (*data).fields.timestamp= TimerValueGet(GPTIMER2_BASE, GPTIMER_A); +} + +static unsigned short alt_inv_row_2_scale(const signed char *row) +{ + unsigned short b; + + if (row[0] > 0) + b = 0; + else if (row[0] < 0) + b = 4; + else if (row[1] > 0) + b = 1; + else if (row[1] < 0) + b = 5; + else if (row[2] > 0) + b = 2; + else if (row[2] < 0) + b = 6; + else + b = 7; // error + return b; +} + +/** Converts an orientation matrix made up of 0,+1,and -1 to a scalar representation. +* @param[in] mtx Orientation matrix to convert to a scalar. +* @return Description of orientation matrix. The lowest 2 bits (0 and 1) represent the column the one is on for the +* first row, with the bit number 2 being the sign. The next 2 bits (3 and 4) represent +* the column the one is on for the second row with bit number 5 being the sign. +* The next 2 bits (6 and 7) represent the column the one is on for the third row with +* bit number 8 being the sign. In binary the identity matrix would therefor be: +* 010_001_000 or 0x88 in hex. +*/ +unsigned short alt_inv_orientation_matrix_to_scalar(const signed char *mtx) +{ + + unsigned short scalar; + + /* + XYZ 010_001_000 Identity Matrix + XZY 001_010_000 + YXZ 010_000_001 + YZX 000_010_001 + ZXY 001_000_010 + ZYX 000_001_010 + */ + + scalar = alt_inv_row_2_scale(mtx); + scalar |= alt_inv_row_2_scale(mtx + 3) << 3; + scalar |= alt_inv_row_2_scale(mtx + 6) << 6; + + + return scalar; +} + +void mimsyDmpBegin(){ + dmp_load_motion_driver_firmware(); + dmp_set_orientation( + alt_inv_orientation_matrix_to_scalar(gyro_pdata.orientation)); + dmp_register_tap_cb(tap_cb); + dmp_register_android_orient_cb(android_orient_cb); + + hal.dmp_features = DMP_FEATURE_6X_LP_QUAT + | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_GYRO_CAL |DMP_FEATURE_SEND_CAL_GYRO; + dmp_enable_feature(hal.dmp_features); + dmp_set_fifo_rate(100); + //dmp_enable_6x_lp_quat(1); + mpu_set_dmp_state(1); + hal.dmp_on = 1; +} + +/** Performs a multiply and shift by 29. These are good functions to write in assembly on + * with devices with small memory where you want to get rid of the long long which some + * assemblers don't handle well + * @param[in] a + * @param[in] b + * @return ((long long)a*b)>>29 +*/ +static long alt_inv_q29_mult(long a, long b) +{ +#ifdef EMPL_NO_64BIT + long result; + result = (long)((float)a * b / (1L << 29)); + return result; +#else + long long temp; + long result; + temp = (long long)a * b; + result = (long)(temp >> 29); + return result; +#endif +} + +/** Performs a multiply and shift by 30. These are good functions to write in assembly on + * with devices with small memory where you want to get rid of the long long which some + * assemblers don't handle well + * @param[in] a + * @param[in] b + * @return ((long long)a*b)>>30 +*/ +static long alt_inv_q30_mult(long a, long b) +{ +#ifdef EMPL_NO_64BIT + long result; + result = (long)((float)a * b / (1L << 30)); + return result; +#else + long long temp; + long result; + temp = (long long)a * b; + result = (long)(temp >> 30); + return result; +#endif +} + +/** Performs a fixed point quaternion multiply. +* @param[in] q1 First Quaternion Multicand, length 4. 1.0 scaled +* to 2^30 +* @param[in] q2 Second Quaternion Multicand, length 4. 1.0 scaled +* to 2^30 +* @param[out] qProd Product after quaternion multiply. Length 4. +* 1.0 scaled to 2^30. +*/ +static void alt_inv_q_mult(const long *q1, const long *q2, long *qProd) +{ + //INVENSENSE_FUNC_START; + qProd[0] = alt_inv_q30_mult(q1[0], q2[0]) - alt_inv_q30_mult(q1[1], q2[1]) - + alt_inv_q30_mult(q1[2], q2[2]) - alt_inv_q30_mult(q1[3], q2[3]); + + qProd[1] = alt_inv_q30_mult(q1[0], q2[1]) + alt_inv_q30_mult(q1[1], q2[0]) + + alt_inv_q30_mult(q1[2], q2[3]) - alt_inv_q30_mult(q1[3], q2[2]); + + qProd[2] = alt_inv_q30_mult(q1[0], q2[2]) - alt_inv_q30_mult(q1[1], q2[3]) + + alt_inv_q30_mult(q1[2], q2[0]) + alt_inv_q30_mult(q1[3], q2[1]); + + qProd[3] = alt_inv_q30_mult(q1[0], q2[3]) + alt_inv_q30_mult(q1[1], q2[2]) - + alt_inv_q30_mult(q1[2], q2[1]) + alt_inv_q30_mult(q1[3], q2[0]); +} + +/** Rotates a 3-element vector by Rotation defined by Q +*/ +void alt_inv_q_rotate(const long *q, const long *in, long *out) +{ + long q_temp1[4], q_temp2[4]; + long in4[4], out4[4]; + + // Fixme optimize + in4[0] = 0; + memcpy(&in4[1], in, 3 * sizeof(long)); + alt_inv_q_mult(q, in4, q_temp1); + alt_inv_q_invert(q, q_temp2); + alt_inv_q_mult(q_temp1, q_temp2, out4); + memcpy(out, &out4[1], 3 * sizeof(long)); +} + +void alt_inv_q_invert(const long *q, long *qInverted) +{ + //INVENSENSE_FUNC_START; + qInverted[0] = q[0]; + qInverted[1] = -q[1]; + qInverted[2] = -q[2]; + qInverted[3] = -q[3]; +} + +/** + * Converts a quaternion to a rotation matrix. + * @param[in] quat 4-element quaternion in fixed point. One is 2^30. + * @param[out] rot Rotation matrix in fixed point. One is 2^30. The + * First 3 elements of the rotation matrix, represent + * the first row of the matrix. Rotation matrix multiplied + * by a 3 element column vector transform a vector from Body + * to World. + */ +void alt_inv_quaternion_to_rotation(const long *quat, long *rot) +{ + rot[0] = + alt_inv_q29_mult(quat[1], quat[1]) + alt_inv_q29_mult(quat[0], + quat[0]) - + 1073741824L; + rot[1] = + alt_inv_q29_mult(quat[1], quat[2]) - alt_inv_q29_mult(quat[3], quat[0]); + rot[2] = + alt_inv_q29_mult(quat[1], quat[3]) + alt_inv_q29_mult(quat[2], quat[0]); + rot[3] = + alt_inv_q29_mult(quat[1], quat[2]) + alt_inv_q29_mult(quat[3], quat[0]); + rot[4] = + alt_inv_q29_mult(quat[2], quat[2]) + alt_inv_q29_mult(quat[0], + quat[0]) - + 1073741824L; + rot[5] = + alt_inv_q29_mult(quat[2], quat[3]) - alt_inv_q29_mult(quat[1], quat[0]); + rot[6] = + alt_inv_q29_mult(quat[1], quat[3]) - alt_inv_q29_mult(quat[2], quat[0]); + rot[7] = + alt_inv_q29_mult(quat[2], quat[3]) + alt_inv_q29_mult(quat[1], quat[0]); + rot[8] = + alt_inv_q29_mult(quat[3], quat[3]) + alt_inv_q29_mult(quat[0], + quat[0]) - + 1073741824L; +} + +void alt_mlMatrixVectorMult(long matrix[9], const long vecIn[3], long *vecOut) { + // matrix format + // [ 0 3 6; + // 1 4 7; + // 2 5 8] + + // vector format: [0 1 2]^T; + int i, j; + long temp; + + for (i=0; i<3; i++) { + temp = 0; + for (j=0; j<3; j++) { + temp += alt_inv_q30_mult(matrix[i+j*3], vecIn[j]); + } + vecOut[i] = temp; + } +} + +void alt_inv_q_normalizef(float *q) +{ + //INVENSENSE_FUNC_START; + float normSF = 0; + float xHalf = 0; + normSF = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + if (normSF < 2) { + xHalf = 0.5f * normSF; + normSF = normSF * (1.5f - xHalf * normSF * normSF); + normSF = normSF * (1.5f - xHalf * normSF * normSF); + normSF = normSF * (1.5f - xHalf * normSF * normSF); + normSF = normSF * (1.5f - xHalf * normSF * normSF); + q[0] *= normSF; + q[1] *= normSF; + q[2] *= normSF; + q[3] *= normSF; + } else { + q[0] = 1.0; + q[1] = 0.0; + q[2] = 0.0; + q[3] = 0.0; + } + normSF = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); +} + + + diff --git a/bsp/boards/mimsy2-cc2538/accel_mimsy.h b/bsp/boards/mimsy2-cc2538/accel_mimsy.h new file mode 100644 index 0000000000..c1264c66b7 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/accel_mimsy.h @@ -0,0 +1,17 @@ +#ifndef __XL_MIMSY_H__ +#define __XL_MIMSY_H__ + +#include "flash_mimsy.h" +extern void mimsyIMURead6Dof(IMUData *data); +unsigned short alt_inv_orientation_matrix_to_scalar(const signed char *mtx); +void alt_inv_q_rotate(const long *q, const long *in, long *out); +void alt_inv_quaternion_to_rotation(const long *quat, long *rot); +void alt_mlMatrixVectorMult(long matrix[9], const long vecIn[3], long *vecOut); +void alt_inv_q_normalizef(float *q); +void mimsyIMUInit(void); +void mimsyIMURead6DofInv(IMUData *data); +void mimsyDmpBegin(void); +void mimsySetAccelFsr(int fsr); +void mimsySetGyroFsr(int fsr); + +#endif diff --git a/bsp/boards/mimsy2-cc2538/adc_sensor.c b/bsp/boards/mimsy2-cc2538/adc_sensor.c new file mode 100644 index 0000000000..0f087bb4cf --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/adc_sensor.c @@ -0,0 +1,62 @@ +/** + \brief Definition of the OpenMote-CC2538 ADC temperature sensor driver. + \author Nicola Accettura , March 2015. +*/ + +#include +#include + +#include + +#include "adc_sensor.h" + +//=========================== defines ========================================= + +#define CONST 0.58134 //(VREF / 2047) = (1190 / 2047), VREF from Datasheet +#define OFFSET_DATASHEET_25C 827 // 1422*CONST, from Datasheet +#define TEMP_COEFF (CONST * 4.2) // From Datasheet +#define OFFSET_0C (OFFSET_DATASHEET_25C - (25 * TEMP_COEFF)) + +//=========================== variables ======================================= + +//=========================== prototype ======================================= + +//=========================== public ========================================== + +/** + \brief Initialize the sensor +*/ +void adc_sensor_init(void) { + HWREG(CCTEST_TR0) |= CCTEST_TR0_ADCTM; + HWREG(RFCORE_XREG_ATEST) = 0x01; + SOCADCSingleConfigure(SOCADC_12_BIT, SOCADC_REF_INTERNAL); + adc_sens_read_temperature(); +} + +/** + \brief Read rough data from sensor + \param[out] ui16Dummy rough data. +*/ +uint16_t adc_sens_read_temperature(void) { + uint16_t ui16Dummy; + + SOCADCSingleStart(SOCADC_TEMP_SENS); + while(!SOCADCEndOfCOnversionGet()); + ui16Dummy = SOCADCDataGet() >> SOCADC_12_BIT_RSHIFT; + return ui16Dummy; +} + +/** + \brief Convert rough data to human understandable + \param[in] cputemp rough data. + \param[out] the number of registered OpenSensors. +*/ +float adc_sens_convert_temperature(uint16_t cputemp) { + float dOutputVoltage; + + dOutputVoltage = cputemp * CONST; + dOutputVoltage = ((dOutputVoltage - OFFSET_0C) / TEMP_COEFF); + return dOutputVoltage; +} + +//=========================== private ========================================= diff --git a/bsp/boards/mimsy2-cc2538/adc_sensor.h b/bsp/boards/mimsy2-cc2538/adc_sensor.h new file mode 100644 index 0000000000..42b051c3db --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/adc_sensor.h @@ -0,0 +1,23 @@ +/** + \brief Declaration of the OpenMote-CC2538 ADC temperature sensor driver. + \author Nicola Accettura , March 2015. +*/ + +#ifndef __ADC_SENSOR_H__ +#define __ADC_SENSOR_H__ + +#include "board_info.h" + +//=========================== define ========================================== + +//=========================== typedef ========================================= + +//=========================== module variables ================================ + +//=========================== prototypes ====================================== + +void adc_sensor_init(void); +uint16_t adc_sens_read_temperature(void); +float adc_sens_convert_temperature(uint16_t cputemp); + +#endif // __ADC_SENSOR_H__ diff --git a/bsp/boards/mimsy2-cc2538/board.c b/bsp/boards/mimsy2-cc2538/board.c new file mode 100644 index 0000000000..7a15a8f46b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/board.c @@ -0,0 +1,315 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "board" bsp module. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include "debugpins.h" +#include "i2c.h" +#include "leds.h" +#include "radio.h" +#include "sensors.h" +#include "sctimer.h" +#include "uart.h" +#include "cryptoengine.h" +#include "uart_mimsy.h" + +//=========================== variables ======================================= + +#define BSP_BUTTON_BASE ( GPIO_C_BASE ) +#define BSP_BUTTON_USER ( GPIO_PIN_3 ) + +#ifdef REVA1 //Rev.A1 uses SF23 cc2538 which start at diffferent location + #define CC2538_FLASH_ADDRESS ( 0x0023F800 ) +#else + #define CC2538_FLASH_ADDRESS ( 0x0027F800 ) +#endif +//=========================== prototypes ====================================== + +void board_timer_init(void); +uint32_t board_timer_get(void); +bool board_timer_expired(uint32_t future); + +static void clock_init(void); +static void gpio_init(void); +static void button_init(void); + +static void SysCtrlDeepSleepSetting(void); +static void SysCtrlSleepSetting(void); +static void SysCtrlRunSetting(void); +static void SysCtrlWakeupSetting(void); + +static void GPIO_C_Handler(void); + +bool user_button_initialized; + +//=========================== main ============================================ + +extern int mote_main(void); + +int main(void) { + return mote_main(); +} + +//=========================== public ========================================== + +void board_init(void) { + user_button_initialized = FALSE; + + gpio_init(); + clock_init(); + //board_timer_init(); changed for inchwrom code + //leds_init(); changed for incworm code + //debugpins_init(); changed for inchworm code + //button_init(); + //sctimer_init(); changed for inchworm code + //uart_init(); changed for inchwrom code + //radio_init(); changed for incwhorm code + //i2c_init(); changed for inchworm code + // sensors_init(); + // cryptoengine_init(); +} + +/** + * Puts the board to sleep + */ +void board_sleep(void) { + SysCtrlPowerModeSet(SYS_CTRL_PM_NOACTION); + SysCtrlSleep(); +} + +/** + * Timer runs at 32 MHz and is 32-bit wide + * The timer is divided by 32, whichs gives a 1 microsecond ticks + */ +void board_timer_init(void) { + // Configure the timer + TimerConfigure(GPTIMER2_BASE, GPTIMER_CFG_PERIODIC_UP); + + // Enable the timer + TimerEnable(GPTIMER2_BASE, GPTIMER_BOTH); +} + +/** + * Returns the current value of the timer + * The timer is divided by 32, whichs gives a 1 microsecond ticks + */ +uint32_t board_timer_get(void) { + uint32_t current; + + current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; + + return current; +} + +/** + * Returns true if the timer has expired + * The timer is divided by 32, whichs gives a 1 microsecond ticks + */ +bool board_timer_expired(uint32_t future) { + uint32_t current; + int32_t remaining; + + current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; + + remaining = (int32_t) (future - current); + + if (remaining > 0) { + return false; + } else { + return true; + } +} + +/** + * Resets the board + */ +void board_reset(void) { + SysCtrlReset(); +} + +//=========================== private ========================================= + +static void gpio_init(void) { + /* Set GPIOs as output */ + GPIOPinTypeGPIOOutput(GPIO_A_BASE, 0xFF); + GPIOPinTypeGPIOOutput(GPIO_B_BASE, 0xFF); + GPIOPinTypeGPIOOutput(GPIO_C_BASE, 0xFF); + GPIOPinTypeGPIOOutput(GPIO_D_BASE, 0xFF); + + /* Initialize GPIOs to low */ + GPIOPinWrite(GPIO_A_BASE, 0xFF, 0x00); + GPIOPinWrite(GPIO_B_BASE, 0xFF, 0x00); + GPIOPinWrite(GPIO_C_BASE, 0xFF, 0x00); + GPIOPinWrite(GPIO_D_BASE, 0xFF, 0x00); +} + +static void clock_init(void) { + /* Disable global interrupts */ + bool bIntDisabled = IntMasterDisable(); + + /* Configure the 32 kHz pins, PD6 and PD7, for crystal operation */ + /* By default they are configured as GPIOs */ + GPIODirModeSet(GPIO_D_BASE, 0x40, GPIO_DIR_MODE_IN); + GPIODirModeSet(GPIO_D_BASE, 0x80, GPIO_DIR_MODE_IN); + IOCPadConfigSet(GPIO_D_BASE, 0x40, IOC_OVERRIDE_ANA); + IOCPadConfigSet(GPIO_D_BASE, 0x80, IOC_OVERRIDE_ANA); + + /* Set the real-time clock to use the 32 kHz external crystal */ + /* Set the system clock to use the external 32 MHz crystal */ + /* Set the system clock to 32 MHz */ + SysCtrlClockSet(true, false, SYS_CTRL_SYSDIV_32MHZ); + + /* Set the IO clock to operate at 16 MHz */ + /* This way peripherals can run while the system clock is gated */ + SysCtrlIOClockSet(SYS_CTRL_SYSDIV_16MHZ); + + /* Wait until the selected clock configuration is stable */ + while (!((HWREG(SYS_CTRL_CLOCK_STA)) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); + + /* Define what peripherals run in each mode */ + SysCtrlRunSetting(); + SysCtrlSleepSetting(); + SysCtrlDeepSleepSetting(); + SysCtrlWakeupSetting(); + /* Re-enable interrupt if initially enabled */ + if (!bIntDisabled) { + IntMasterEnable(); + } +} + +/** + * Configures the user button as input source + */ +static void button_init(void) { + volatile uint32_t i; + + /* Delay to avoid pin floating problems */ + for (i = 0xFFFF; i != 0; i--); + + GPIOPinIntDisable(BSP_BUTTON_BASE, BSP_BUTTON_USER); + GPIOPinIntClear(BSP_BUTTON_BASE, BSP_BUTTON_USER); + + /* The button is an input GPIO on falling edge */ + GPIOPinTypeGPIOInput(BSP_BUTTON_BASE, BSP_BUTTON_USER); + GPIOIntTypeSet(BSP_BUTTON_BASE, BSP_BUTTON_USER, GPIO_FALLING_EDGE); + + /* Register the interrupt */ + GPIOPortIntRegister(BSP_BUTTON_BASE, GPIO_C_Handler); + + /* Clear and enable the interrupt */ + GPIOPinIntClear(BSP_BUTTON_BASE, BSP_BUTTON_USER); + GPIOPinIntEnable(BSP_BUTTON_BASE, BSP_BUTTON_USER); + user_button_initialized = TRUE; +} + +static void SysCtrlRunSetting(void) { + /* Disable General Purpose Timers 0, 1, 2, 3 when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT3); + + /* Disable SSI 0, 1 when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI1); + + /* Disable UART1 when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_UART1); + + /* Disable I2C, AES and PKA when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_AES); + + /* Enable UART0 and RFC when running */ + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_RFC); +} + +static void SysCtrlSleepSetting(void) { + /* Disable General Purpose Timers 0, 1, 2, 3 during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT3); + + /* Disable SSI 0, 1 during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI1); + + /* Disable UART 0, 1 during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_UART1); + + /* Disable I2C, PKA, AES during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_AES); + + /* Enable UART and RFC during sleep */ + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_RFC); +} + +static void SysCtrlDeepSleepSetting(void) { + /* Disable General Purpose Timers 0, 1, 2, 3 during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT3); + + /* Disable SSI 0, 1 during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI1); + + /* Disable UART 0, 1 during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART1); + + /* Disable I2C, PKA, AES during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_AES); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_RFC); +} + +static void SysCtrlWakeupSetting(void) { + /* Allow the SMTimer to wake up the processor */ + GPIOIntWakeupEnable(GPIO_IWE_SM_TIMER); +} + +//=========================== interrupt handlers ============================== + +/** + * GPIO_C interrupt handler. User button is GPIO_C_3 + * Erases a Flash sector to trigger the bootloader backdoor + */ +static void GPIO_C_Handler(void) { + if (!user_button_initialized) return; + /* Disable the interrupts */ + IntMasterDisable(); + leds_all_off(); + + /* Eras the CCA flash page */ + FlashMainPageErase(CC2538_FLASH_ADDRESS); + + leds_circular_shift(); + + /* Reset the board */ + SysCtrlReset(); +} diff --git a/bsp/boards/mimsy2-cc2538/board_info.h b/bsp/boards/mimsy2-cc2538/board_info.h new file mode 100644 index 0000000000..74b7ce551c --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/board_info.h @@ -0,0 +1,117 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Modified: Tengfei Chang (tengfei.chang@eecs.berkeley.edu) + * Date: July 2013 + * Description: CC2538-specific board information bsp module. + */ + +#ifndef __BOARD_INFO_H +#define __BOARD_INFO_H + +#include +#include + +#include +#include + +//=========================== defines ========================================= + +//===== interrupt state + +#define INTERRUPT_DECLARATION() +#define DISABLE_INTERRUPTS() IntMasterDisable() + +#define ENABLE_INTERRUPTS() IntMasterEnable() + +//===== timer + +#define PORT_TIMER_WIDTH uint32_t +#define PORT_RADIOTIMER_WIDTH uint32_t + +#define PORT_SIGNED_INT_WIDTH int32_t +#define PORT_TICS_PER_MS 33 + +// on GINA, we use the comparatorA interrupt for the OS +#define SCHEDULER_WAKEUP() +#define SCHEDULER_ENABLE_INTERRUPT() + +// this is a workaround from the fact that the interrupt pin for the GINA radio +// is not connected to a pin on the MSP which allows time capture. +#define CAPTURE_TIME() + +/* sleep timer interrupt */ +#define HAL_INT_PRIOR_ST (4 << 5) +/* MAC interrupts */ +#define HAL_INT_PRIOR_MAC (4 << 5) +/* UART interrupt */ +#define HAL_INT_PRIOR_UART (5 << 5) + +//===== pinout + +// [P4.7] radio SLP_TR_CNTL +#define PORT_PIN_RADIO_SLP_TR_CNTL_HIGH() +#define PORT_PIN_RADIO_SLP_TR_CNTL_LOW() +// radio reset line +// on cc2538, the /RST line is not connected to the uC +#define PORT_PIN_RADIO_RESET_HIGH() // nothing +#define PORT_PIN_RADIO_RESET_LOW() // nothing + +//===== IEEE802154E timing + +#define SLOTDURATION_10MS // by default, we use 10ms time slot + +#ifdef SLOTDURATION_10MS +// time-slot related +#define PORT_TsSlotDuration 328 // counter counts one extra count, see datasheet +// execution speed related +#define PORT_maxTxDataPrepare 10 // 305us (measured 82us) +#define PORT_maxRxAckPrepare 10 // 305us (measured 83us) +#define PORT_maxRxDataPrepare 4 // 122us (measured 22us) +#define PORT_maxTxAckPrepare 10 // 122us (measured 94us) +// radio speed related +#ifdef L2_SECURITY_ACTIVE +#define PORT_delayTx 14 // 366us (measured xxxus) +#else +#define PORT_delayTx 12 // 366us (measured xxxus) +#endif +#define PORT_delayRx 0 // 0us (can not measure) +// radio watchdog +#else +// time-slot related +#define PORT_TsSlotDuration 492 // counter counts one extra count, see datasheet +// execution speed related +#define PORT_maxTxDataPrepare 66 // 2014us (measured 746us) +#define PORT_maxRxAckPrepare 10 // 305us (measured 83us) +#define PORT_maxRxDataPrepare 33 // 1007us (measured 84us) +#define PORT_maxTxAckPrepare 22 // 305us (measured 219us) +// radio speed related +#define PORT_delayTx 12 // 214us (measured 219us) +#define PORT_delayRx 0 // 0us (can not measure) +// radio watchdog +#endif + +//===== adaptive_sync accuracy + +#define SYNC_ACCURACY 1 // ticks + +//===== per-board number of sensors + +#define NUMSENSORS 7 + +//=========================== typedef ======================================== + +//=========================== variables ======================================= + +static const uint8_t rreg_uriquery[] = "h=ucb"; +static const uint8_t infoBoardname[] = "CC2538"; +static const uint8_t infouCName[] = "CC2538"; +static const uint8_t infoRadioName[] = "CC2538 SoC"; + +//=========================== prototypes ====================================== + +//=========================== public ========================================== + +//=========================== private ========================================= + +#endif diff --git a/bsp/boards/mimsy2-cc2538/cc2538rf.h b/bsp/boards/mimsy2-cc2538/cc2538rf.h new file mode 100644 index 0000000000..82b05c2bb1 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/cc2538rf.h @@ -0,0 +1,93 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "radio" bsp module. + */ + +#ifndef CC2538RF_H_ +#define CC2538RF_H_ + +#include +#include + +/*--------------------------------------------------------------------------- + * RF Config + *---------------------------------------------------------------------------*/ +/* Constants */ +#define CC2538_RF_CCA_THRES_USER_GUIDE 0xF8 +#define CC2538_RF_TX_POWER_RECOMMENDED 0xD5 /* TODO: Check value */ +#define CC2538_RF_CHANNEL_MIN 11 //poipoi -- in fact is sending on 0x17 check that. +#define CC2538_RF_CHANNEL_MAX 26 +#define CC2538_RF_CHANNEL_SPACING 5 +#define CC2538_RF_MAX_PACKET_LEN 127 +#define CC2538_RF_MIN_PACKET_LEN 4 +#define CC2538_RF_CCA_CLEAR 1 +#define CC2538_RF_CCA_BUSY 0 +/*---------------------------------------------------------------------------*/ +#ifdef CC2538_RF_CONF_TX_POWER +#define CC2538_RF_TX_POWER CC2538_RF_CONF_TX_POWER +#else +#define CC2538_RF_TX_POWER CC2538_RF_TX_POWER_RECOMMENDED +#endif /* CC2538_RF_CONF_TX_POWER */ + + +#ifdef CC2538_RF_CONF_CHANNEL +#define CC2538_RF_CHANNEL CC2538_RF_CONF_CHANNEL +#else +#define CC2538_RF_CHANNEL CC2538_RF_CHANNEL_MIN +#endif /* CC2538_RF_CONF_CHANNEL */ + +#ifdef CC2538_RF_CONF_AUTOACK +#define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK +#else +#define CC2538_RF_AUTOACK 1 +#endif /* CC2538_RF_CONF_AUTOACK */ +/*--------------------------------------------------------------------------- + * Command Strobe Processor + *---------------------------------------------------------------------------*/ +/* OPCODES */ +#define CC2538_RF_CSP_OP_ISRXON 0xE3 +#define CC2538_RF_CSP_OP_ISTXON 0xE9 +#define CC2538_RF_CSP_OP_ISTXONCCA 0xEA +#define CC2538_RF_CSP_OP_ISRFOFF 0xEF +#define CC2538_RF_CSP_OP_ISFLUSHRX 0xED +#define CC2538_RF_CSP_OP_ISFLUSHTX 0xEE + +/** + * \brief Send an RX ON command strobe to the CSP + */ +#define CC2538_RF_CSP_ISRXON() \ + do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRXON; } while(0) + +/** + * \brief Send a TX ON command strobe to the CSP + */ +#define CC2538_RF_CSP_ISTXON() \ + do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISTXON; } while(0) + +/** + * \brief Send a RF OFF command strobe to the CSP + */ +#define CC2538_RF_CSP_ISRFOFF() \ + do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRFOFF; } while(0) + +/** + * \brief Flush the RX FIFO + */ +#define CC2538_RF_CSP_ISFLUSHRX() do { \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ +} while(0) + +/** + * \brief Flush the TX FIFO + */ +#define CC2538_RF_CSP_ISFLUSHTX() do { \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ +} while(0) +/*---------------------------------------------------------------------------*/ + + +#endif /* CC2538RF_H_ */ diff --git a/bsp/boards/mimsy2-cc2538/cc2538sf23.lds b/bsp/boards/mimsy2-cc2538/cc2538sf23.lds new file mode 100644 index 0000000000..57226ddde2 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/cc2538sf23.lds @@ -0,0 +1,62 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific linker script configuration file. + */ + +/** + * Indicate to the linker the entry point. + */ +ENTRY(ResetISR) + +/** + * RAM is 16 KB retention and 16 KB no retention + * NON-RETENTION RAM starts at 0x20000000 with length 0x00004000 + * RETENTION RAM starts at 0x20004000 with length 0x00004000 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 0x0003FFD4 + FLASH_CCA (RX) : ORIGIN = 0x0023FFD4, LENGTH = 12 + SRAM (RWX) : ORIGIN = 0x20004000, LENGTH = 0x00004000 +} + +SECTIONS +{ + .text : + { + _text = .; + KEEP(*(.vectors)) + *(.text*) + *(.rodata*) + _etext = .; + } > FLASH=0 + + .data : + AT (ADDR (.text) + SIZEOF (.text)) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > SRAM + + .ARM.exidx : + { + *(.ARM.exidx*) + } > FLASH + + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > SRAM + + .flashcca : + { + KEEP(*(.flashcca)) + } > FLASH_CCA +} diff --git a/bsp/boards/mimsy2-cc2538/cc2538sf53.lds b/bsp/boards/mimsy2-cc2538/cc2538sf53.lds new file mode 100644 index 0000000000..d38e7f2a67 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/cc2538sf53.lds @@ -0,0 +1,62 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific linker script configuration file. + */ + +/** + * Indicate to the linker the entry point. + */ +ENTRY(ResetISR) + +/** + * RAM is 16 KB retention and 16 KB no retention + * NON-RETENTION RAM starts at 0x20000000 with length 0x00004000 + * RETENTION RAM starts at 0x20004000 with length 0x00004000 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 0x0007FFD4 + FLASH_CCA (RX) : ORIGIN = 0x0027FFD4, LENGTH = 12 + SRAM (RWX) : ORIGIN = 0x20004000, LENGTH = 0x00004000 +} + +SECTIONS +{ + .text : + { + _text = .; + KEEP(*(.vectors)) + *(.text*) + *(.rodata*) + _etext = .; + } > FLASH=0 + + .data : + AT (ADDR (.text) + SIZEOF (.text)) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > SRAM + + .ARM.exidx : + { + *(.ARM.exidx*) + } > SRAM + + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > SRAM + + .flashcca : + { + KEEP(*(.flashcca)) + } > FLASH_CCA +} diff --git a/bsp/boards/mimsy2-cc2538/compass_vec_cal.h b/bsp/boards/mimsy2-cc2538/compass_vec_cal.h new file mode 100644 index 0000000000..2b156bc839 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/compass_vec_cal.h @@ -0,0 +1,35 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ + +#ifndef COMPASS_ONLY_CAL_H__ +#define COMPASS_ONLY_CAL_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_vector_compass_cal(void); +inv_error_t inv_disable_vector_compass_cal(void); +inv_error_t inv_start_vector_compass_cal(void); +inv_error_t inv_stop_vector_compass_cal(void); +void inv_vector_compass_cal_sensitivity(float sens); +inv_error_t inv_init_vector_compass_cal(void); + +#ifdef __cplusplus +} +#endif + +#endif // COMPASS_ONLY_CAL_H__ + diff --git a/bsp/boards/mimsy2-cc2538/cryptoengine.c b/bsp/boards/mimsy2-cc2538/cryptoengine.c new file mode 100644 index 0000000000..10f4ecc27b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/cryptoengine.c @@ -0,0 +1,159 @@ +/** +\brief Crypto engine implementation for OpenMote-CC2538 + +\author Malisa Vucinic , March 2015. +*/ +#include + +#include + +#include +#include +#include + +#include "cryptoengine.h" + +#define DEFAULT_KEY_AREA KEY_AREA_0 + + +//=========================== prototypes ====================================== + +static owerror_t load_key(uint8_t key[16], uint8_t* /* out */ key_location); + + +//=========================== public ========================================== + +owerror_t cryptoengine_init(void) { + // + // Enable AES peripheral + // + SysCtrlPeripheralReset(SYS_CTRL_PERIPH_AES); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_AES); + return E_SUCCESS; +} + +owerror_t cryptoengine_aes_ccms_enc(uint8_t* a, + uint8_t len_a, + uint8_t* m, + uint8_t* len_m, + uint8_t* nonce, + uint8_t l, + uint8_t key[16], + uint8_t len_mac) { + + bool encrypt; + uint8_t key_location; + + encrypt = *len_m > 0 ? true : false; + + if(load_key(key, &key_location) == E_SUCCESS) { + if(CCMAuthEncryptStart(encrypt, + len_mac, + nonce, + m, + (uint16_t) *len_m, + a, + (uint16_t) len_a, + key_location, + &m[*len_m], + l, + /* polling */ 0) == AES_SUCCESS) { + + do { + ASM_NOP; + } while(CCMAuthEncryptCheckResult() == 0); + + if(CCMAuthEncryptGetResult(len_mac, + (uint16_t) *len_m, + &m[*len_m]) == AES_SUCCESS) { + + *len_m += len_mac; + return E_SUCCESS; + } + } + } + + return E_FAIL; +} + +owerror_t cryptoengine_aes_ccms_dec(uint8_t* a, + uint8_t len_a, + uint8_t* m, + uint8_t* len_m, + uint8_t* nonce, + uint8_t l, + uint8_t key[16], + uint8_t len_mac) { + + bool decrypt; + uint8_t key_location; + uint8_t tag[CBC_MAX_MAC_SIZE]; + + decrypt = *len_m - len_mac > 0 ? true : false; + + if(load_key(key, &key_location) == E_SUCCESS) { + if(CCMInvAuthDecryptStart(decrypt, + len_mac, + nonce, + m, + (uint16_t) *len_m, + a, + (uint16_t) len_a, + key_location, + tag, + l, + /* polling */ 0) == AES_SUCCESS) { + + do { + ASM_NOP; + } while(CCMInvAuthDecryptCheckResult() == 0); + + if(CCMInvAuthDecryptGetResult(len_mac, + m, + (uint16_t) *len_m, + tag) == AES_SUCCESS) { + + *len_m -= len_mac; + return E_SUCCESS; + } + } + } + return E_FAIL; +} + +owerror_t cryptoengine_aes_ecb_enc(uint8_t* buffer, uint8_t* key) { + uint8_t key_location; + if(load_key(key, &key_location) == E_SUCCESS) { + // Polling + if(AESECBStart(buffer, buffer, key_location, 1, 0) == AES_SUCCESS) { + do { + ASM_NOP; + } while(AESECBCheckResult() == 0); + + if(AESECBGetResult() == AES_SUCCESS) { + return E_SUCCESS; + } + } + } + return E_FAIL; +} + +//=========================== private ========================================== + +/** +\brief On success, returns by reference the location in key RAM where the + new/existing key is stored. +*/ +static owerror_t load_key(uint8_t key[16], uint8_t* /* out */ key_location) { + static uint8_t loaded_key[16]; + + if(memcmp(loaded_key, key, 16) != 0) { + memcpy(loaded_key, key, 16); + // Load the key in key RAM + if(AESLoadKey(loaded_key, DEFAULT_KEY_AREA) != AES_SUCCESS) { + return E_FAIL; + } + } + *key_location = DEFAULT_KEY_AREA; + return E_SUCCESS; +} diff --git a/bsp/boards/mimsy2-cc2538/data_builder.c b/bsp/boards/mimsy2-cc2538/data_builder.c new file mode 100644 index 0000000000..8dfffb21bc --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/data_builder.c @@ -0,0 +1,1263 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/** + * @defgroup Data_Builder data_builder + * @brief Motion Library - Data Builder + * Constructs and Creates the data for MPL + * + * @{ + * @file data_builder.c + * @brief Data Builder. + */ + +#undef MPL_LOG_NDEBUG +#define MPL_LOG_NDEBUG 0 /* Use 0 to turn on MPL_LOGV output */ + +#include + +#include "ml_math_func.h" +#include "data_builder.h" +#include "mlmath.h" +#include "storage_manager.h" +#include "message_layer.h" +#include "results_holder.h" + +#include "log.h" +#undef MPL_LOG_TAG +#define MPL_LOG_TAG "MPL" + +typedef inv_error_t (*inv_process_cb_func)(struct inv_sensor_cal_t *data); + +struct process_t { + inv_process_cb_func func; + int priority; + int data_required; +}; + +struct inv_db_save_t { + /** Compass Bias in Chip Frame in Hardware units scaled by 2^16 */ + long compass_bias[3]; + /** Gyro Bias in Chip Frame in Hardware units scaled by 2^16 */ + long gyro_bias[3]; + /** Temperature when *gyro_bias was stored. */ + long gyro_temp; + /** Flag to indicate temperature compensation that biases where stored. */ + int gyro_bias_tc_set; + /** Accel Bias in Chip Frame in Hardware units scaled by 2^16 */ + long accel_bias[3]; + /** Temperature when accel bias was stored. */ + long accel_temp; + long gyro_temp_slope[3]; + /** Sensor Accuracy */ + int gyro_accuracy; + int accel_accuracy; + int compass_accuracy; +}; + +struct inv_data_builder_t { + int num_cb; + struct process_t process[INV_MAX_DATA_CB]; + struct inv_db_save_t save; + int compass_disturbance; +#ifdef INV_PLAYBACK_DBG + int debug_mode; + int last_mode; + FILE *file; +#endif +}; + +void inv_apply_calibration(struct inv_single_sensor_t *sensor, const long *bias); +static void inv_set_contiguous(void); + +static struct inv_data_builder_t inv_data_builder; +static struct inv_sensor_cal_t sensors; + +/** Change this key if the data being stored by this file changes */ +#define INV_DB_SAVE_KEY 53395 + +#ifdef INV_PLAYBACK_DBG + +/** Turn on data logging to allow playback of same scenario at a later time. +* @param[in] file File to write to, must be open. +*/ +void inv_turn_on_data_logging(FILE *file) +{ + MPL_LOGV("input data logging started\n"); + inv_data_builder.file = file; + inv_data_builder.debug_mode = RD_RECORD; +} + +/** Turn off data logging to allow playback of same scenario at a later time. +* File passed to inv_turn_on_data_logging() must be closed after calling this. +*/ +void inv_turn_off_data_logging() +{ + MPL_LOGV("input data logging stopped\n"); + inv_data_builder.debug_mode = RD_NO_DEBUG; + inv_data_builder.file = NULL; +} +#endif + +/** This function receives the data that was stored in non-volatile memory between power off */ +static inv_error_t inv_db_load_func(const unsigned char *data) +{ + memcpy(&inv_data_builder.save, data, sizeof(inv_data_builder.save)); + // copy in the saved accuracy in the actual sensors accuracy + sensors.gyro.accuracy = inv_data_builder.save.gyro_accuracy; + sensors.accel.accuracy = inv_data_builder.save.accel_accuracy; + sensors.compass.accuracy = inv_data_builder.save.compass_accuracy; + // TODO + if (sensors.compass.accuracy == 3) { + inv_set_compass_bias_found(1); + } + return INV_SUCCESS; +} + +/** This function returns the data to be stored in non-volatile memory between power off */ +static inv_error_t inv_db_save_func(unsigned char *data) +{ + memcpy(data, &inv_data_builder.save, sizeof(inv_data_builder.save)); + return INV_SUCCESS; +} + +/** Initialize the data builder +*/ +inv_error_t inv_init_data_builder(void) +{ + /* TODO: Hardcode temperature scale/offset here. */ + memset(&inv_data_builder, 0, sizeof(inv_data_builder)); + memset(&sensors, 0, sizeof(sensors)); + + // disable the soft iron transform process + inv_reset_compass_soft_iron_matrix(); + + return inv_register_load_store(inv_db_load_func, inv_db_save_func, + sizeof(inv_data_builder.save), + INV_DB_SAVE_KEY); +} + +/** Gyro sensitivity. +* @return A scale factor to convert device units to degrees per second scaled by 2^16 +* such that degrees_per_second = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum rate * 2^15. +*/ +long inv_get_gyro_sensitivity() +{ + return sensors.gyro.sensitivity; +} + +/** Accel sensitivity. +* @return A scale factor to convert device units to g's scaled by 2^16 +* such that g_s = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum accel value in g's * 2^15. +*/ +long inv_get_accel_sensitivity(void) +{ + return sensors.accel.sensitivity; +} + +/** Compass sensitivity. +* @return A scale factor to convert device units to micro Tesla scaled by 2^16 +* such that uT = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum uT * 2^15. +*/ +long inv_get_compass_sensitivity(void) +{ + return sensors.compass.sensitivity; +} + +/** Sets orientation and sensitivity field for a sensor. +* @param[out] sensor Structure to apply settings to +* @param[in] orientation Orientation description of how part is mounted. +* @param[in] sensitivity A Scale factor to convert from hardware units to +* standard units (dps, uT, g). +*/ +void set_sensor_orientation_and_scale(struct inv_single_sensor_t *sensor, + int orientation, long sensitivity) +{ + sensor->sensitivity = sensitivity; + sensor->orientation = orientation; +} + +/** Sets the Orientation and Sensitivity of the gyro data. +* @param[in] orientation A scalar defining the transformation from chip mounting +* to the body frame. The function inv_orientation_matrix_to_scalar() +* can convert the transformation matrix to this scalar and describes the +* scalar in further detail. +* @param[in] sensitivity A scale factor to convert device units to degrees per second scaled by 2^16 +* such that degrees_per_second = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum rate * 2^15. +*/ +void inv_set_gyro_orientation_and_scale(int orientation, long sensitivity) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_G_ORIENT; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&orientation, sizeof(orientation), 1, inv_data_builder.file); + fwrite(&sensitivity, sizeof(sensitivity), 1, inv_data_builder.file); + } +#endif + set_sensor_orientation_and_scale(&sensors.gyro, orientation, + sensitivity); +} + +/** Set Gyro Sample rate in micro seconds. +* @param[in] sample_rate_us Set Gyro Sample rate in us +*/ +void inv_set_gyro_sample_rate(long sample_rate_us) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_G_SAMPLE_RATE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); + } +#endif + sensors.gyro.sample_rate_us = sample_rate_us; + sensors.gyro.sample_rate_ms = sample_rate_us / 1000; + if (sensors.gyro.bandwidth == 0) { + sensors.gyro.bandwidth = (int)(1000000L / sample_rate_us); + } +} + +/** Set Accel Sample rate in micro seconds. +* @param[in] sample_rate_us Set Accel Sample rate in us +*/ +void inv_set_accel_sample_rate(long sample_rate_us) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_A_SAMPLE_RATE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); + } +#endif + sensors.accel.sample_rate_us = sample_rate_us; + sensors.accel.sample_rate_ms = sample_rate_us / 1000; + if (sensors.accel.bandwidth == 0) { + sensors.accel.bandwidth = (int)(1000000L / sample_rate_us); + } +} + +/** Set Compass Sample rate in micro seconds. +* @param[in] sample_rate_us Set Gyro Sample rate in micro seconds. +*/ +void inv_set_compass_sample_rate(long sample_rate_us) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_C_SAMPLE_RATE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); + } +#endif + sensors.compass.sample_rate_us = sample_rate_us; + sensors.compass.sample_rate_ms = sample_rate_us / 1000; + if (sensors.compass.bandwidth == 0) { + sensors.compass.bandwidth = (int)(1000000L / sample_rate_us); + } +} + +void inv_get_gyro_sample_rate_ms(long *sample_rate_ms) +{ + *sample_rate_ms = sensors.gyro.sample_rate_ms; +} + +void inv_get_accel_sample_rate_ms(long *sample_rate_ms) +{ + *sample_rate_ms = sensors.accel.sample_rate_ms; +} + +void inv_get_compass_sample_rate_ms(long *sample_rate_ms) +{ + *sample_rate_ms = sensors.compass.sample_rate_ms; +} + +/** Set Quat Sample rate in micro seconds. +* @param[in] sample_rate_us Set Quat Sample rate in us +*/ +void inv_set_quat_sample_rate(long sample_rate_us) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_Q_SAMPLE_RATE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); + } +#endif + sensors.quat.sample_rate_us = sample_rate_us; + sensors.quat.sample_rate_ms = sample_rate_us / 1000; +} + +/** Set Gyro Bandwidth in Hz +* @param[in] bandwidth_hz Gyro bandwidth in Hz +*/ +void inv_set_gyro_bandwidth(int bandwidth_hz) +{ + sensors.gyro.bandwidth = bandwidth_hz; +} + +/** Set Accel Bandwidth in Hz +* @param[in] bandwidth_hz Gyro bandwidth in Hz +*/ +void inv_set_accel_bandwidth(int bandwidth_hz) +{ + sensors.accel.bandwidth = bandwidth_hz; +} + +/** Set Compass Bandwidth in Hz +* @param[in] bandwidth_hz Gyro bandwidth in Hz +*/ +void inv_set_compass_bandwidth(int bandwidth_hz) +{ + sensors.compass.bandwidth = bandwidth_hz; +} + +/** Helper function stating whether the compass is on or off. + * @return TRUE if compass if on, 0 if compass if off +*/ +int inv_get_compass_on() +{ + return (sensors.compass.status & INV_SENSOR_ON) == INV_SENSOR_ON; +} + +/** Helper function stating whether the gyro is on or off. + * @return TRUE if gyro if on, 0 if gyro if off +*/ +int inv_get_gyro_on() +{ + return (sensors.gyro.status & INV_SENSOR_ON) == INV_SENSOR_ON; +} + +/** Helper function stating whether the acceleromter is on or off. + * @return TRUE if accel if on, 0 if accel if off +*/ +int inv_get_accel_on() +{ + return (sensors.accel.status & INV_SENSOR_ON) == INV_SENSOR_ON; +} + +/** Get last timestamp across all 3 sensors that are on. +* This find out which timestamp has the largest value for sensors that are on. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_time_t inv_get_last_timestamp() +{ + inv_time_t timestamp = 0; + if (sensors.accel.status & INV_SENSOR_ON) { + timestamp = sensors.accel.timestamp; + } + if (sensors.gyro.status & INV_SENSOR_ON) { + if (timestamp < sensors.gyro.timestamp) { + timestamp = sensors.gyro.timestamp; + } + } + if (sensors.compass.status & INV_SENSOR_ON) { + if (timestamp < sensors.compass.timestamp) { + timestamp = sensors.compass.timestamp; + } + } + if (sensors.temp.status & INV_SENSOR_ON) { + if (timestamp < sensors.temp.timestamp) + timestamp = sensors.temp.timestamp; + } + return timestamp; +} + +/** Sets the orientation and sensitivity of the gyro data. +* @param[in] orientation A scalar defining the transformation from chip mounting +* to the body frame. The function inv_orientation_matrix_to_scalar() +* can convert the transformation matrix to this scalar and describes the +* scalar in further detail. +* @param[in] sensitivity A scale factor to convert device units to g's +* such that g's = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum g_value * 2^15. +*/ +void inv_set_accel_orientation_and_scale(int orientation, long sensitivity) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_A_ORIENT; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&orientation, sizeof(orientation), 1, inv_data_builder.file); + fwrite(&sensitivity, sizeof(sensitivity), 1, inv_data_builder.file); + } +#endif + set_sensor_orientation_and_scale(&sensors.accel, orientation, + sensitivity); +} + +/** Sets the Orientation and Sensitivity of the gyro data. +* @param[in] orientation A scalar defining the transformation from chip mounting +* to the body frame. The function inv_orientation_matrix_to_scalar() +* can convert the transformation matrix to this scalar and describes the +* scalar in further detail. +* @param[in] sensitivity A scale factor to convert device units to uT +* such that uT = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum uT_value * 2^15. +*/ +void inv_set_compass_orientation_and_scale(int orientation, long sensitivity) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_C_ORIENT; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&orientation, sizeof(orientation), 1, inv_data_builder.file); + fwrite(&sensitivity, sizeof(sensitivity), 1, inv_data_builder.file); + } +#endif + set_sensor_orientation_and_scale(&sensors.compass, orientation, sensitivity); +} + +void inv_matrix_vector_mult(const long *A, const long *x, long *y) +{ + y[0] = inv_q30_mult(A[0], x[0]) + inv_q30_mult(A[1], x[1]) + inv_q30_mult(A[2], x[2]); + y[1] = inv_q30_mult(A[3], x[0]) + inv_q30_mult(A[4], x[1]) + inv_q30_mult(A[5], x[2]); + y[2] = inv_q30_mult(A[6], x[0]) + inv_q30_mult(A[7], x[1]) + inv_q30_mult(A[8], x[2]); +} + +/** Takes raw data stored in the sensor, removes bias, and converts it to +* calibrated data in the body frame. Also store raw data for body frame. +* @param[in,out] sensor structure to modify +* @param[in] bias bias in the mounting frame, in hardware units scaled by +* 2^16. Length 3. +*/ +void inv_apply_calibration(struct inv_single_sensor_t *sensor, const long *bias) +{ + long raw32[3]; + + // Convert raw to calibrated + raw32[0] = (long)sensor->raw[0] << 15; + raw32[1] = (long)sensor->raw[1] << 15; + raw32[2] = (long)sensor->raw[2] << 15; + + inv_convert_to_body_with_scale(sensor->orientation, sensor->sensitivity << 1, raw32, sensor->raw_scaled); + + raw32[0] -= bias[0] >> 1; + raw32[1] -= bias[1] >> 1; + raw32[2] -= bias[2] >> 1; + + inv_convert_to_body_with_scale(sensor->orientation, sensor->sensitivity << 1, raw32, sensor->calibrated); + + sensor->status |= INV_CALIBRATED; +} + +/** Returns the current bias for the compass +* @param[out] bias Compass bias in hardware units scaled by 2^16. In mounting frame. +* Length 3. +*/ +void inv_get_compass_bias(long *bias) +{ + if (bias != NULL) { + memcpy(bias, inv_data_builder.save.compass_bias, sizeof(inv_data_builder.save.compass_bias)); + } +} + +void inv_set_compass_bias(const long *bias, int accuracy) +{ + if (memcmp(inv_data_builder.save.compass_bias, bias, sizeof(inv_data_builder.save.compass_bias))) { + memcpy(inv_data_builder.save.compass_bias, bias, sizeof(inv_data_builder.save.compass_bias)); + inv_apply_calibration(&sensors.compass, inv_data_builder.save.compass_bias); + } + sensors.compass.accuracy = accuracy; + inv_data_builder.save.compass_accuracy = accuracy; + inv_set_message(INV_MSG_NEW_CB_EVENT, INV_MSG_NEW_CB_EVENT, 0); +} + +/** Set the state of a compass disturbance +* @param[in] dist 1=disturbance, 0=no disturbance +*/ +void inv_set_compass_disturbance(int dist) +{ + inv_data_builder.compass_disturbance = dist; +} + +int inv_get_compass_disturbance(void) { + return inv_data_builder.compass_disturbance; +} +/** Sets the accel bias. +* @param[in] bias Accel bias, length 3. In HW units scaled by 2^16 in body frame +* @param[in] accuracy Accuracy rating from 0 to 3, with 3 being most accurate. +*/ +void inv_set_accel_bias(const long *bias, int accuracy) +{ + if (bias) { + if (memcmp(inv_data_builder.save.accel_bias, bias, sizeof(inv_data_builder.save.accel_bias))) { + memcpy(inv_data_builder.save.accel_bias, bias, sizeof(inv_data_builder.save.accel_bias)); + inv_apply_calibration(&sensors.accel, inv_data_builder.save.accel_bias); + } + } + sensors.accel.accuracy = accuracy; + inv_data_builder.save.accel_accuracy = accuracy; + inv_set_message(INV_MSG_NEW_AB_EVENT, INV_MSG_NEW_AB_EVENT, 0); +} + +/** Sets the accel accuracy. +* @param[in] accuracy Accuracy rating from 0 to 3, with 3 being most accurate. +*/ +void inv_set_accel_accuracy(int accuracy) +{ + sensors.accel.accuracy = accuracy; + inv_data_builder.save.accel_accuracy = accuracy; + inv_set_message(INV_MSG_NEW_AB_EVENT, INV_MSG_NEW_AB_EVENT, 0); +} + +/** Sets the accel bias with control over which axis. +* @param[in] bias Accel bias, length 3. In HW units scaled by 2^16 in body frame +* @param[in] accuracy Accuracy rating from 0 to 3, with 3 being most accurate. +* @param[in] mask Mask to select axis to apply bias set. +*/ +void inv_set_accel_bias_mask(const long *bias, int accuracy, int mask) +{ + if (bias) { + if (mask & 1){ + inv_data_builder.save.accel_bias[0] = bias[0]; + } + if (mask & 2){ + inv_data_builder.save.accel_bias[1] = bias[1]; + } + if (mask & 4){ + inv_data_builder.save.accel_bias[2] = bias[2]; + } + + inv_apply_calibration(&sensors.accel, inv_data_builder.save.accel_bias); + } + sensors.accel.accuracy = accuracy; + inv_data_builder.save.accel_accuracy = accuracy; + inv_set_message(INV_MSG_NEW_AB_EVENT, INV_MSG_NEW_AB_EVENT, 0); +} + + +/** Sets the gyro bias +* @param[in] bias Gyro bias in hardware units scaled by 2^16. In chip mounting frame. +* Length 3. +* @param[in] accuracy Accuracy of bias. 0 = least accurate, 3 = most accurate. +*/ +void inv_set_gyro_bias(const long *bias, int accuracy) +{ + if (bias != NULL) { + if (memcmp(inv_data_builder.save.gyro_bias, bias, sizeof(inv_data_builder.save.gyro_bias))) { + memcpy(inv_data_builder.save.gyro_bias, bias, sizeof(inv_data_builder.save.gyro_bias)); + inv_apply_calibration(&sensors.gyro, inv_data_builder.save.gyro_bias); + } + } + sensors.gyro.accuracy = accuracy; + inv_data_builder.save.gyro_accuracy = accuracy; + + /* TODO: What should we do if there's no temperature data? */ + if (sensors.temp.calibrated[0]) + inv_data_builder.save.gyro_temp = sensors.temp.calibrated[0]; + else + /* Set to 27 deg C for now until we've got a better solution. */ + inv_data_builder.save.gyro_temp = 1769472L; + inv_set_message(INV_MSG_NEW_GB_EVENT, INV_MSG_NEW_GB_EVENT, 0); + + /* TODO: this flag works around the synchronization problem seen with using + the user-exposed message layer to signal the temperature compensation + module that gyro biases were set. + A better, cleaner method is certainly needed. */ + inv_data_builder.save.gyro_bias_tc_set = true; +} + +/** + * @internal + * @brief Return whether gyro biases were set to signal the temperature + * compensation algorithm that it can collect a data point to build + * the temperature slope while in no motion state. + * The flag clear automatically after is read. + * @return true if the flag was set, indicating gyro biases were set. + * false if the flag was not set. + */ +int inv_get_gyro_bias_tc_set(void) +{ + int flag = (inv_data_builder.save.gyro_bias_tc_set == true); + inv_data_builder.save.gyro_bias_tc_set = false; + return flag; +} + +/* TODO: Add this information to inv_sensor_cal_t */ +/** + * Get the gyro biases and temperature record from MPL + * @param[in] bias + * Gyro bias in hardware units scaled by 2^16. + * In chip mounting frame. + * Length 3. + * @param[in] temp + * Tempearature in degrees C. + */ +void inv_get_gyro_bias(long *bias, long *temp) +{ + if (bias != NULL) + memcpy(bias, inv_data_builder.save.gyro_bias, + sizeof(inv_data_builder.save.gyro_bias)); + if (temp != NULL) + temp[0] = inv_data_builder.save.gyro_temp; +} + +/** Get Accel Bias +* @param[out] bias Accel bias where +* @param[out] temp Temperature where 1 C = 2^16 +*/ +void inv_get_accel_bias(long *bias, long *temp) +{ + if (bias != NULL) + memcpy(bias, inv_data_builder.save.accel_bias, + sizeof(inv_data_builder.save.accel_bias)); + if (temp != NULL) + temp[0] = inv_data_builder.save.accel_temp; +} + +/** + * Record new accel data for use when inv_execute_on_data() is called + * @param[in] accel accel data. + * Length 3. + * Calibrated data is in m/s^2 scaled by 2^16 in body frame. + * Raw data is in device units in chip mounting frame. + * @param[in] status + * Lower 2 bits are the accuracy, with 0 being inaccurate, and 3 + * being most accurate. + * The upper bit INV_CALIBRATED, is set if the data was calibrated + * outside MPL and it is not set if the data being passed is raw. + * Raw data should be in device units, typically in a 16-bit range. + * @param[in] timestamp + * Monotonic time stamp, for Android it's in nanoseconds. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_build_accel(const long *accel, int status, inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_ACCEL; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(accel, sizeof(accel[0]), 3, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + + if ((status & INV_CALIBRATED) == 0) { + sensors.accel.raw[0] = (short)accel[0]; + sensors.accel.raw[1] = (short)accel[1]; + sensors.accel.raw[2] = (short)accel[2]; + sensors.accel.status |= INV_RAW_DATA; + inv_apply_calibration(&sensors.accel, inv_data_builder.save.accel_bias); + } else { + sensors.accel.calibrated[0] = accel[0]; + sensors.accel.calibrated[1] = accel[1]; + sensors.accel.calibrated[2] = accel[2]; + sensors.accel.status |= INV_CALIBRATED; + sensors.accel.accuracy = status & 3; + inv_data_builder.save.accel_accuracy = status & 3; + } + sensors.accel.status |= INV_NEW_DATA | INV_SENSOR_ON; + sensors.accel.timestamp_prev = sensors.accel.timestamp; + sensors.accel.timestamp = timestamp; + + return INV_SUCCESS; +} + +/** Record new gyro data and calls inv_execute_on_data() if previous +* sample has not been processed. +* @param[in] gyro Data is in device units. Length 3. +* @param[in] timestamp Monotonic time stamp, for Android it's in nanoseconds. +* @param[out] executed Set to 1 if data processing was done. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_build_gyro(const short *gyro, inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_GYRO; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(gyro, sizeof(gyro[0]), 3, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + + memcpy(sensors.gyro.raw, gyro, 3 * sizeof(short)); + sensors.gyro.status |= INV_NEW_DATA | INV_RAW_DATA | INV_SENSOR_ON; + sensors.gyro.timestamp_prev = sensors.gyro.timestamp; + sensors.gyro.timestamp = timestamp; + inv_apply_calibration(&sensors.gyro, inv_data_builder.save.gyro_bias); + + return INV_SUCCESS; +} + +/** Record new compass data for use when inv_execute_on_data() is called +* @param[in] compass Compass data, if it was calibrated outside MPL, the units are uT scaled by 2^16. +* Length 3. +* @param[in] status Lower 2 bits are the accuracy, with 0 being inaccurate, and 3 being most accurate. +* The upper bit INV_CALIBRATED, is set if the data was calibrated outside MPL and it is +* not set if the data being passed is raw. Raw data should be in device units, typically +* in a 16-bit range. +* @param[in] timestamp Monotonic time stamp, for Android it's in nanoseconds. +* @param[out] executed Set to 1 if data processing was done. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_build_compass(const long *compass, int status, + inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_COMPASS; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(compass, sizeof(compass[0]), 3, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + + if ((status & INV_CALIBRATED) == 0) { + long data[3]; + inv_set_compass_soft_iron_input_data(compass); + inv_get_compass_soft_iron_output_data(data); + sensors.compass.raw[0] = (short)data[0]; + sensors.compass.raw[1] = (short)data[1]; + sensors.compass.raw[2] = (short)data[2]; + inv_apply_calibration(&sensors.compass, inv_data_builder.save.compass_bias); + sensors.compass.status |= INV_RAW_DATA; + } else { + sensors.compass.calibrated[0] = compass[0]; + sensors.compass.calibrated[1] = compass[1]; + sensors.compass.calibrated[2] = compass[2]; + sensors.compass.status |= INV_CALIBRATED; + sensors.compass.accuracy = status & 3; + inv_data_builder.save.compass_accuracy = status & 3; + } + sensors.compass.timestamp_prev = sensors.compass.timestamp; + sensors.compass.timestamp = timestamp; + sensors.compass.status |= INV_NEW_DATA | INV_SENSOR_ON; + + return INV_SUCCESS; +} + +/** Record new temperature data for use when inv_execute_on_data() is called. + * @param[in] temp Temperature data in q16 format. + * @param[in] timestamp Monotonic time stamp; for Android it's in + * nanoseconds. +* @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_build_temp(const long temp, inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_TEMPERATURE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&temp, sizeof(temp), 1, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + sensors.temp.calibrated[0] = temp; + sensors.temp.status |= INV_NEW_DATA | INV_RAW_DATA | INV_SENSOR_ON; + sensors.temp.timestamp_prev = sensors.temp.timestamp; + sensors.temp.timestamp = timestamp; + /* TODO: Apply scale, remove offset. */ + + return INV_SUCCESS; +} +/** quaternion data +* @param[in] quat Quaternion data. 2^30 = 1.0 or 2^14=1 for 16-bit data. +* Real part first. Length 4. +* @param[in] status number of axis, 16-bit or 32-bit +* @param[in] timestamp +* @param[in] timestamp Monotonic time stamp; for Android it's in +* nanoseconds. +* @param[out] executed Set to 1 if data processing was done. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_build_quat(const long *quat, int status, inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_QUAT; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(quat, sizeof(quat[0]), 4, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + + memcpy(sensors.quat.raw, quat, sizeof(sensors.quat.raw)); + sensors.quat.timestamp = timestamp; + sensors.quat.status |= INV_NEW_DATA | INV_RAW_DATA | INV_SENSOR_ON; + sensors.quat.status |= (INV_BIAS_APPLIED & status); + + return INV_SUCCESS; +} + +/** This should be called when the accel has been turned off. This is so +* that we will know if the data is contiguous. +*/ +void inv_accel_was_turned_off() +{ + sensors.accel.status = 0; +} + +/** This should be called when the compass has been turned off. This is so +* that we will know if the data is contiguous. +*/ +void inv_compass_was_turned_off() +{ + sensors.compass.status = 0; +} + +/** This should be called when the quaternion data from the DMP has been turned off. This is so +* that we will know if the data is contiguous. +*/ +void inv_quaternion_sensor_was_turned_off(void) +{ + sensors.quat.status = 0; +} + +/** This should be called when the gyro has been turned off. This is so +* that we will know if the data is contiguous. +*/ +void inv_gyro_was_turned_off() +{ + sensors.gyro.status = 0; +} + +/** This should be called when the temperature sensor has been turned off. + * This is so that we will know if the data is contiguous. + */ +void inv_temperature_was_turned_off() +{ + sensors.temp.status = 0; +} + +/** Registers to receive a callback when there is new sensor data. +* @internal +* @param[in] func Function pointer to receive callback when there is new sensor data +* @param[in] priority Lower priority numbers receive a callback before larger numbers. All priority +* numbers must be unique. +* @param[in] sensor_type Sets the type of data that triggers the callback. Must be non-zero. May be +* a combination. INV_ACCEL_NEW = accel data, INV_GYRO_NEW = +* gyro data, INV_MAG_NEW = compass data. So passing in +* INV_ACCEL_NEW | INV_MAG_NEW, a +* callback would be generated if there was new magnetomer data OR new accel data. +*/ +inv_error_t inv_register_data_cb( + inv_error_t (*func)(struct inv_sensor_cal_t *data), + int priority, int sensor_type) +{ + inv_error_t result = INV_SUCCESS; + int kk, nn; + + // Make sure we haven't registered this function already + // Or used the same priority + for (kk = 0; kk < inv_data_builder.num_cb; ++kk) { + if ((inv_data_builder.process[kk].func == func) || + (inv_data_builder.process[kk].priority == priority)) { + return INV_ERROR_INVALID_PARAMETER; //fixme give a warning + } + } + + // Make sure we have not filled up our number of allowable callbacks + if (inv_data_builder.num_cb <= INV_MAX_DATA_CB - 1) { + kk = 0; + if (inv_data_builder.num_cb != 0) { + // set kk to be where this new callback goes in the array + while ((kk < inv_data_builder.num_cb) && + (inv_data_builder.process[kk].priority < priority)) { + kk++; + } + if (kk != inv_data_builder.num_cb) { + // We need to move the others + for (nn = inv_data_builder.num_cb; nn > kk; --nn) { + inv_data_builder.process[nn] = + inv_data_builder.process[nn - 1]; + } + } + } + // Add new callback + inv_data_builder.process[kk].func = func; + inv_data_builder.process[kk].priority = priority; + inv_data_builder.process[kk].data_required = sensor_type; + inv_data_builder.num_cb++; + } else { + MPL_LOGE("Unable to add feature callback as too many were already registered\n"); + result = INV_ERROR_MEMORY_EXAUSTED; + } + + return result; +} + +/** Unregisters the callback that happens when new sensor data is received. +* @internal +* @param[in] func Function pointer to receive callback when there is new sensor data +* @param[in] priority Lower priority numbers receive a callback before larger numbers. All priority +* numbers must be unique. +* @param[in] sensor_type Sets the type of data that triggers the callback. Must be non-zero. May be +* a combination. INV_ACCEL_NEW = accel data, INV_GYRO_NEW = +* gyro data, INV_MAG_NEW = compass data. So passing in +* INV_ACCEL_NEW | INV_MAG_NEW, a +* callback would be generated if there was new magnetomer data OR new accel data. +*/ +inv_error_t inv_unregister_data_cb( + inv_error_t (*func)(struct inv_sensor_cal_t *data)) +{ + int kk, nn; + + for (kk = 0; kk < inv_data_builder.num_cb; ++kk) { + if (inv_data_builder.process[kk].func == func) { + // Delete this callback + for (nn = kk + 1; nn < inv_data_builder.num_cb; ++nn) { + inv_data_builder.process[nn - 1] = + inv_data_builder.process[nn]; + } + inv_data_builder.num_cb--; + return INV_SUCCESS; + } + } + + return INV_SUCCESS; // We did not find the callback +} + +/** After at least one of inv_build_gyro(), inv_build_accel(), or +* inv_build_compass() has been called, this function should be called. +* It will process the data it has received and update all the internal states +* and features that have been turned on. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_execute_on_data(void) +{ + inv_error_t result, first_error; + int kk; + int mode; + +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_EXECUTE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + } +#endif + // Determine what new data we have + mode = 0; + if (sensors.gyro.status & INV_NEW_DATA) + mode |= INV_GYRO_NEW; + if (sensors.accel.status & INV_NEW_DATA) + mode |= INV_ACCEL_NEW; + if (sensors.compass.status & INV_NEW_DATA) + mode |= INV_MAG_NEW; + if (sensors.temp.status & INV_NEW_DATA) + mode |= INV_TEMP_NEW; + if (sensors.quat.status & INV_NEW_DATA) + mode |= INV_QUAT_NEW; + + first_error = INV_SUCCESS; + + for (kk = 0; kk < inv_data_builder.num_cb; ++kk) { + if (mode & inv_data_builder.process[kk].data_required) { + result = inv_data_builder.process[kk].func(&sensors); + if (result && !first_error) { + first_error = result; + } + } + } + + inv_set_contiguous(); + + return first_error; +} + +/** Cleans up status bits after running all the callbacks. It sets the contiguous flag. +* +*/ +static void inv_set_contiguous(void) +{ + inv_time_t current_time = 0; + if (sensors.gyro.status & INV_NEW_DATA) { + sensors.gyro.status |= INV_CONTIGUOUS; + current_time = sensors.gyro.timestamp; + } + if (sensors.accel.status & INV_NEW_DATA) { + sensors.accel.status |= INV_CONTIGUOUS; + current_time = MAX(current_time, sensors.accel.timestamp); + } + if (sensors.compass.status & INV_NEW_DATA) { + sensors.compass.status |= INV_CONTIGUOUS; + current_time = MAX(current_time, sensors.compass.timestamp); + } + if (sensors.temp.status & INV_NEW_DATA) { + sensors.temp.status |= INV_CONTIGUOUS; + current_time = MAX(current_time, sensors.temp.timestamp); + } + if (sensors.quat.status & INV_NEW_DATA) { + sensors.quat.status |= INV_CONTIGUOUS; + current_time = MAX(current_time, sensors.quat.timestamp); + } + +#if 0 + /* See if sensors are still on. These should be turned off by inv_*_was_turned_off() + * type functions. This is just in case that breaks down. We make sure + * all the data is within 2 seconds of the newest piece of data*/ + if (inv_delta_time_ms(current_time, sensors.gyro.timestamp) >= 2000) + inv_gyro_was_turned_off(); + if (inv_delta_time_ms(current_time, sensors.accel.timestamp) >= 2000) + inv_accel_was_turned_off(); + if (inv_delta_time_ms(current_time, sensors.compass.timestamp) >= 2000) + inv_compass_was_turned_off(); + /* TODO: Temperature might not need to be read this quickly. */ + if (inv_delta_time_ms(current_time, sensors.temp.timestamp) >= 2000) + inv_temperature_was_turned_off(); +#endif + + /* clear bits */ + sensors.gyro.status &= ~INV_NEW_DATA; + sensors.accel.status &= ~INV_NEW_DATA; + sensors.compass.status &= ~INV_NEW_DATA; + sensors.temp.status &= ~INV_NEW_DATA; + sensors.quat.status &= ~INV_NEW_DATA; +} + +/** Gets a whole set of accel data including data, accuracy and timestamp. + * @param[out] data Accel Data where 1g = 2^16 + * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. + * @param[out] timestamp The timestamp of the data sample. +*/ +void inv_get_accel_set(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + if (data != NULL) { + memcpy(data, sensors.accel.calibrated, sizeof(sensors.accel.calibrated)); + } + if (timestamp != NULL) { + *timestamp = sensors.accel.timestamp; + } + if (accuracy != NULL) { + *accuracy = sensors.accel.accuracy; + } +} + +/** Gets a whole set of gyro data including data, accuracy and timestamp. + * @param[out] data Gyro Data where 1 dps = 2^16 + * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. + * @param[out] timestamp The timestamp of the data sample. +*/ +void inv_get_gyro_set(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + memcpy(data, sensors.gyro.calibrated, sizeof(sensors.gyro.calibrated)); + if (timestamp != NULL) { + *timestamp = sensors.gyro.timestamp; + } + if (accuracy != NULL) { + *accuracy = sensors.gyro.accuracy; + } +} + +/** Gets a whole set of gyro raw data including data, accuracy and timestamp. + * @param[out] data Gyro Data where 1 dps = 2^16 + * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. + * @param[out] timestamp The timestamp of the data sample. +*/ +void inv_get_gyro_set_raw(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + memcpy(data, sensors.gyro.raw_scaled, sizeof(sensors.gyro.raw_scaled)); + if (timestamp != NULL) { + *timestamp = sensors.gyro.timestamp; + } + if (accuracy != NULL) { + *accuracy = sensors.gyro.accuracy; + } +} + +/** Get's latest gyro data. +* @param[out] gyro Gyro Data, Length 3. 1 dps = 2^16. +*/ +void inv_get_gyro(long *gyro) +{ + memcpy(gyro, sensors.gyro.calibrated, sizeof(sensors.gyro.calibrated)); +} + +/** Gets a whole set of compass data including data, accuracy and timestamp. + * @param[out] data Compass Data where 1 uT = 2^16 + * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. + * @param[out] timestamp The timestamp of the data sample. +*/ +void inv_get_compass_set(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + memcpy(data, sensors.compass.calibrated, sizeof(sensors.compass.calibrated)); + if (timestamp != NULL) { + *timestamp = sensors.compass.timestamp; + } + if (accuracy != NULL) { + if (inv_data_builder.compass_disturbance) + *accuracy = 0; + else + *accuracy = sensors.compass.accuracy; + } +} + +/** Gets a whole set of temperature data including data, accuracy and timestamp. + * @param[out] data Temperature data where 1 degree C = 2^16 + * @param[out] accuracy 0 to 3, where 3 is most accurate. + * @param[out] timestamp The timestamp of the data sample. + */ +void inv_get_temp_set(long *data, int *accuracy, inv_time_t *timestamp) +{ + data[0] = sensors.temp.calibrated[0]; + if (timestamp) + *timestamp = sensors.temp.timestamp; + if (accuracy) + *accuracy = sensors.temp.accuracy; +} + +/** Returns accuracy of gyro. + * @return Accuracy of gyro with 0 being not accurate, and 3 being most accurate. +*/ +int inv_get_gyro_accuracy(void) +{ + return sensors.gyro.accuracy; +} + +/** Returns accuracy of compass. + * @return Accuracy of compass with 0 being not accurate, and 3 being most accurate. +*/ +int inv_get_mag_accuracy(void) +{ + if (inv_data_builder.compass_disturbance) + return 0; + return sensors.compass.accuracy; +} + +/** Returns accuracy of accel. + * @return Accuracy of accel with 0 being not accurate, and 3 being most accurate. +*/ +int inv_get_accel_accuracy(void) +{ + return sensors.accel.accuracy; +} + +inv_error_t inv_get_gyro_orient(int *orient) +{ + *orient = sensors.gyro.orientation; + return 0; +} + +inv_error_t inv_get_accel_orient(int *orient) +{ + *orient = sensors.accel.orientation; + return 0; +} + +/*======================================================================*/ +/* compass soft iron module */ +/*======================================================================*/ + +/** Gets the 3x3 compass transform matrix in 32 bit Q30 fixed point format. + * @param[out] the pointer of the 3x3 matrix in Q30 format +*/ +void inv_get_compass_soft_iron_matrix_d(long *matrix) { + int i; + for (i=0; i<9; i++) { + matrix[i] = sensors.soft_iron.matrix_d[i]; + } +} + +/** Sets the 3x3 compass transform matrix in 32 bit Q30 fixed point format. + * @param[in] the pointer of the 3x3 matrix in Q30 format +*/ +void inv_set_compass_soft_iron_matrix_d(long *matrix) { + int i; + for (i=0; i<9; i++) { + // set the floating point matrix + sensors.soft_iron.matrix_d[i] = matrix[i]; + // convert to Q30 format + sensors.soft_iron.matrix_f[i] = inv_q30_to_float(matrix[i]); + } +} +/** Gets the 3x3 compass transform matrix in 32 bit floating point format. + * @param[out] the pointer of the 3x3 matrix in floating point format +*/ +void inv_get_compass_soft_iron_matrix_f(float *matrix) { + int i; + for (i=0; i<9; i++) { + matrix[i] = sensors.soft_iron.matrix_f[i]; + } +} +/** Sets the 3x3 compass transform matrix in 32 bit floating point format. + * @param[in] the pointer of the 3x3 matrix in floating point format +*/ +void inv_set_compass_soft_iron_matrix_f(float *matrix) { + int i; + for (i=0; i<9; i++) { + // set the floating point matrix + sensors.soft_iron.matrix_f[i] = matrix[i]; + // convert to Q30 format + sensors.soft_iron.matrix_d[i] = (long )(matrix[i]*ROT_MATRIX_SCALE_LONG); + } +} + +/** This subroutine gets the fixed point Q30 compass data after the soft iron transformation. + * @param[out] the pointer of the 3x1 vector compass data in MPL format +*/ +void inv_get_compass_soft_iron_output_data(long *data) { + int i; + for (i=0; i<3; i++) { + data[i] = sensors.soft_iron.trans[i]; + } +} +/** This subroutine gets the fixed point Q30 compass data before the soft iron transformation. + * @param[out] the pointer of the 3x1 vector compass data in MPL format +*/ +void inv_get_compass_soft_iron_input_data(long *data) { + int i; + for (i=0; i<3; i++) { + data[i] = sensors.soft_iron.raw[i]; + } +} +/** This subroutine sets the compass raw data for the soft iron transformation. + * @param[int] the pointer of the 3x1 vector compass raw data in MPL format +*/ +void inv_set_compass_soft_iron_input_data(const long *data) { + int i; + for (i=0; i<3; i++) { + sensors.soft_iron.raw[i] = data[i]; + } + if (sensors.soft_iron.enable == 1) { + mlMatrixVectorMult(sensors.soft_iron.matrix_d, data, sensors.soft_iron.trans); + } else { + for (i=0; i<3; i++) { + sensors.soft_iron.trans[i] = data[i]; + } + } +} + +/** This subroutine resets the the soft iron transformation to unity matrix and + * disable the soft iron transformation process by default. +*/ +void inv_reset_compass_soft_iron_matrix(void) { + int i; + for (i=0; i<9; i++) { + sensors.soft_iron.matrix_f[i] = 0.0f; + } + + memset(&sensors.soft_iron.matrix_d,0,sizeof(sensors.soft_iron.matrix_d)); + + for (i=0; i<3; i++) { + // set the floating point matrix + sensors.soft_iron.matrix_f[i*4] = 1.0; + // set the fixed point matrix + sensors.soft_iron.matrix_d[i*4] = ROT_MATRIX_SCALE_LONG; + } + + inv_disable_compass_soft_iron_matrix(); +} + +/** This subroutine enables the the soft iron transformation process. +*/ +void inv_enable_compass_soft_iron_matrix(void) { + sensors.soft_iron.enable = 1; +} + +/** This subroutine disables the the soft iron transformation process. +*/ +void inv_disable_compass_soft_iron_matrix(void) { + sensors.soft_iron.enable = 0; +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/data_builder.h b/bsp/boards/mimsy2-cc2538/data_builder.h new file mode 100644 index 0000000000..4c22767fd0 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/data_builder.h @@ -0,0 +1,259 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" + +#ifndef INV_DATA_BUILDER_H__ +#define INV_DATA_BUILDER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +// Uncomment this flag to enable playback debug and record or playback scenarios +//#define INV_PLAYBACK_DBG + +/** This is a new sample of accel data */ +#define INV_ACCEL_NEW 1 +/** This is a new sample of gyro data */ +#define INV_GYRO_NEW 2 +/** This is a new sample of compass data */ +#define INV_MAG_NEW 4 +/** This is a new sample of temperature data */ +#define INV_TEMP_NEW 8 +/** This is a new sample of quaternion data */ +#define INV_QUAT_NEW 16 + +/** Set if the data is contiguous. Typically not set if a sample was skipped */ +#define INV_CONTIGUOUS 16 +/** Set if the calibrated data has been solved for */ +#define INV_CALIBRATED 32 +/* INV_NEW_DATA set for a new set of data, cleared if not available. */ +#define INV_NEW_DATA 64 +/* Set if raw data exists */ +#define INV_RAW_DATA 128 +/* Set if the sensor is on */ +#define INV_SENSOR_ON 256 +/* Set if quaternion has bias correction applied */ +#define INV_BIAS_APPLIED 512 + +#define INV_PRIORITY_MOTION_NO_MOTION 100 +#define INV_PRIORITY_GYRO_TC 150 +#define INV_PRIORITY_QUATERNION_GYRO_ACCEL 200 +#define INV_PRIORITY_QUATERNION_NO_GYRO 250 +#define INV_PRIORITY_MAGNETIC_DISTURBANCE 300 +#define INV_PRIORITY_HEADING_FROM_GYRO 350 +#define INV_PRIORITY_COMPASS_BIAS_W_GYRO 375 +#define INV_PRIORITY_COMPASS_VECTOR_CAL 400 +#define INV_PRIORITY_COMPASS_ADV_BIAS 500 +#define INV_PRIORITY_9_AXIS_FUSION 600 +#define INV_PRIORITY_QUATERNION_ADJUST_9_AXIS 700 +#define INV_PRIORITY_QUATERNION_ACCURACY 750 +#define INV_PRIORITY_RESULTS_HOLDER 800 +#define INV_PRIORITY_INUSE_AUTO_CALIBRATION 850 +#define INV_PRIORITY_HAL_OUTPUTS 900 +#define INV_PRIORITY_GLYPH 950 +#define INV_PRIORITY_SHAKE 975 +#define INV_PRIORITY_SM 1000 + +struct inv_single_sensor_t { + /** Orientation Descriptor. Describes how to go from the mounting frame to the body frame when + * the rotation matrix could be thought of only having elements of 0,1,-1. + * 2 bits are used to describe the column of the 1 or -1 and the 3rd bit is used for the sign. + * Bit 8 is sign of +/- 1 in third row. Bit 6-7 is column of +/-1 in third row. + * Bit 5 is sign of +/- 1 in second row. Bit 3-4 is column of +/-1 in second row. + * Bit 2 is sign of +/- 1 in first row. Bit 0-1 is column of +/-1 in first row. + */ + int orientation; + /** The raw data in raw data units in the mounting frame */ + short raw[3]; + /** Raw data in body frame */ + long raw_scaled[3]; + /** Calibrated data */ + long calibrated[3]; + long sensitivity; + /** Sample rate in microseconds */ + long sample_rate_us; + long sample_rate_ms; + /** INV_CONTIGUOUS is set for contiguous data. Will not be set if there was a sample + * skipped due to power savings turning off this sensor. + * INV_NEW_DATA set for a new set of data, cleared if not available. + * INV_CALIBRATED_SET if calibrated data has been solved for */ + int status; + /** 0 to 3 for how well sensor data and biases are known. 3 is most accurate. */ + int accuracy; + inv_time_t timestamp; + inv_time_t timestamp_prev; + /** Bandwidth in Hz */ + int bandwidth; +}; +struct inv_quat_sensor_t { + long raw[4]; + /** INV_CONTIGUOUS is set for contiguous data. Will not be set if there was a sample + * skipped due to power savings turning off this sensor. + * INV_NEW_DATA set for a new set of data, cleared if not available. + * INV_CALIBRATED_SET if calibrated data has been solved for */ + int status; + inv_time_t timestamp; + long sample_rate_us; + long sample_rate_ms; +}; + +struct inv_soft_iron_t { + long raw[3]; + long trans[3]; + long matrix_d[9]; // Q30 format fixed point. The dynamic range is (-2.0 to 2.0); + float matrix_f[9]; + + int enable; +}; + +struct inv_sensor_cal_t { + struct inv_single_sensor_t gyro; + struct inv_single_sensor_t accel; + struct inv_single_sensor_t compass; + struct inv_single_sensor_t temp; + struct inv_quat_sensor_t quat; + struct inv_soft_iron_t soft_iron; + /** Combinations of INV_GYRO_NEW, INV_ACCEL_NEW, INV_MAG_NEW to indicate + * which data is a new sample as these data points may have different sample rates. + */ + int status; +}; + +// Useful for debug record and playback +typedef enum { + RD_NO_DEBUG, + RD_RECORD, + RD_PLAYBACK +} rd_dbg_mode; + +typedef enum { + PLAYBACK_DBG_TYPE_GYRO, + PLAYBACK_DBG_TYPE_ACCEL, + PLAYBACK_DBG_TYPE_COMPASS, + PLAYBACK_DBG_TYPE_TEMPERATURE, + PLAYBACK_DBG_TYPE_EXECUTE, + PLAYBACK_DBG_TYPE_A_ORIENT, + PLAYBACK_DBG_TYPE_G_ORIENT, + PLAYBACK_DBG_TYPE_C_ORIENT, + PLAYBACK_DBG_TYPE_A_SAMPLE_RATE, + PLAYBACK_DBG_TYPE_C_SAMPLE_RATE, + PLAYBACK_DBG_TYPE_G_SAMPLE_RATE, + PLAYBACK_DBG_TYPE_GYRO_OFF, + PLAYBACK_DBG_TYPE_ACCEL_OFF, + PLAYBACK_DBG_TYPE_COMPASS_OFF, + PLAYBACK_DBG_TYPE_Q_SAMPLE_RATE, + PLAYBACK_DBG_TYPE_QUAT + +} inv_rd_dbg_states; + +/** Maximum number of data callbacks that are supported. Safe to increase if needed.*/ +#define INV_MAX_DATA_CB 20 + +#ifdef INV_PLAYBACK_DBG +#include +void inv_turn_on_data_logging(FILE *file); +void inv_turn_off_data_logging(); +#endif + +void inv_set_gyro_orientation_and_scale(int orientation, long sensitivity); +void inv_set_accel_orientation_and_scale(int orientation, + long sensitivity); +void inv_set_compass_orientation_and_scale(int orientation, + long sensitivity); +void inv_set_gyro_sample_rate(long sample_rate_us); +void inv_set_compass_sample_rate(long sample_rate_us); +void inv_set_quat_sample_rate(long sample_rate_us); +void inv_set_accel_sample_rate(long sample_rate_us); +void inv_set_gyro_bandwidth(int bandwidth_hz); +void inv_set_accel_bandwidth(int bandwidth_hz); +void inv_set_compass_bandwidth(int bandwidth_hz); + +void inv_get_gyro_sample_rate_ms(long *sample_rate_ms); +void inv_get_accel_sample_rate_ms(long *sample_rate_ms); +void inv_get_compass_sample_rate_ms(long *sample_rate_ms); + +inv_error_t inv_register_data_cb(inv_error_t (*func) + (struct inv_sensor_cal_t * data), int priority, + int sensor_type); +inv_error_t inv_unregister_data_cb(inv_error_t (*func) + (struct inv_sensor_cal_t * data)); + +inv_error_t inv_build_gyro(const short *gyro, inv_time_t timestamp); +inv_error_t inv_build_compass(const long *compass, int status, + inv_time_t timestamp); +inv_error_t inv_build_accel(const long *accel, int status, + inv_time_t timestamp); +inv_error_t inv_build_temp(const long temp, inv_time_t timestamp); +inv_error_t inv_build_quat(const long *quat, int status, inv_time_t timestamp); +inv_error_t inv_execute_on_data(void); + +void inv_get_compass_bias(long *bias); + +void inv_set_compass_bias(const long *bias, int accuracy); +void inv_set_compass_disturbance(int dist); +void inv_set_gyro_bias(const long *bias, int accuracy); +void inv_set_accel_bias(const long *bias, int accuracy); +void inv_set_accel_accuracy(int accuracy); +void inv_set_accel_bias_mask(const long *bias, int accuracy, int mask); + +void inv_get_compass_soft_iron_matrix_d(long *matrix); +void inv_set_compass_soft_iron_matrix_d(long *matrix); + +void inv_get_compass_soft_iron_matrix_f(float *matrix); +void inv_set_compass_soft_iron_matrix_f(float *matrix); + +void inv_get_compass_soft_iron_output_data(long *data); +void inv_get_compass_soft_iron_input_data(long *data); +void inv_set_compass_soft_iron_input_data(const long *data); + +void inv_reset_compass_soft_iron_matrix(void); +void inv_enable_compass_soft_iron_matrix(void); +void inv_disable_compass_soft_iron_matrix(void); + +void inv_get_gyro_bias(long *bias, long *temp); +void inv_get_accel_bias(long *bias, long *temp); + +void inv_gyro_was_turned_off(void); +void inv_accel_was_turned_off(void); +void inv_compass_was_turned_off(void); +void inv_quaternion_sensor_was_turned_off(void); +inv_error_t inv_init_data_builder(void); +long inv_get_gyro_sensitivity(void); +long inv_get_accel_sensitivity(void); +long inv_get_compass_sensitivity(void); + +void inv_get_accel_set(long *data, int8_t *accuracy, inv_time_t * timestamp); +void inv_get_gyro_set(long *data, int8_t *accuracy, inv_time_t * timestamp); +void inv_get_gyro_set_raw(long *data, int8_t *accuracy, inv_time_t * timestamp); +void inv_get_compass_set(long *data, int8_t *accuracy, inv_time_t * timestamp); + +void inv_get_gyro(long *gyro); + +int inv_get_gyro_accuracy(void); +int inv_get_accel_accuracy(void); +int inv_get_mag_accuracy(void); + +int inv_get_compass_on(void); +int inv_get_gyro_on(void); +int inv_get_accel_on(void); + +inv_time_t inv_get_last_timestamp(void); +int inv_get_compass_disturbance(void); + +//New DMP Cal Functions +inv_error_t inv_get_gyro_orient(int *orient); +inv_error_t inv_get_accel_orient(int *orient); + +// internal +int inv_get_gyro_bias_tc_set(void); + +#ifdef __cplusplus +} +#endif + +#endif /* INV_DATA_BUILDER_H__ */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/debugpins.c b/bsp/boards/mimsy2-cc2538/debugpins.c new file mode 100644 index 0000000000..2ef9e544e0 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/debugpins.c @@ -0,0 +1,135 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "debugpins" bsp module. + */ + +#include +#include + +#include + +#include "board.h" +#include "debugpins.h" + +//=========================== defines ========================================= +// Board dbPINS defines +#define BSP_PINA_BASE GPIO_A_BASE +#define BSP_PIND_BASE GPIO_D_BASE +#define BSP_PINC_BASE GPIO_C_BASE + +#define BSP_PINA_4 GPIO_PIN_4 //!< PA4 -- frame -RF1.5 +#define BSP_PINA_5 GPIO_PIN_5 //!< PA5 -- isr -RF1.11 + +#define BSP_PIND_3 GPIO_PIN_3 //!< PD3 -- slot -RF1.6 +#define BSP_PIND_2 GPIO_PIN_2 //!< PD2 -- fsm -RF1.8 +#define BSP_PIND_1 GPIO_PIN_1 //!< PD1 -- task -RF1.10 +#define BSP_PIND_0 GPIO_PIN_0 //!< PD0 -- radio -RF1-12 + +#define BSP_PINC_5 GPIO_PIN_5 //!< PD3 -- slot -RF1.6 +#define BSP_PINC_3 GPIO_PIN_3 //!< PD2 -- fsm -RF1.8 +#define BSP_PINC_2 GPIO_PIN_2 //!< PD1 -- task -RF1.10 +#define BSP_PINC_1 GPIO_PIN_1 //!< PD0 -- radio -RF1-12 + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +void bspDBpinToggle(uint32_t base,uint8_t ui8Pin); + +//=========================== public ========================================== + +void debugpins_init() { + GPIOPinTypeGPIOOutput(BSP_PINA_BASE, BSP_PINA_4 | BSP_PINA_5); + GPIOPinTypeGPIOOutput(BSP_PINC_BASE, BSP_PINC_3 | BSP_PINC_2 | BSP_PINC_1 | BSP_PINC_5); + + GPIOPinWrite(BSP_PINA_BASE, (BSP_PINA_4 | BSP_PINA_5), 0x00); + GPIOPinWrite(BSP_PINC_BASE, (BSP_PINC_3 | BSP_PINC_2 | BSP_PINC_1 | BSP_PINC_5), 0); +} + +// PA4 +void debugpins_frame_toggle() { + bspDBpinToggle(BSP_PINA_BASE, BSP_PINA_4); +} +void debugpins_frame_clr() { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_4, 0); +} +void debugpins_frame_set() { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_4, BSP_PINA_4); +} + +// PD3 +void debugpins_slot_toggle() { + bspDBpinToggle(BSP_PINC_BASE, BSP_PINC_3); +} +void debugpins_slot_clr() { + GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_3, 0); +} +void debugpins_slot_set() { + GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_3, BSP_PINC_3); +} + +// PD2 +void debugpins_fsm_toggle() { + bspDBpinToggle(BSP_PINC_BASE, BSP_PINC_2); +} +void debugpins_fsm_clr() { + GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_2, 0); +} +void debugpins_fsm_set() { + GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_2, BSP_PINC_2); +} + +// PD1 +void debugpins_task_toggle() { + bspDBpinToggle(BSP_PINC_BASE,BSP_PINC_1); +} +void debugpins_task_clr() { + GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_1, 0); +} +void debugpins_task_set() { + GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_1, BSP_PINC_1); +} + +// PA5 +void debugpins_isr_toggle() { + bspDBpinToggle(BSP_PINA_BASE, BSP_PINA_5); +} +void debugpins_isr_clr() { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_5, 0); +} +void debugpins_isr_set() { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_5, BSP_PINA_5); +} + +// PD0 +void debugpins_radio_toggle() { + bspDBpinToggle(BSP_PINC_BASE, BSP_PINC_5); +} +void debugpins_radio_clr() { + GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_5, 0); +} +void debugpins_radio_set() { + GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_5, BSP_PINC_5); +} + +//------------ private ------------// + +void bspDBpinToggle(uint32_t base, uint8_t ui8Pin) +{ + // + // Get current pin values of selected bits + // + uint32_t ui32Toggle = GPIOPinRead(base, ui8Pin); + + // + // Invert selected bits + // + ui32Toggle = (~ui32Toggle) & ui8Pin; + + // + // Set GPIO + // + GPIOPinWrite(base, ui8Pin, ui32Toggle); +} diff --git a/bsp/boards/mimsy2-cc2538/dmpKey.h b/bsp/boards/mimsy2-cc2538/dmpKey.h new file mode 100644 index 0000000000..c8f62a2aff --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/dmpKey.h @@ -0,0 +1,494 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +#ifndef DMPKEY_H__ +#define DMPKEY_H__ + +#define KEY_CFG_25 (0) +#define KEY_CFG_24 (KEY_CFG_25 + 1) +#define KEY_CFG_26 (KEY_CFG_24 + 1) +#define KEY_CFG_27 (KEY_CFG_26 + 1) +#define KEY_CFG_21 (KEY_CFG_27 + 1) +#define KEY_CFG_20 (KEY_CFG_21 + 1) +#define KEY_CFG_TAP4 (KEY_CFG_20 + 1) +#define KEY_CFG_TAP5 (KEY_CFG_TAP4 + 1) +#define KEY_CFG_TAP6 (KEY_CFG_TAP5 + 1) +#define KEY_CFG_TAP7 (KEY_CFG_TAP6 + 1) +#define KEY_CFG_TAP0 (KEY_CFG_TAP7 + 1) +#define KEY_CFG_TAP1 (KEY_CFG_TAP0 + 1) +#define KEY_CFG_TAP2 (KEY_CFG_TAP1 + 1) +#define KEY_CFG_TAP3 (KEY_CFG_TAP2 + 1) +#define KEY_CFG_TAP_QUANTIZE (KEY_CFG_TAP3 + 1) +#define KEY_CFG_TAP_JERK (KEY_CFG_TAP_QUANTIZE + 1) +#define KEY_CFG_DR_INT (KEY_CFG_TAP_JERK + 1) +#define KEY_CFG_AUTH (KEY_CFG_DR_INT + 1) +#define KEY_CFG_TAP_SAVE_ACCB (KEY_CFG_AUTH + 1) +#define KEY_CFG_TAP_CLEAR_STICKY (KEY_CFG_TAP_SAVE_ACCB + 1) +#define KEY_CFG_FIFO_ON_EVENT (KEY_CFG_TAP_CLEAR_STICKY + 1) +#define KEY_FCFG_ACCEL_INPUT (KEY_CFG_FIFO_ON_EVENT + 1) +#define KEY_FCFG_ACCEL_INIT (KEY_FCFG_ACCEL_INPUT + 1) +#define KEY_CFG_23 (KEY_FCFG_ACCEL_INIT + 1) +#define KEY_FCFG_1 (KEY_CFG_23 + 1) +#define KEY_FCFG_3 (KEY_FCFG_1 + 1) +#define KEY_FCFG_2 (KEY_FCFG_3 + 1) +#define KEY_CFG_3D (KEY_FCFG_2 + 1) +#define KEY_CFG_3B (KEY_CFG_3D + 1) +#define KEY_CFG_3C (KEY_CFG_3B + 1) +#define KEY_FCFG_5 (KEY_CFG_3C + 1) +#define KEY_FCFG_4 (KEY_FCFG_5 + 1) +#define KEY_FCFG_7 (KEY_FCFG_4 + 1) +#define KEY_FCFG_FSCALE (KEY_FCFG_7 + 1) +#define KEY_FCFG_AZ (KEY_FCFG_FSCALE + 1) +#define KEY_FCFG_6 (KEY_FCFG_AZ + 1) +#define KEY_FCFG_LSB4 (KEY_FCFG_6 + 1) +#define KEY_CFG_12 (KEY_FCFG_LSB4 + 1) +#define KEY_CFG_14 (KEY_CFG_12 + 1) +#define KEY_CFG_15 (KEY_CFG_14 + 1) +#define KEY_CFG_16 (KEY_CFG_15 + 1) +#define KEY_CFG_18 (KEY_CFG_16 + 1) +#define KEY_CFG_6 (KEY_CFG_18 + 1) +#define KEY_CFG_7 (KEY_CFG_6 + 1) +#define KEY_CFG_4 (KEY_CFG_7 + 1) +#define KEY_CFG_5 (KEY_CFG_4 + 1) +#define KEY_CFG_2 (KEY_CFG_5 + 1) +#define KEY_CFG_3 (KEY_CFG_2 + 1) +#define KEY_CFG_1 (KEY_CFG_3 + 1) +#define KEY_CFG_EXTERNAL (KEY_CFG_1 + 1) +#define KEY_CFG_8 (KEY_CFG_EXTERNAL + 1) +#define KEY_CFG_9 (KEY_CFG_8 + 1) +#define KEY_CFG_ORIENT_3 (KEY_CFG_9 + 1) +#define KEY_CFG_ORIENT_2 (KEY_CFG_ORIENT_3 + 1) +#define KEY_CFG_ORIENT_1 (KEY_CFG_ORIENT_2 + 1) +#define KEY_CFG_GYRO_SOURCE (KEY_CFG_ORIENT_1 + 1) +#define KEY_CFG_ORIENT_IRQ_1 (KEY_CFG_GYRO_SOURCE + 1) +#define KEY_CFG_ORIENT_IRQ_2 (KEY_CFG_ORIENT_IRQ_1 + 1) +#define KEY_CFG_ORIENT_IRQ_3 (KEY_CFG_ORIENT_IRQ_2 + 1) +#define KEY_FCFG_MAG_VAL (KEY_CFG_ORIENT_IRQ_3 + 1) +#define KEY_FCFG_MAG_MOV (KEY_FCFG_MAG_VAL + 1) +#define KEY_CFG_LP_QUAT (KEY_FCFG_MAG_MOV + 1) + +/* MPU6050 keys */ +#define KEY_CFG_ACCEL_FILTER (KEY_CFG_LP_QUAT + 1) +#define KEY_CFG_MOTION_BIAS (KEY_CFG_ACCEL_FILTER + 1) +#define KEY_TEMPLABEL (KEY_CFG_MOTION_BIAS + 1) + +#define KEY_D_0_22 (KEY_TEMPLABEL + 1) +#define KEY_D_0_24 (KEY_D_0_22 + 1) +#define KEY_D_0_36 (KEY_D_0_24 + 1) +#define KEY_D_0_52 (KEY_D_0_36 + 1) +#define KEY_D_0_96 (KEY_D_0_52 + 1) +#define KEY_D_0_104 (KEY_D_0_96 + 1) +#define KEY_D_0_108 (KEY_D_0_104 + 1) +#define KEY_D_0_163 (KEY_D_0_108 + 1) +#define KEY_D_0_188 (KEY_D_0_163 + 1) +#define KEY_D_0_192 (KEY_D_0_188 + 1) +#define KEY_D_0_224 (KEY_D_0_192 + 1) +#define KEY_D_0_228 (KEY_D_0_224 + 1) +#define KEY_D_0_232 (KEY_D_0_228 + 1) +#define KEY_D_0_236 (KEY_D_0_232 + 1) + +#define KEY_DMP_PREVPTAT (KEY_D_0_236 + 1) +#define KEY_D_1_2 (KEY_DMP_PREVPTAT + 1) +#define KEY_D_1_4 (KEY_D_1_2 + 1) +#define KEY_D_1_8 (KEY_D_1_4 + 1) +#define KEY_D_1_10 (KEY_D_1_8 + 1) +#define KEY_D_1_24 (KEY_D_1_10 + 1) +#define KEY_D_1_28 (KEY_D_1_24 + 1) +#define KEY_D_1_36 (KEY_D_1_28 + 1) +#define KEY_D_1_40 (KEY_D_1_36 + 1) +#define KEY_D_1_44 (KEY_D_1_40 + 1) +#define KEY_D_1_72 (KEY_D_1_44 + 1) +#define KEY_D_1_74 (KEY_D_1_72 + 1) +#define KEY_D_1_79 (KEY_D_1_74 + 1) +#define KEY_D_1_88 (KEY_D_1_79 + 1) +#define KEY_D_1_90 (KEY_D_1_88 + 1) +#define KEY_D_1_92 (KEY_D_1_90 + 1) +#define KEY_D_1_96 (KEY_D_1_92 + 1) +#define KEY_D_1_98 (KEY_D_1_96 + 1) +#define KEY_D_1_100 (KEY_D_1_98 + 1) +#define KEY_D_1_106 (KEY_D_1_100 + 1) +#define KEY_D_1_108 (KEY_D_1_106 + 1) +#define KEY_D_1_112 (KEY_D_1_108 + 1) +#define KEY_D_1_128 (KEY_D_1_112 + 1) +#define KEY_D_1_152 (KEY_D_1_128 + 1) +#define KEY_D_1_160 (KEY_D_1_152 + 1) +#define KEY_D_1_168 (KEY_D_1_160 + 1) +#define KEY_D_1_175 (KEY_D_1_168 + 1) +#define KEY_D_1_176 (KEY_D_1_175 + 1) +#define KEY_D_1_178 (KEY_D_1_176 + 1) +#define KEY_D_1_179 (KEY_D_1_178 + 1) +#define KEY_D_1_218 (KEY_D_1_179 + 1) +#define KEY_D_1_232 (KEY_D_1_218 + 1) +#define KEY_D_1_236 (KEY_D_1_232 + 1) +#define KEY_D_1_240 (KEY_D_1_236 + 1) +#define KEY_D_1_244 (KEY_D_1_240 + 1) +#define KEY_D_1_250 (KEY_D_1_244 + 1) +#define KEY_D_1_252 (KEY_D_1_250 + 1) +#define KEY_D_2_12 (KEY_D_1_252 + 1) +#define KEY_D_2_96 (KEY_D_2_12 + 1) +#define KEY_D_2_108 (KEY_D_2_96 + 1) +#define KEY_D_2_208 (KEY_D_2_108 + 1) +#define KEY_FLICK_MSG (KEY_D_2_208 + 1) +#define KEY_FLICK_COUNTER (KEY_FLICK_MSG + 1) +#define KEY_FLICK_LOWER (KEY_FLICK_COUNTER + 1) +#define KEY_CFG_FLICK_IN (KEY_FLICK_LOWER + 1) +#define KEY_FLICK_UPPER (KEY_CFG_FLICK_IN + 1) +#define KEY_CGNOTICE_INTR (KEY_FLICK_UPPER + 1) +#define KEY_D_2_224 (KEY_CGNOTICE_INTR + 1) +#define KEY_D_2_244 (KEY_D_2_224 + 1) +#define KEY_D_2_248 (KEY_D_2_244 + 1) +#define KEY_D_2_252 (KEY_D_2_248 + 1) + +#define KEY_D_GYRO_BIAS_X (KEY_D_2_252 + 1) +#define KEY_D_GYRO_BIAS_Y (KEY_D_GYRO_BIAS_X + 1) +#define KEY_D_GYRO_BIAS_Z (KEY_D_GYRO_BIAS_Y + 1) +#define KEY_D_ACC_BIAS_X (KEY_D_GYRO_BIAS_Z + 1) +#define KEY_D_ACC_BIAS_Y (KEY_D_ACC_BIAS_X + 1) +#define KEY_D_ACC_BIAS_Z (KEY_D_ACC_BIAS_Y + 1) +#define KEY_D_GYRO_ENABLE (KEY_D_ACC_BIAS_Z + 1) +#define KEY_D_ACCEL_ENABLE (KEY_D_GYRO_ENABLE + 1) +#define KEY_D_QUAT_ENABLE (KEY_D_ACCEL_ENABLE +1) +#define KEY_D_OUTPUT_ENABLE (KEY_D_QUAT_ENABLE + 1) +#define KEY_D_CR_TIME_G (KEY_D_OUTPUT_ENABLE + 1) +#define KEY_D_CR_TIME_A (KEY_D_CR_TIME_G + 1) +#define KEY_D_CR_TIME_Q (KEY_D_CR_TIME_A + 1) +#define KEY_D_CS_TAX (KEY_D_CR_TIME_Q + 1) +#define KEY_D_CS_TAY (KEY_D_CS_TAX + 1) +#define KEY_D_CS_TAZ (KEY_D_CS_TAY + 1) +#define KEY_D_CS_TGX (KEY_D_CS_TAZ + 1) +#define KEY_D_CS_TGY (KEY_D_CS_TGX + 1) +#define KEY_D_CS_TGZ (KEY_D_CS_TGY + 1) +#define KEY_D_CS_TQ0 (KEY_D_CS_TGZ + 1) +#define KEY_D_CS_TQ1 (KEY_D_CS_TQ0 + 1) +#define KEY_D_CS_TQ2 (KEY_D_CS_TQ1 + 1) +#define KEY_D_CS_TQ3 (KEY_D_CS_TQ2 + 1) + +/* Compass keys */ +#define KEY_CPASS_BIAS_X (KEY_D_CS_TQ3 + 1) +#define KEY_CPASS_BIAS_Y (KEY_CPASS_BIAS_X + 1) +#define KEY_CPASS_BIAS_Z (KEY_CPASS_BIAS_Y + 1) +#define KEY_CPASS_MTX_00 (KEY_CPASS_BIAS_Z + 1) +#define KEY_CPASS_MTX_01 (KEY_CPASS_MTX_00 + 1) +#define KEY_CPASS_MTX_02 (KEY_CPASS_MTX_01 + 1) +#define KEY_CPASS_MTX_10 (KEY_CPASS_MTX_02 + 1) +#define KEY_CPASS_MTX_11 (KEY_CPASS_MTX_10 + 1) +#define KEY_CPASS_MTX_12 (KEY_CPASS_MTX_11 + 1) +#define KEY_CPASS_MTX_20 (KEY_CPASS_MTX_12 + 1) +#define KEY_CPASS_MTX_21 (KEY_CPASS_MTX_20 + 1) +#define KEY_CPASS_MTX_22 (KEY_CPASS_MTX_21 + 1) + +/* Gesture Keys */ +#define KEY_DMP_TAPW_MIN (KEY_CPASS_MTX_22 + 1) +#define KEY_DMP_TAP_THR_X (KEY_DMP_TAPW_MIN + 1) +#define KEY_DMP_TAP_THR_Y (KEY_DMP_TAP_THR_X + 1) +#define KEY_DMP_TAP_THR_Z (KEY_DMP_TAP_THR_Y + 1) +#define KEY_DMP_SH_TH_Y (KEY_DMP_TAP_THR_Z + 1) +#define KEY_DMP_SH_TH_X (KEY_DMP_SH_TH_Y + 1) +#define KEY_DMP_SH_TH_Z (KEY_DMP_SH_TH_X + 1) +#define KEY_DMP_ORIENT (KEY_DMP_SH_TH_Z + 1) +#define KEY_D_ACT0 (KEY_DMP_ORIENT + 1) +#define KEY_D_ACSX (KEY_D_ACT0 + 1) +#define KEY_D_ACSY (KEY_D_ACSX + 1) +#define KEY_D_ACSZ (KEY_D_ACSY + 1) + +#define KEY_X_GRT_Y_TMP (KEY_D_ACSZ + 1) +#define KEY_SKIP_X_GRT_Y_TMP (KEY_X_GRT_Y_TMP + 1) +#define KEY_SKIP_END_COMPARE (KEY_SKIP_X_GRT_Y_TMP + 1) +#define KEY_END_COMPARE_Y_X_TMP2 (KEY_SKIP_END_COMPARE + 1) +#define KEY_CFG_ANDROID_ORIENT_INT (KEY_END_COMPARE_Y_X_TMP2 + 1) +#define KEY_NO_ORIENT_INTERRUPT (KEY_CFG_ANDROID_ORIENT_INT + 1) +#define KEY_END_COMPARE_Y_X_TMP (KEY_NO_ORIENT_INTERRUPT + 1) +#define KEY_END_ORIENT_1 (KEY_END_COMPARE_Y_X_TMP + 1) +#define KEY_END_COMPARE_Y_X (KEY_END_ORIENT_1 + 1) +#define KEY_END_ORIENT (KEY_END_COMPARE_Y_X + 1) +#define KEY_X_GRT_Y (KEY_END_ORIENT + 1) +#define KEY_NOT_TIME_MINUS_1 (KEY_X_GRT_Y + 1) +#define KEY_END_COMPARE_Y_X_TMP3 (KEY_NOT_TIME_MINUS_1 + 1) +#define KEY_X_GRT_Y_TMP2 (KEY_END_COMPARE_Y_X_TMP3 + 1) + +/* Authenticate Keys */ +#define KEY_D_AUTH_OUT (KEY_X_GRT_Y_TMP2 + 1) +#define KEY_D_AUTH_IN (KEY_D_AUTH_OUT + 1) +#define KEY_D_AUTH_A (KEY_D_AUTH_IN + 1) +#define KEY_D_AUTH_B (KEY_D_AUTH_A + 1) + +/* Pedometer standalone only keys */ +#define KEY_D_PEDSTD_BP_B (KEY_D_AUTH_B + 1) +#define KEY_D_PEDSTD_HP_A (KEY_D_PEDSTD_BP_B + 1) +#define KEY_D_PEDSTD_HP_B (KEY_D_PEDSTD_HP_A + 1) +#define KEY_D_PEDSTD_BP_A4 (KEY_D_PEDSTD_HP_B + 1) +#define KEY_D_PEDSTD_BP_A3 (KEY_D_PEDSTD_BP_A4 + 1) +#define KEY_D_PEDSTD_BP_A2 (KEY_D_PEDSTD_BP_A3 + 1) +#define KEY_D_PEDSTD_BP_A1 (KEY_D_PEDSTD_BP_A2 + 1) +#define KEY_D_PEDSTD_INT_THRSH (KEY_D_PEDSTD_BP_A1 + 1) +#define KEY_D_PEDSTD_CLIP (KEY_D_PEDSTD_INT_THRSH + 1) +#define KEY_D_PEDSTD_SB (KEY_D_PEDSTD_CLIP + 1) +#define KEY_D_PEDSTD_SB_TIME (KEY_D_PEDSTD_SB + 1) +#define KEY_D_PEDSTD_PEAKTHRSH (KEY_D_PEDSTD_SB_TIME + 1) +#define KEY_D_PEDSTD_TIML (KEY_D_PEDSTD_PEAKTHRSH + 1) +#define KEY_D_PEDSTD_TIMH (KEY_D_PEDSTD_TIML + 1) +#define KEY_D_PEDSTD_PEAK (KEY_D_PEDSTD_TIMH + 1) +#define KEY_D_PEDSTD_TIMECTR (KEY_D_PEDSTD_PEAK + 1) +#define KEY_D_PEDSTD_STEPCTR (KEY_D_PEDSTD_TIMECTR + 1) +#define KEY_D_PEDSTD_WALKTIME (KEY_D_PEDSTD_STEPCTR + 1) +#define KEY_D_PEDSTD_DECI (KEY_D_PEDSTD_WALKTIME + 1) + +/*Host Based No Motion*/ +#define KEY_D_HOST_NO_MOT (KEY_D_PEDSTD_DECI + 1) + +/* EIS keys */ +#define KEY_P_EIS_FIFO_FOOTER (KEY_D_HOST_NO_MOT + 1) +#define KEY_P_EIS_FIFO_YSHIFT (KEY_P_EIS_FIFO_FOOTER + 1) +#define KEY_P_EIS_DATA_RATE (KEY_P_EIS_FIFO_YSHIFT + 1) +#define KEY_P_EIS_FIFO_XSHIFT (KEY_P_EIS_DATA_RATE + 1) +#define KEY_P_EIS_FIFO_SYNC (KEY_P_EIS_FIFO_XSHIFT + 1) +#define KEY_P_EIS_FIFO_ZSHIFT (KEY_P_EIS_FIFO_SYNC + 1) +#define KEY_P_EIS_FIFO_READY (KEY_P_EIS_FIFO_ZSHIFT + 1) +#define KEY_DMP_FOOTER (KEY_P_EIS_FIFO_READY + 1) +#define KEY_DMP_INTX_HC (KEY_DMP_FOOTER + 1) +#define KEY_DMP_INTX_PH (KEY_DMP_INTX_HC + 1) +#define KEY_DMP_INTX_SH (KEY_DMP_INTX_PH + 1) +#define KEY_DMP_AINV_SH (KEY_DMP_INTX_SH + 1) +#define KEY_DMP_A_INV_XH (KEY_DMP_AINV_SH + 1) +#define KEY_DMP_AINV_PH (KEY_DMP_A_INV_XH + 1) +#define KEY_DMP_CTHX_H (KEY_DMP_AINV_PH + 1) +#define KEY_DMP_CTHY_H (KEY_DMP_CTHX_H + 1) +#define KEY_DMP_CTHZ_H (KEY_DMP_CTHY_H + 1) +#define KEY_DMP_NCTHX_H (KEY_DMP_CTHZ_H + 1) +#define KEY_DMP_NCTHY_H (KEY_DMP_NCTHX_H + 1) +#define KEY_DMP_NCTHZ_H (KEY_DMP_NCTHY_H + 1) +#define KEY_DMP_CTSQ_XH (KEY_DMP_NCTHZ_H + 1) +#define KEY_DMP_CTSQ_YH (KEY_DMP_CTSQ_XH + 1) +#define KEY_DMP_CTSQ_ZH (KEY_DMP_CTSQ_YH + 1) +#define KEY_DMP_INTX_H (KEY_DMP_CTSQ_ZH + 1) +#define KEY_DMP_INTY_H (KEY_DMP_INTX_H + 1) +#define KEY_DMP_INTZ_H (KEY_DMP_INTY_H + 1) +//#define KEY_DMP_HPX_H (KEY_DMP_INTZ_H + 1) +//#define KEY_DMP_HPY_H (KEY_DMP_HPX_H + 1) +//#define KEY_DMP_HPZ_H (KEY_DMP_HPY_H + 1) + +/* Stream keys */ +#define KEY_STREAM_P_GYRO_Z (KEY_DMP_INTZ_H + 1) +#define KEY_STREAM_P_GYRO_Y (KEY_STREAM_P_GYRO_Z + 1) +#define KEY_STREAM_P_GYRO_X (KEY_STREAM_P_GYRO_Y + 1) +#define KEY_STREAM_P_TEMP (KEY_STREAM_P_GYRO_X + 1) +#define KEY_STREAM_P_AUX_Y (KEY_STREAM_P_TEMP + 1) +#define KEY_STREAM_P_AUX_X (KEY_STREAM_P_AUX_Y + 1) +#define KEY_STREAM_P_AUX_Z (KEY_STREAM_P_AUX_X + 1) +#define KEY_STREAM_P_ACCEL_Y (KEY_STREAM_P_AUX_Z + 1) +#define KEY_STREAM_P_ACCEL_X (KEY_STREAM_P_ACCEL_Y + 1) +#define KEY_STREAM_P_FOOTER (KEY_STREAM_P_ACCEL_X + 1) +#define KEY_STREAM_P_ACCEL_Z (KEY_STREAM_P_FOOTER + 1) + +#define NUM_KEYS (KEY_STREAM_P_ACCEL_Z + 1) + +typedef struct { + unsigned short key; + unsigned short addr; +} tKeyLabel; + +#define DINA0A 0x0a +#define DINA22 0x22 +#define DINA42 0x42 +#define DINA5A 0x5a + +#define DINA06 0x06 +#define DINA0E 0x0e +#define DINA16 0x16 +#define DINA1E 0x1e +#define DINA26 0x26 +#define DINA2E 0x2e +#define DINA36 0x36 +#define DINA3E 0x3e +#define DINA46 0x46 +#define DINA4E 0x4e +#define DINA56 0x56 +#define DINA5E 0x5e +#define DINA66 0x66 +#define DINA6E 0x6e +#define DINA76 0x76 +#define DINA7E 0x7e + +#define DINA00 0x00 +#define DINA08 0x08 +#define DINA10 0x10 +#define DINA18 0x18 +#define DINA20 0x20 +#define DINA28 0x28 +#define DINA30 0x30 +#define DINA38 0x38 +#define DINA40 0x40 +#define DINA48 0x48 +#define DINA50 0x50 +#define DINA58 0x58 +#define DINA60 0x60 +#define DINA68 0x68 +#define DINA70 0x70 +#define DINA78 0x78 + +#define DINA04 0x04 +#define DINA0C 0x0c +#define DINA14 0x14 +#define DINA1C 0x1C +#define DINA24 0x24 +#define DINA2C 0x2c +#define DINA34 0x34 +#define DINA3C 0x3c +#define DINA44 0x44 +#define DINA4C 0x4c +#define DINA54 0x54 +#define DINA5C 0x5c +#define DINA64 0x64 +#define DINA6C 0x6c +#define DINA74 0x74 +#define DINA7C 0x7c + +#define DINA01 0x01 +#define DINA09 0x09 +#define DINA11 0x11 +#define DINA19 0x19 +#define DINA21 0x21 +#define DINA29 0x29 +#define DINA31 0x31 +#define DINA39 0x39 +#define DINA41 0x41 +#define DINA49 0x49 +#define DINA51 0x51 +#define DINA59 0x59 +#define DINA61 0x61 +#define DINA69 0x69 +#define DINA71 0x71 +#define DINA79 0x79 + +#define DINA25 0x25 +#define DINA2D 0x2d +#define DINA35 0x35 +#define DINA3D 0x3d +#define DINA4D 0x4d +#define DINA55 0x55 +#define DINA5D 0x5D +#define DINA6D 0x6d +#define DINA75 0x75 +#define DINA7D 0x7d + +#define DINADC 0xdc +#define DINAF2 0xf2 +#define DINAAB 0xab +#define DINAAA 0xaa +#define DINAF1 0xf1 +#define DINADF 0xdf +#define DINADA 0xda +#define DINAB1 0xb1 +#define DINAB9 0xb9 +#define DINAF3 0xf3 +#define DINA8B 0x8b +#define DINAA3 0xa3 +#define DINA91 0x91 +#define DINAB6 0xb6 +#define DINAB4 0xb4 + + +#define DINC00 0x00 +#define DINC01 0x01 +#define DINC02 0x02 +#define DINC03 0x03 +#define DINC08 0x08 +#define DINC09 0x09 +#define DINC0A 0x0a +#define DINC0B 0x0b +#define DINC10 0x10 +#define DINC11 0x11 +#define DINC12 0x12 +#define DINC13 0x13 +#define DINC18 0x18 +#define DINC19 0x19 +#define DINC1A 0x1a +#define DINC1B 0x1b + +#define DINC20 0x20 +#define DINC21 0x21 +#define DINC22 0x22 +#define DINC23 0x23 +#define DINC28 0x28 +#define DINC29 0x29 +#define DINC2A 0x2a +#define DINC2B 0x2b +#define DINC30 0x30 +#define DINC31 0x31 +#define DINC32 0x32 +#define DINC33 0x33 +#define DINC38 0x38 +#define DINC39 0x39 +#define DINC3A 0x3a +#define DINC3B 0x3b + +#define DINC40 0x40 +#define DINC41 0x41 +#define DINC42 0x42 +#define DINC43 0x43 +#define DINC48 0x48 +#define DINC49 0x49 +#define DINC4A 0x4a +#define DINC4B 0x4b +#define DINC50 0x50 +#define DINC51 0x51 +#define DINC52 0x52 +#define DINC53 0x53 +#define DINC58 0x58 +#define DINC59 0x59 +#define DINC5A 0x5a +#define DINC5B 0x5b + +#define DINC60 0x60 +#define DINC61 0x61 +#define DINC62 0x62 +#define DINC63 0x63 +#define DINC68 0x68 +#define DINC69 0x69 +#define DINC6A 0x6a +#define DINC6B 0x6b +#define DINC70 0x70 +#define DINC71 0x71 +#define DINC72 0x72 +#define DINC73 0x73 +#define DINC78 0x78 +#define DINC79 0x79 +#define DINC7A 0x7a +#define DINC7B 0x7b + +#define DIND40 0x40 + + +#define DINA80 0x80 +#define DINA90 0x90 +#define DINAA0 0xa0 +#define DINAC9 0xc9 +#define DINACB 0xcb +#define DINACD 0xcd +#define DINACF 0xcf +#define DINAC8 0xc8 +#define DINACA 0xca +#define DINACC 0xcc +#define DINACE 0xce +#define DINAD8 0xd8 +#define DINADD 0xdd +#define DINAF8 0xf0 +#define DINAFE 0xfe + +#define DINBF8 0xf8 +#define DINAC0 0xb0 +#define DINAC1 0xb1 +#define DINAC2 0xb4 +#define DINAC3 0xb5 +#define DINAC4 0xb8 +#define DINAC5 0xb9 +#define DINBC0 0xc0 +#define DINBC2 0xc2 +#define DINBC4 0xc4 +#define DINBC6 0xc6 + + + +#endif // DMPKEY_H__ diff --git a/bsp/boards/mimsy2-cc2538/dmpmap.h b/bsp/boards/mimsy2-cc2538/dmpmap.h new file mode 100644 index 0000000000..391ba14421 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/dmpmap.h @@ -0,0 +1,264 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +#ifndef DMPMAP_H +#define DMPMAP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define DMP_PTAT 0 +#define DMP_XGYR 2 +#define DMP_YGYR 4 +#define DMP_ZGYR 6 +#define DMP_XACC 8 +#define DMP_YACC 10 +#define DMP_ZACC 12 +#define DMP_ADC1 14 +#define DMP_ADC2 16 +#define DMP_ADC3 18 +#define DMP_BIASUNC 20 +#define DMP_FIFORT 22 +#define DMP_INVGSFH 24 +#define DMP_INVGSFL 26 +#define DMP_1H 28 +#define DMP_1L 30 +#define DMP_BLPFSTCH 32 +#define DMP_BLPFSTCL 34 +#define DMP_BLPFSXH 36 +#define DMP_BLPFSXL 38 +#define DMP_BLPFSYH 40 +#define DMP_BLPFSYL 42 +#define DMP_BLPFSZH 44 +#define DMP_BLPFSZL 46 +#define DMP_BLPFMTC 48 +#define DMP_SMC 50 +#define DMP_BLPFMXH 52 +#define DMP_BLPFMXL 54 +#define DMP_BLPFMYH 56 +#define DMP_BLPFMYL 58 +#define DMP_BLPFMZH 60 +#define DMP_BLPFMZL 62 +#define DMP_BLPFC 64 +#define DMP_SMCTH 66 +#define DMP_0H2 68 +#define DMP_0L2 70 +#define DMP_BERR2H 72 +#define DMP_BERR2L 74 +#define DMP_BERR2NH 76 +#define DMP_SMCINC 78 +#define DMP_ANGVBXH 80 +#define DMP_ANGVBXL 82 +#define DMP_ANGVBYH 84 +#define DMP_ANGVBYL 86 +#define DMP_ANGVBZH 88 +#define DMP_ANGVBZL 90 +#define DMP_BERR1H 92 +#define DMP_BERR1L 94 +#define DMP_ATCH 96 +#define DMP_BIASUNCSF 98 +#define DMP_ACT2H 100 +#define DMP_ACT2L 102 +#define DMP_GSFH 104 +#define DMP_GSFL 106 +#define DMP_GH 108 +#define DMP_GL 110 +#define DMP_0_5H 112 +#define DMP_0_5L 114 +#define DMP_0_0H 116 +#define DMP_0_0L 118 +#define DMP_1_0H 120 +#define DMP_1_0L 122 +#define DMP_1_5H 124 +#define DMP_1_5L 126 +#define DMP_TMP1AH 128 +#define DMP_TMP1AL 130 +#define DMP_TMP2AH 132 +#define DMP_TMP2AL 134 +#define DMP_TMP3AH 136 +#define DMP_TMP3AL 138 +#define DMP_TMP4AH 140 +#define DMP_TMP4AL 142 +#define DMP_XACCW 144 +#define DMP_TMP5 146 +#define DMP_XACCB 148 +#define DMP_TMP8 150 +#define DMP_YACCB 152 +#define DMP_TMP9 154 +#define DMP_ZACCB 156 +#define DMP_TMP10 158 +#define DMP_DZH 160 +#define DMP_DZL 162 +#define DMP_XGCH 164 +#define DMP_XGCL 166 +#define DMP_YGCH 168 +#define DMP_YGCL 170 +#define DMP_ZGCH 172 +#define DMP_ZGCL 174 +#define DMP_YACCW 176 +#define DMP_TMP7 178 +#define DMP_AFB1H 180 +#define DMP_AFB1L 182 +#define DMP_AFB2H 184 +#define DMP_AFB2L 186 +#define DMP_MAGFBH 188 +#define DMP_MAGFBL 190 +#define DMP_QT1H 192 +#define DMP_QT1L 194 +#define DMP_QT2H 196 +#define DMP_QT2L 198 +#define DMP_QT3H 200 +#define DMP_QT3L 202 +#define DMP_QT4H 204 +#define DMP_QT4L 206 +#define DMP_CTRL1H 208 +#define DMP_CTRL1L 210 +#define DMP_CTRL2H 212 +#define DMP_CTRL2L 214 +#define DMP_CTRL3H 216 +#define DMP_CTRL3L 218 +#define DMP_CTRL4H 220 +#define DMP_CTRL4L 222 +#define DMP_CTRLS1 224 +#define DMP_CTRLSF1 226 +#define DMP_CTRLS2 228 +#define DMP_CTRLSF2 230 +#define DMP_CTRLS3 232 +#define DMP_CTRLSFNLL 234 +#define DMP_CTRLS4 236 +#define DMP_CTRLSFNL2 238 +#define DMP_CTRLSFNL 240 +#define DMP_TMP30 242 +#define DMP_CTRLSFJT 244 +#define DMP_TMP31 246 +#define DMP_TMP11 248 +#define DMP_CTRLSF2_2 250 +#define DMP_TMP12 252 +#define DMP_CTRLSF1_2 254 +#define DMP_PREVPTAT 256 +#define DMP_ACCZB 258 +#define DMP_ACCXB 264 +#define DMP_ACCYB 266 +#define DMP_1HB 272 +#define DMP_1LB 274 +#define DMP_0H 276 +#define DMP_0L 278 +#define DMP_ASR22H 280 +#define DMP_ASR22L 282 +#define DMP_ASR6H 284 +#define DMP_ASR6L 286 +#define DMP_TMP13 288 +#define DMP_TMP14 290 +#define DMP_FINTXH 292 +#define DMP_FINTXL 294 +#define DMP_FINTYH 296 +#define DMP_FINTYL 298 +#define DMP_FINTZH 300 +#define DMP_FINTZL 302 +#define DMP_TMP1BH 304 +#define DMP_TMP1BL 306 +#define DMP_TMP2BH 308 +#define DMP_TMP2BL 310 +#define DMP_TMP3BH 312 +#define DMP_TMP3BL 314 +#define DMP_TMP4BH 316 +#define DMP_TMP4BL 318 +#define DMP_STXG 320 +#define DMP_ZCTXG 322 +#define DMP_STYG 324 +#define DMP_ZCTYG 326 +#define DMP_STZG 328 +#define DMP_ZCTZG 330 +#define DMP_CTRLSFJT2 332 +#define DMP_CTRLSFJTCNT 334 +#define DMP_PVXG 336 +#define DMP_TMP15 338 +#define DMP_PVYG 340 +#define DMP_TMP16 342 +#define DMP_PVZG 344 +#define DMP_TMP17 346 +#define DMP_MNMFLAGH 352 +#define DMP_MNMFLAGL 354 +#define DMP_MNMTMH 356 +#define DMP_MNMTML 358 +#define DMP_MNMTMTHRH 360 +#define DMP_MNMTMTHRL 362 +#define DMP_MNMTHRH 364 +#define DMP_MNMTHRL 366 +#define DMP_ACCQD4H 368 +#define DMP_ACCQD4L 370 +#define DMP_ACCQD5H 372 +#define DMP_ACCQD5L 374 +#define DMP_ACCQD6H 376 +#define DMP_ACCQD6L 378 +#define DMP_ACCQD7H 380 +#define DMP_ACCQD7L 382 +#define DMP_ACCQD0H 384 +#define DMP_ACCQD0L 386 +#define DMP_ACCQD1H 388 +#define DMP_ACCQD1L 390 +#define DMP_ACCQD2H 392 +#define DMP_ACCQD2L 394 +#define DMP_ACCQD3H 396 +#define DMP_ACCQD3L 398 +#define DMP_XN2H 400 +#define DMP_XN2L 402 +#define DMP_XN1H 404 +#define DMP_XN1L 406 +#define DMP_YN2H 408 +#define DMP_YN2L 410 +#define DMP_YN1H 412 +#define DMP_YN1L 414 +#define DMP_YH 416 +#define DMP_YL 418 +#define DMP_B0H 420 +#define DMP_B0L 422 +#define DMP_A1H 424 +#define DMP_A1L 426 +#define DMP_A2H 428 +#define DMP_A2L 430 +#define DMP_SEM1 432 +#define DMP_FIFOCNT 434 +#define DMP_SH_TH_X 436 +#define DMP_PACKET 438 +#define DMP_SH_TH_Y 440 +#define DMP_FOOTER 442 +#define DMP_SH_TH_Z 444 +#define DMP_TEMP29 448 +#define DMP_TEMP30 450 +#define DMP_XACCB_PRE 452 +#define DMP_XACCB_PREL 454 +#define DMP_YACCB_PRE 456 +#define DMP_YACCB_PREL 458 +#define DMP_ZACCB_PRE 460 +#define DMP_ZACCB_PREL 462 +#define DMP_TMP22 464 +#define DMP_TAP_TIMER 466 +#define DMP_TAP_THX 468 +#define DMP_TAP_THY 472 +#define DMP_TAP_THZ 476 +#define DMP_TAPW_MIN 478 +#define DMP_TMP25 480 +#define DMP_TMP26 482 +#define DMP_TMP27 484 +#define DMP_TMP28 486 +#define DMP_ORIENT 488 +#define DMP_THRSH 490 +#define DMP_ENDIANH 492 +#define DMP_ENDIANL 494 +#define DMP_BLPFNMTCH 496 +#define DMP_BLPFNMTCL 498 +#define DMP_BLPFNMXH 500 +#define DMP_BLPFNMXL 502 +#define DMP_BLPFNMYH 504 +#define DMP_BLPFNMYL 506 +#define DMP_BLPFNMZH 508 +#define DMP_BLPFNMZL 510 +#ifdef __cplusplus +} +#endif +#endif // DMPMAP_H diff --git a/bsp/boards/mimsy2-cc2538/eMPL-hal/eMPL_outputs.c b/bsp/boards/mimsy2-cc2538/eMPL-hal/eMPL_outputs.c new file mode 100644 index 0000000000..08f073bcee --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/eMPL-hal/eMPL_outputs.c @@ -0,0 +1,322 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/** + * @defgroup HAL_Outputs hal_outputs + * @brief Motion Library - HAL Outputs + * Sets up common outputs for HAL + * + * @{ + * @file eMPL_outputs.c + * @brief Embedded MPL outputs. + */ +#include "eMPL_outputs.h" +#include "ml_math_func.h" +#include "mlmath.h" +#include "start_manager.h" +#include "data_builder.h" +#include "results_holder.h" + +struct eMPL_output_s { + long quat[4]; + int quat_accuracy; + int gyro_status; + int accel_status; + int compass_status; + int nine_axis_status; + inv_time_t nine_axis_timestamp; +}; + +static struct eMPL_output_s eMPL_out; + +/** + * @brief Acceleration (g's) in body frame. + * Embedded MPL defines gravity as positive acceleration pointing away from + * the Earth. + * @param[out] data Acceleration in g's, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_accel(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + inv_get_accel_set(data, accuracy, timestamp); + if (eMPL_out.accel_status & INV_NEW_DATA) + return 1; + else + return 0; +} + +/** + * @brief Angular velocity (degrees per second) in body frame. + * @param[out] data Angular velocity in dps, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_gyro(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + inv_get_gyro_set(data, accuracy, timestamp); + if (eMPL_out.gyro_status & INV_NEW_DATA) + return 1; + else + return 0; +} + +/** + * @brief Magnetic field strength in body frame. + * @param[out] data Field strength in microteslas, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_compass(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + inv_get_compass_set(data, accuracy, timestamp); + if (eMPL_out.compass_status & INV_NEW_DATA) + return 1; + else + return 0; +} + +/** + * @brief Body-to-world frame quaternion. + * The elements are output in the following order: W, X, Y, Z. + * @param[out] data Quaternion, q30 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_quat(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + memcpy(data, eMPL_out.quat, sizeof(eMPL_out.quat)); + accuracy[0] = eMPL_out.quat_accuracy; + timestamp[0] = eMPL_out.nine_axis_timestamp; + return eMPL_out.nine_axis_status; +} + +/** + * @brief Quaternion-derived heading. + * @param[out] data Heading in degrees, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_heading(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + long t1, t2, q00, q03, q12, q22; + float fdata; + + q00 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[0]); + q03 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[3]); + q12 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[2]); + q22 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[2]); + + /* X component of the Ybody axis in World frame */ + t1 = q12 - q03; + + /* Y component of the Ybody axis in World frame */ + t2 = q22 + q00 - (1L << 30); + fdata = atan2f((float) t1, (float) t2) * 180.f / (float) M_PI; + if (fdata < 0.f) + fdata += 360.f; + data[0] = (long)(fdata * 65536.f); + + accuracy[0] = eMPL_out.quat_accuracy; + timestamp[0] = eMPL_out.nine_axis_timestamp; + return eMPL_out.nine_axis_status; +} + +/** + * @brief Body-to-world frame euler angles. + * The euler angles are output with the following convention: + * Pitch: -180 to 180 + * Roll: -90 to 90 + * Yaw: -180 to 180 + * @param[out] data Euler angles in degrees, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_euler(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + long t1, t2, t3; + long q00, q01, q02, q03, q11, q12, q13, q22, q23, q33; + float values[3]; + + q00 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[0]); + q01 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[1]); + q02 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[2]); + q03 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[3]); + q11 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[1]); + q12 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[2]); + q13 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[3]); + q22 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[2]); + q23 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[3]); + q33 = inv_q29_mult(eMPL_out.quat[3], eMPL_out.quat[3]); + + /* X component of the Ybody axis in World frame */ + t1 = q12 - q03; + + /* Y component of the Ybody axis in World frame */ + t2 = q22 + q00 - (1L << 30); + values[2] = -atan2f((float) t1, (float) t2) * 180.f / (float) M_PI; + + /* Z component of the Ybody axis in World frame */ + t3 = q23 + q01; + values[0] = + atan2f((float) t3, + sqrtf((float) t1 * t1 + + (float) t2 * t2)) * 180.f / (float) M_PI; + /* Z component of the Zbody axis in World frame */ + t2 = q33 + q00 - (1L << 30); + if (t2 < 0) { + if (values[0] >= 0) + values[0] = 180.f - values[0]; + else + values[0] = -180.f - values[0]; + } + + /* X component of the Xbody axis in World frame */ + t1 = q11 + q00 - (1L << 30); + /* Y component of the Xbody axis in World frame */ + t2 = q12 + q03; + /* Z component of the Xbody axis in World frame */ + t3 = q13 - q02; + + values[1] = + (atan2f((float)(q33 + q00 - (1L << 30)), (float)(q13 - q02)) * + 180.f / (float) M_PI - 90); + if (values[1] >= 90) + values[1] = 180 - values[1]; + + if (values[1] < -90) + values[1] = -180 - values[1]; + data[0] = (long)(values[0] * 65536.f); + data[1] = (long)(values[1] * 65536.f); + data[2] = (long)(values[2] * 65536.f); + + accuracy[0] = eMPL_out.quat_accuracy; + timestamp[0] = eMPL_out.nine_axis_timestamp; + return eMPL_out.nine_axis_status; +} + +/** + * @brief Body-to-world frame rotation matrix. + * @param[out] data Rotation matrix, q30 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_rot_mat(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + inv_quaternion_to_rotation(eMPL_out.quat, data); + accuracy[0] = eMPL_out.quat_accuracy; + timestamp[0] = eMPL_out.nine_axis_timestamp; + return eMPL_out.nine_axis_status; +} + +static inv_error_t inv_generate_eMPL_outputs + (struct inv_sensor_cal_t *sensor_cal) +{ + int use_sensor; + long sr = 1000; + inv_get_quaternion_set(eMPL_out.quat, &eMPL_out.quat_accuracy, &eMPL_out.nine_axis_timestamp); + eMPL_out.gyro_status = sensor_cal->gyro.status; + eMPL_out.accel_status = sensor_cal->accel.status; + eMPL_out.compass_status = sensor_cal->compass.status; + + /* Find the highest sample rate and tie sensor fusion timestamps to that one. */ + if (sensor_cal->gyro.status & INV_SENSOR_ON) { + sr = sensor_cal->gyro.sample_rate_ms; + use_sensor = 0; + } + if ((sensor_cal->accel.status & INV_SENSOR_ON) && (sr > sensor_cal->accel.sample_rate_ms)) { + sr = sensor_cal->accel.sample_rate_ms; + use_sensor = 1; + } + if ((sensor_cal->compass.status & INV_SENSOR_ON) && (sr > sensor_cal->compass.sample_rate_ms)) { + sr = sensor_cal->compass.sample_rate_ms; + use_sensor = 2; + } + if ((sensor_cal->quat.status & INV_SENSOR_ON) && (sr > sensor_cal->quat.sample_rate_ms)) { + sr = sensor_cal->quat.sample_rate_ms; + use_sensor = 3; + } + + switch (use_sensor) { + default: + case 0: + eMPL_out.nine_axis_status = (sensor_cal->gyro.status & INV_NEW_DATA) ? 1 : 0; + eMPL_out.nine_axis_timestamp = sensor_cal->gyro.timestamp; + break; + case 1: + eMPL_out.nine_axis_status = (sensor_cal->accel.status & INV_NEW_DATA) ? 1 : 0; + eMPL_out.nine_axis_timestamp = sensor_cal->accel.timestamp; + break; + case 2: + eMPL_out.nine_axis_status = (sensor_cal->compass.status & INV_NEW_DATA) ? 1 : 0; + eMPL_out.nine_axis_timestamp = sensor_cal->compass.timestamp; + break; + case 3: + eMPL_out.nine_axis_status = (sensor_cal->quat.status & INV_NEW_DATA) ? 1 : 0; + eMPL_out.nine_axis_timestamp = sensor_cal->quat.timestamp; + break; + } + + + return INV_SUCCESS; +} + +static inv_error_t inv_start_eMPL_outputs(void) +{ + return inv_register_data_cb(inv_generate_eMPL_outputs, + INV_PRIORITY_HAL_OUTPUTS, INV_GYRO_NEW | INV_ACCEL_NEW | INV_MAG_NEW); +} + +static inv_error_t inv_stop_eMPL_outputs(void) +{ + return inv_unregister_data_cb(inv_generate_eMPL_outputs); +} + +static inv_error_t inv_init_eMPL_outputs(void) +{ + memset(&eMPL_out, 0, sizeof(eMPL_out)); + return INV_SUCCESS; +} + +/** + * @brief Turns on creation and storage of HAL type results. + */ +inv_error_t inv_enable_eMPL_outputs(void) +{ + inv_error_t result; + result = inv_init_eMPL_outputs(); + if (result) + return result; + return inv_register_mpl_start_notification(inv_start_eMPL_outputs); +} + +/** + * @brief Turns off creation and storage of HAL type results. + */ +inv_error_t inv_disable_eMPL_outputs(void) +{ + inv_stop_eMPL_outputs(); + return inv_unregister_mpl_start_notification(inv_start_eMPL_outputs); +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/eMPL-hal/eMPL_outputs.h b/bsp/boards/mimsy2-cc2538/eMPL-hal/eMPL_outputs.h new file mode 100644 index 0000000000..bcdefebd4c --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/eMPL-hal/eMPL_outputs.h @@ -0,0 +1,44 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @defgroup HAL_Outputs + * @brief Motion Library - HAL Outputs + * Sets up common outputs for HAL + * + * @{ + * @file eMPL_outputs.h + * @brief Embedded MPL outputs. + */ +#ifndef _EMPL_OUTPUTS_H_ +#define _EMPL_OUTPUTS_H_ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + int inv_get_sensor_type_accel(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_gyro(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_compass(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_quat(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_euler(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_rot_mat(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_heading(long *data, int8_t *accuracy, inv_time_t *timestamp); + + inv_error_t inv_enable_eMPL_outputs(void); + inv_error_t inv_disable_eMPL_outputs(void); + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef _EMPL_OUTPUTS_H_ */ + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/eMPL_outputs.c b/bsp/boards/mimsy2-cc2538/eMPL_outputs.c new file mode 100644 index 0000000000..08f073bcee --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/eMPL_outputs.c @@ -0,0 +1,322 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/** + * @defgroup HAL_Outputs hal_outputs + * @brief Motion Library - HAL Outputs + * Sets up common outputs for HAL + * + * @{ + * @file eMPL_outputs.c + * @brief Embedded MPL outputs. + */ +#include "eMPL_outputs.h" +#include "ml_math_func.h" +#include "mlmath.h" +#include "start_manager.h" +#include "data_builder.h" +#include "results_holder.h" + +struct eMPL_output_s { + long quat[4]; + int quat_accuracy; + int gyro_status; + int accel_status; + int compass_status; + int nine_axis_status; + inv_time_t nine_axis_timestamp; +}; + +static struct eMPL_output_s eMPL_out; + +/** + * @brief Acceleration (g's) in body frame. + * Embedded MPL defines gravity as positive acceleration pointing away from + * the Earth. + * @param[out] data Acceleration in g's, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_accel(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + inv_get_accel_set(data, accuracy, timestamp); + if (eMPL_out.accel_status & INV_NEW_DATA) + return 1; + else + return 0; +} + +/** + * @brief Angular velocity (degrees per second) in body frame. + * @param[out] data Angular velocity in dps, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_gyro(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + inv_get_gyro_set(data, accuracy, timestamp); + if (eMPL_out.gyro_status & INV_NEW_DATA) + return 1; + else + return 0; +} + +/** + * @brief Magnetic field strength in body frame. + * @param[out] data Field strength in microteslas, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_compass(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + inv_get_compass_set(data, accuracy, timestamp); + if (eMPL_out.compass_status & INV_NEW_DATA) + return 1; + else + return 0; +} + +/** + * @brief Body-to-world frame quaternion. + * The elements are output in the following order: W, X, Y, Z. + * @param[out] data Quaternion, q30 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_quat(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + memcpy(data, eMPL_out.quat, sizeof(eMPL_out.quat)); + accuracy[0] = eMPL_out.quat_accuracy; + timestamp[0] = eMPL_out.nine_axis_timestamp; + return eMPL_out.nine_axis_status; +} + +/** + * @brief Quaternion-derived heading. + * @param[out] data Heading in degrees, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_heading(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + long t1, t2, q00, q03, q12, q22; + float fdata; + + q00 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[0]); + q03 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[3]); + q12 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[2]); + q22 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[2]); + + /* X component of the Ybody axis in World frame */ + t1 = q12 - q03; + + /* Y component of the Ybody axis in World frame */ + t2 = q22 + q00 - (1L << 30); + fdata = atan2f((float) t1, (float) t2) * 180.f / (float) M_PI; + if (fdata < 0.f) + fdata += 360.f; + data[0] = (long)(fdata * 65536.f); + + accuracy[0] = eMPL_out.quat_accuracy; + timestamp[0] = eMPL_out.nine_axis_timestamp; + return eMPL_out.nine_axis_status; +} + +/** + * @brief Body-to-world frame euler angles. + * The euler angles are output with the following convention: + * Pitch: -180 to 180 + * Roll: -90 to 90 + * Yaw: -180 to 180 + * @param[out] data Euler angles in degrees, q16 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_euler(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + long t1, t2, t3; + long q00, q01, q02, q03, q11, q12, q13, q22, q23, q33; + float values[3]; + + q00 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[0]); + q01 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[1]); + q02 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[2]); + q03 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[3]); + q11 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[1]); + q12 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[2]); + q13 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[3]); + q22 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[2]); + q23 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[3]); + q33 = inv_q29_mult(eMPL_out.quat[3], eMPL_out.quat[3]); + + /* X component of the Ybody axis in World frame */ + t1 = q12 - q03; + + /* Y component of the Ybody axis in World frame */ + t2 = q22 + q00 - (1L << 30); + values[2] = -atan2f((float) t1, (float) t2) * 180.f / (float) M_PI; + + /* Z component of the Ybody axis in World frame */ + t3 = q23 + q01; + values[0] = + atan2f((float) t3, + sqrtf((float) t1 * t1 + + (float) t2 * t2)) * 180.f / (float) M_PI; + /* Z component of the Zbody axis in World frame */ + t2 = q33 + q00 - (1L << 30); + if (t2 < 0) { + if (values[0] >= 0) + values[0] = 180.f - values[0]; + else + values[0] = -180.f - values[0]; + } + + /* X component of the Xbody axis in World frame */ + t1 = q11 + q00 - (1L << 30); + /* Y component of the Xbody axis in World frame */ + t2 = q12 + q03; + /* Z component of the Xbody axis in World frame */ + t3 = q13 - q02; + + values[1] = + (atan2f((float)(q33 + q00 - (1L << 30)), (float)(q13 - q02)) * + 180.f / (float) M_PI - 90); + if (values[1] >= 90) + values[1] = 180 - values[1]; + + if (values[1] < -90) + values[1] = -180 - values[1]; + data[0] = (long)(values[0] * 65536.f); + data[1] = (long)(values[1] * 65536.f); + data[2] = (long)(values[2] * 65536.f); + + accuracy[0] = eMPL_out.quat_accuracy; + timestamp[0] = eMPL_out.nine_axis_timestamp; + return eMPL_out.nine_axis_status; +} + +/** + * @brief Body-to-world frame rotation matrix. + * @param[out] data Rotation matrix, q30 fixed point. + * @param[out] accuracy Accuracy of the measurement from 0 (least accurate) + * to 3 (most accurate). + * @param[out] timestamp The time in milliseconds when this sensor was read. + * @return 1 if data was updated. + */ +int inv_get_sensor_type_rot_mat(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + inv_quaternion_to_rotation(eMPL_out.quat, data); + accuracy[0] = eMPL_out.quat_accuracy; + timestamp[0] = eMPL_out.nine_axis_timestamp; + return eMPL_out.nine_axis_status; +} + +static inv_error_t inv_generate_eMPL_outputs + (struct inv_sensor_cal_t *sensor_cal) +{ + int use_sensor; + long sr = 1000; + inv_get_quaternion_set(eMPL_out.quat, &eMPL_out.quat_accuracy, &eMPL_out.nine_axis_timestamp); + eMPL_out.gyro_status = sensor_cal->gyro.status; + eMPL_out.accel_status = sensor_cal->accel.status; + eMPL_out.compass_status = sensor_cal->compass.status; + + /* Find the highest sample rate and tie sensor fusion timestamps to that one. */ + if (sensor_cal->gyro.status & INV_SENSOR_ON) { + sr = sensor_cal->gyro.sample_rate_ms; + use_sensor = 0; + } + if ((sensor_cal->accel.status & INV_SENSOR_ON) && (sr > sensor_cal->accel.sample_rate_ms)) { + sr = sensor_cal->accel.sample_rate_ms; + use_sensor = 1; + } + if ((sensor_cal->compass.status & INV_SENSOR_ON) && (sr > sensor_cal->compass.sample_rate_ms)) { + sr = sensor_cal->compass.sample_rate_ms; + use_sensor = 2; + } + if ((sensor_cal->quat.status & INV_SENSOR_ON) && (sr > sensor_cal->quat.sample_rate_ms)) { + sr = sensor_cal->quat.sample_rate_ms; + use_sensor = 3; + } + + switch (use_sensor) { + default: + case 0: + eMPL_out.nine_axis_status = (sensor_cal->gyro.status & INV_NEW_DATA) ? 1 : 0; + eMPL_out.nine_axis_timestamp = sensor_cal->gyro.timestamp; + break; + case 1: + eMPL_out.nine_axis_status = (sensor_cal->accel.status & INV_NEW_DATA) ? 1 : 0; + eMPL_out.nine_axis_timestamp = sensor_cal->accel.timestamp; + break; + case 2: + eMPL_out.nine_axis_status = (sensor_cal->compass.status & INV_NEW_DATA) ? 1 : 0; + eMPL_out.nine_axis_timestamp = sensor_cal->compass.timestamp; + break; + case 3: + eMPL_out.nine_axis_status = (sensor_cal->quat.status & INV_NEW_DATA) ? 1 : 0; + eMPL_out.nine_axis_timestamp = sensor_cal->quat.timestamp; + break; + } + + + return INV_SUCCESS; +} + +static inv_error_t inv_start_eMPL_outputs(void) +{ + return inv_register_data_cb(inv_generate_eMPL_outputs, + INV_PRIORITY_HAL_OUTPUTS, INV_GYRO_NEW | INV_ACCEL_NEW | INV_MAG_NEW); +} + +static inv_error_t inv_stop_eMPL_outputs(void) +{ + return inv_unregister_data_cb(inv_generate_eMPL_outputs); +} + +static inv_error_t inv_init_eMPL_outputs(void) +{ + memset(&eMPL_out, 0, sizeof(eMPL_out)); + return INV_SUCCESS; +} + +/** + * @brief Turns on creation and storage of HAL type results. + */ +inv_error_t inv_enable_eMPL_outputs(void) +{ + inv_error_t result; + result = inv_init_eMPL_outputs(); + if (result) + return result; + return inv_register_mpl_start_notification(inv_start_eMPL_outputs); +} + +/** + * @brief Turns off creation and storage of HAL type results. + */ +inv_error_t inv_disable_eMPL_outputs(void) +{ + inv_stop_eMPL_outputs(); + return inv_unregister_mpl_start_notification(inv_start_eMPL_outputs); +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/eMPL_outputs.h b/bsp/boards/mimsy2-cc2538/eMPL_outputs.h new file mode 100644 index 0000000000..bcdefebd4c --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/eMPL_outputs.h @@ -0,0 +1,44 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @defgroup HAL_Outputs + * @brief Motion Library - HAL Outputs + * Sets up common outputs for HAL + * + * @{ + * @file eMPL_outputs.h + * @brief Embedded MPL outputs. + */ +#ifndef _EMPL_OUTPUTS_H_ +#define _EMPL_OUTPUTS_H_ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + int inv_get_sensor_type_accel(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_gyro(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_compass(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_quat(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_euler(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_rot_mat(long *data, int8_t *accuracy, inv_time_t *timestamp); + int inv_get_sensor_type_heading(long *data, int8_t *accuracy, inv_time_t *timestamp); + + inv_error_t inv_enable_eMPL_outputs(void); + inv_error_t inv_disable_eMPL_outputs(void); + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef _EMPL_OUTPUTS_H_ */ + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/eui64.c b/bsp/boards/mimsy2-cc2538/eui64.c new file mode 100644 index 0000000000..04c8ca580f --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/eui64.c @@ -0,0 +1,40 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "eui64" bsp module. + */ + +#include + +#include "eui64.h" + +//=========================== defines ========================================= + +#define BSP_EUI64_ADDRESS_HI_H ( 0x0028002F ) +#define BSP_EUI64_ADDRESS_HI_L ( 0x0028002C ) +#define BSP_EUI64_ADDRESS_LO_H ( 0x0028002B ) +#define BSP_EUI64_ADDRESS_LO_L ( 0x00280028 ) + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +//=========================== public ========================================== + +void eui64_get(uint8_t* addressToWrite) { + uint8_t* eui64_flash; + + eui64_flash = (uint8_t*)BSP_EUI64_ADDRESS_LO_H; + while(eui64_flash >= (uint8_t*)BSP_EUI64_ADDRESS_LO_L) { + *addressToWrite++ = *eui64_flash--; + } + + eui64_flash = (uint8_t*)BSP_EUI64_ADDRESS_HI_H; + while(eui64_flash >= (uint8_t*)BSP_EUI64_ADDRESS_HI_L) { + *addressToWrite++ = *eui64_flash--; + } +} + +//=========================== private ========================================= + diff --git a/bsp/boards/mimsy2-cc2538/fast_no_motion.h b/bsp/boards/mimsy2-cc2538/fast_no_motion.h new file mode 100644 index 0000000000..bf5d14af88 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/fast_no_motion.h @@ -0,0 +1,46 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef MLDMP_FAST_NO_MOTION_H__ +#define MLDMP_FAST_NO_MOTION_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + inv_error_t inv_enable_fast_nomot(void); + inv_error_t inv_disable_fast_nomot(void); + inv_error_t inv_start_fast_nomot(void); + inv_error_t inv_stop_fast_nomot(void); + inv_error_t inv_init_fast_nomot(void); + void inv_set_default_number_of_samples(int count); + inv_error_t inv_fast_nomot_is_enabled(unsigned char *is_enabled); + inv_error_t inv_update_fast_nomot(long *gyro); + + void inv_get_fast_nomot_accel_param(long *cntr, long long *param); + void inv_get_fast_nomot_compass_param(long *cntr, long long *param); + void inv_set_fast_nomot_accel_threshold(long long thresh); + void inv_set_fast_nomot_compass_threshold(long long thresh); + void int_set_fast_nomot_gyro_threshold(long long thresh); + + void inv_fnm_debug_print(void); + +#ifdef __cplusplus +} +#endif + + +#endif // MLDMP_FAST_NO_MOTION_H__ + diff --git a/bsp/boards/mimsy2-cc2538/flash_mimsy.c b/bsp/boards/mimsy2-cc2538/flash_mimsy.c new file mode 100644 index 0000000000..69e7bd9f10 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/flash_mimsy.c @@ -0,0 +1,95 @@ +#include "flash_mimsy.h" +#include +//#include +//#include "bsp.h" +//#include "bsp_led.h" +#include "gptimer.h" +#include "sys_ctrl.h" +#include "hw_gptimer.h" +#include "hw_ints.h" +#include "gpio.h" +#include "interrupt.h" +#include "hw_memmap.h" +#include "hw_gpio.h" +#include "ioc.h" +//#include "inchworm.h" +#include "flash.h" +#include "uart_mimsy.h" + +#define PAGE_SIZE 2048 +#define PAGE_TO_ERASE 14 +#define PAGE_TO_ERASE_START_ADDR (FLASH_BASE + (PAGE_TO_ERASE * PAGE_SIZE)) + +/*This function writes a full 2048 KB page-worth of data to flash. + Parameters: + IMUData data[]: pointer to array of IMUData structures that are to be written to flash + uint32_t size: size of data[] in number of IMUData structures + uint32_t startPage: Flash page where data is to be written + IMUDataCard *card: pointer to an IMUDataCard where the function will record + which page the data was written to and which timestamps on the data are included + */ +void flashWriteIMU(IMUData data[],uint32_t size, uint32_t startPage,int wordsWritten){ + + uint32_t pageStartAddr=FLASH_BASE + (startPage * PAGE_SIZE); //page base address + int32_t i32Res; + + uint32_t structNum = size; + + //mimsyPrintf("\n Flash Page Address: %x",pageStartAddr); + if(wordsWritten == 0){ + i32Res = FlashMainPageErase(pageStartAddr); //erase page so there it can be written to + } + //mimsyPrintf("\n Flash Erase Status: %d",i32Res); + for(uint32_t i=0;ipage=startPage; + //card->startTime=data[0].fields.timestamp; + //card->endTime=data[size-1].fields.timestamp; + +} +/*This function reads a page worth of IMUData from flash. + Parameters: + IMUDataCard card: The IMUDataCard that corresponds to the data that you want to read from flash + IMUData * dataArray: pointer that points to location of data array that you want the read operation to be written to + uint32_t size: size of dataArray in number of IMUData structures +*/ +void flashReadIMU(IMUDataCard card, IMUData * dataArray,uint32_t size){ + + uint32_t pageAddr=FLASH_BASE+card.page*PAGE_SIZE; + + for(uint32_t i=0;i + +/*IMUData is a union data structure used to store imu data points. Access the struct +type of this union is used for accessing and setting the data. The uint32 array version +of the struct is used for reading and writing to flash*/ +typedef union IMUData { + + struct { + uint16_t accelX;//a X data + uint16_t accelY;//a X data + uint16_t accelZ;//a X data + + uint16_t gyroX;//gyro X data + uint16_t gyroY;//gyro Y data + uint16_t gyroZ;//gyro Z data + + uint32_t timestamp; + float servo_state_0; + float servo_state_1; + + + +} fields; + struct { + int16_t accelX;//a X data + int16_t accelY;//a X data + int16_t accelZ;//a X data + + int16_t gyroX;//gyro X data + int16_t gyroY;//gyro Y data + int16_t gyroZ;//gyro Z data + + int32_t timestamp; + float servo_state_0; + float servo_state_1; + + + +} signedfields; +uint32_t bits[6]; +}IMUData; + + +/*This struct is used to keep track of wherer data was written to. This strucut +must be passed to flashWriteIMU where it is updated to include the flash location +of the data. A written data card is passed to flashReadIMU inorder to read the +data from that location*/ +typedef struct IMUDataCard{ + uint32_t page; + uint32_t startTime; + uint32_t endTime; +} IMUDataCard; + + +extern void flashWriteIMU(IMUData data[],uint32_t size, uint32_t startPage, int wordsWritten); +extern void flashReadIMU(IMUDataCard card, IMUData *data, uint32_t size); +extern void flashReadIMUSection(IMUDataCard card, IMUData *data, uint32_t size,int wordsRead); + + +#endif diff --git a/bsp/boards/mimsy2-cc2538/fusion_9axis.h b/bsp/boards/mimsy2-cc2538/fusion_9axis.h new file mode 100644 index 0000000000..7d2efe9bb1 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/fusion_9axis.h @@ -0,0 +1,38 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef MLDMP_FUSION9AXIS_H__ +#define MLDMP_FUSION9AXIS_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + void inv_init_9x_fusion(void); + inv_error_t inv_9x_fusion_state_change(unsigned char newState); + inv_error_t inv_enable_9x_sensor_fusion(void); + inv_error_t inv_disable_9x_sensor_fusion(void); + inv_error_t inv_start_9x_sensor_fusion(void); + inv_error_t inv_stop_9x_sensor_fusion(void); + inv_error_t inv_9x_fusion_set_mag_fb(float fb); + inv_error_t inv_9x_fusion_enable_jitter_reduction(int en); + inv_error_t inv_9x_fusion_use_timestamps(int en); + +#ifdef __cplusplus +} +#endif + + +#endif // MLDMP_FUSION9AXIS_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/gyro_tc.h b/bsp/boards/mimsy2-cc2538/gyro_tc.h new file mode 100644 index 0000000000..3347a14878 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/gyro_tc.h @@ -0,0 +1,43 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef _GYRO_TC_H +#define _GYRO_TC_H_ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_gyro_tc(void); +inv_error_t inv_disable_gyro_tc(void); +inv_error_t inv_start_gyro_tc(void); +inv_error_t inv_stop_gyro_tc(void); + +inv_error_t inv_get_gyro_ts(long *data); +inv_error_t inv_set_gyro_ts(long *data); + +inv_error_t inv_init_gyro_ts(void); + +inv_error_t inv_set_gtc_max_temp(long data); +inv_error_t inv_set_gtc_min_temp(long data); + +inv_error_t inv_print_gtc_data(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _GYRO_TC_H */ + diff --git a/bsp/boards/mimsy2-cc2538/hal_outputs.c b/bsp/boards/mimsy2-cc2538/hal_outputs.c new file mode 100644 index 0000000000..3b5f946a9a --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/hal_outputs.c @@ -0,0 +1,486 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/** + * @defgroup HAL_Outputs hal_outputs + * @brief Motion Library - HAL Outputs + * Sets up common outputs for HAL + * + * @{ + * @file hal_outputs.c + * @brief HAL Outputs. + */ + +#include + +#include "hal_outputs.h" +#include "log.h" +#include "ml_math_func.h" +#include "mlmath.h" +#include "start_manager.h" +#include "data_builder.h" +#include "results_holder.h" + +struct hal_output_t { + int accuracy_mag; /**< Compass accuracy */ +// int accuracy_gyro; /**< Gyro Accuracy */ +// int accuracy_accel; /**< Accel Accuracy */ + int accuracy_quat; /**< quat Accuracy */ + + inv_time_t nav_timestamp; + inv_time_t gam_timestamp; +// inv_time_t accel_timestamp; + inv_time_t mag_timestamp; + long nav_quat[4]; + int gyro_status; + int accel_status; + int compass_status; + int nine_axis_status; + inv_biquad_filter_t lp_filter[3]; + float compass_float[3]; +}; + +static struct hal_output_t hal_out; + +/** Acceleration (m/s^2) in body frame. +* @param[out] values Acceleration in m/s^2 includes gravity. So while not in motion, it +* should return a vector of magnitude near 9.81 m/s^2 +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_accel(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_accelerometer(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + int status; + /* Converts fixed point to m/s^2. Fixed point has 1g = 2^16. + * So this 9.80665 / 2^16 */ +#define ACCEL_CONVERSION 0.000149637603759766f + long accel[3]; + inv_get_accel_set(accel, accuracy, timestamp); + values[0] = accel[0] * ACCEL_CONVERSION; + values[1] = accel[1] * ACCEL_CONVERSION; + values[2] = accel[2] * ACCEL_CONVERSION; + if (hal_out.accel_status & INV_NEW_DATA) + status = 1; + else + status = 0; + return status; +} + +/** Linear Acceleration (m/s^2) in Body Frame. +* @param[out] values Linear Acceleration in body frame, length 3, (m/s^2). May show +* accel biases while at rest. +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_accel(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_linear_acceleration(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + long gravity[3], accel[3]; + + inv_get_accel_set(accel, accuracy, timestamp); + inv_get_gravity(gravity); + accel[0] -= gravity[0] >> 14; + accel[1] -= gravity[1] >> 14; + accel[2] -= gravity[2] >> 14; + values[0] = accel[0] * ACCEL_CONVERSION; + values[1] = accel[1] * ACCEL_CONVERSION; + values[2] = accel[2] * ACCEL_CONVERSION; + + return 1; +} + +/** Gravity vector (m/s^2) in Body Frame. +* @param[out] values Gravity vector in body frame, length 3, (m/s^2) +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_accel(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_gravity(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + long gravity[3]; + + *accuracy = (int8_t) hal_out.accuracy_quat; + *timestamp = hal_out.nav_timestamp; + inv_get_gravity(gravity); + values[0] = (gravity[0] >> 14) * ACCEL_CONVERSION; + values[1] = (gravity[1] >> 14) * ACCEL_CONVERSION; + values[2] = (gravity[2] >> 14) * ACCEL_CONVERSION; + + return 1; +} + +/* Converts fixed point to rad/sec. Fixed point has 1 dps = 2^16. + * So this is: pi / 2^16 / 180 */ +#define GYRO_CONVERSION 2.66316109007924e-007f + +/** Gyroscope calibrated data (rad/s) in body frame. +* @param[out] values Rotation Rate in rad/sec. +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_gyro(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_gyroscope(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + long gyro[3]; + int status; + + inv_get_gyro_set(gyro, accuracy, timestamp); + values[0] = gyro[0] * GYRO_CONVERSION; + values[1] = gyro[1] * GYRO_CONVERSION; + values[2] = gyro[2] * GYRO_CONVERSION; + if (hal_out.gyro_status & INV_NEW_DATA) + status = 1; + else + status = 0; + return status; +} + +/** Gyroscope raw data (rad/s) in body frame. +* @param[out] values Rotation Rate in rad/sec. +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_gyro(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_gyroscope_raw(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + long gyro[3]; + int status; + + inv_get_gyro_set_raw(gyro, accuracy, timestamp); + values[0] = gyro[0] * GYRO_CONVERSION; + values[1] = gyro[1] * GYRO_CONVERSION; + values[2] = gyro[2] * GYRO_CONVERSION; + if (hal_out.gyro_status & INV_NEW_DATA) + status = 1; + else + status = 0; + return status; +} + +/** +* This corresponds to Sensor.TYPE_ROTATION_VECTOR. +* The rotation vector represents the orientation of the device as a combination +* of an angle and an axis, in which the device has rotated through an angle @f$\theta@f$ +* around an axis {x, y, z}.
+* The three elements of the rotation vector are +* {x*sin(@f$\theta@f$/2), y*sin(@f$\theta@f$/2), z*sin(@f$\theta@f$/2)}, such that the magnitude of the rotation +* vector is equal to sin(@f$\theta@f$/2), and the direction of the rotation vector is +* equal to the direction of the axis of rotation. +* +* The three elements of the rotation vector are equal to the last three components of a unit quaternion +* {x*sin(@f$\theta@f$/2), y*sin(@f$\theta@f$/2), z*sin(@f$\theta@f$/2)>. The 4th element is cos(@f$\theta@f$/2). +* +* Elements of the rotation vector are unitless. The x,y and z axis are defined in the same way as the acceleration sensor. +* The reference coordinate system is defined as a direct orthonormal basis, where: + + -X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points East). + -Y is tangential to the ground at the device's current location and points towards the magnetic North Pole. + -Z points towards the sky and is perpendicular to the ground. +* @param[out] values Length 4. +* @param[out] accuracy Accuracy 0 to 3, 3 = most accurate +* @param[out] timestamp Timestamp. In (ns) for Android. +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_rotation_vector(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + *accuracy = (int8_t) hal_out.accuracy_quat; + *timestamp = hal_out.nav_timestamp; + + if (hal_out.nav_quat[0] >= 0) { + values[0] = hal_out.nav_quat[1] * INV_TWO_POWER_NEG_30; + values[1] = hal_out.nav_quat[2] * INV_TWO_POWER_NEG_30; + values[2] = hal_out.nav_quat[3] * INV_TWO_POWER_NEG_30; + values[3] = hal_out.nav_quat[0] * INV_TWO_POWER_NEG_30; + } else { + values[0] = -hal_out.nav_quat[1] * INV_TWO_POWER_NEG_30; + values[1] = -hal_out.nav_quat[2] * INV_TWO_POWER_NEG_30; + values[2] = -hal_out.nav_quat[3] * INV_TWO_POWER_NEG_30; + values[3] = -hal_out.nav_quat[0] * INV_TWO_POWER_NEG_30; + } + values[4] = inv_get_heading_confidence_interval(); + + return hal_out.nine_axis_status; +} + +/** Compass data (uT) in body frame. +* @param[out] values Compass data in (uT), length 3. May be calibrated by having +* biases removed and sensitivity adjusted +* @param[out] accuracy Accuracy 0 to 3, 3 = most accurate +* @param[out] timestamp Timestamp. In (ns) for Android. +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_magnetic_field(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + int status; + /* Converts fixed point to uT. Fixed point has 1 uT = 2^16. + * So this is: 1 / 2^16*/ +//#define COMPASS_CONVERSION 1.52587890625e-005f + int i; + + *timestamp = hal_out.mag_timestamp; + *accuracy = (int8_t) hal_out.accuracy_mag; + + for (i=0; i<3; i++) { + values[i] = hal_out.compass_float[i]; + } + if (hal_out.compass_status & INV_NEW_DATA) + status = 1; + else + status = 0; + hal_out.compass_status = 0; + return status; +} + +static void inv_get_rotation(float r[3][3]) +{ + long rot[9]; + float conv = 1.f / (1L<<30); + + inv_quaternion_to_rotation(hal_out.nav_quat, rot); + r[0][0] = rot[0]*conv; + r[0][1] = rot[1]*conv; + r[0][2] = rot[2]*conv; + r[1][0] = rot[3]*conv; + r[1][1] = rot[4]*conv; + r[1][2] = rot[5]*conv; + r[2][0] = rot[6]*conv; + r[2][1] = rot[7]*conv; + r[2][2] = rot[8]*conv; +} + +static void google_orientation(float *g) +{ + float rad2deg = (float)(180.0 / M_PI); + float R[3][3]; + + inv_get_rotation(R); + + g[0] = atan2f(-R[1][0], R[0][0]) * rad2deg; + g[1] = atan2f(-R[2][1], R[2][2]) * rad2deg; + g[2] = asinf ( R[2][0]) * rad2deg; + if (g[0] < 0) + g[0] += 360; +} + + +/** This corresponds to Sensor.TYPE_ORIENTATION. All values are angles in degrees. +* @param[out] values Length 3, Degrees.
+* - values[0]: Azimuth, angle between the magnetic north direction +* and the y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South, 270=West
+* - values[1]: Pitch, rotation around x-axis (-180 to 180), with positive values +* when the z-axis moves toward the y-axis.
+* - values[2]: Roll, rotation around y-axis (-90 to 90), with positive +* values when the x-axis moves toward the z-axis.
+* +* @note This definition is different from yaw, pitch and roll used in aviation +* where the X axis is along the long side of the plane (tail to nose). +* Note: This sensor type exists for legacy reasons, please use getRotationMatrix() +* in conjunction with remapCoordinateSystem() and getOrientation() to compute +* these values instead. +* Important note: For historical reasons the roll angle is positive in the +* clockwise direction (mathematically speaking, it should be positive in +* the counter-clockwise direction). +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_orientation(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + *accuracy = (int8_t) hal_out.accuracy_quat; + *timestamp = hal_out.nav_timestamp; + + google_orientation(values); + + return hal_out.nine_axis_status; +} + +/** Main callback to generate HAL outputs. Typically not called by library users. +* @param[in] sensor_cal Input variable to take sensor data whenever there is new +* sensor data. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_generate_hal_outputs(struct inv_sensor_cal_t *sensor_cal) +{ + int use_sensor = 0; + long sr = 1000; + long compass[3]; + int8_t accuracy; + int i; + (void) sensor_cal; + + inv_get_quaternion_set(hal_out.nav_quat, &hal_out.accuracy_quat, + &hal_out.nav_timestamp); + hal_out.gyro_status = sensor_cal->gyro.status; + hal_out.accel_status = sensor_cal->accel.status; + hal_out.compass_status = sensor_cal->compass.status; + + // Find the highest sample rate and tie generating 9-axis to that one. + if (sensor_cal->gyro.status & INV_SENSOR_ON) { + sr = sensor_cal->gyro.sample_rate_ms; + use_sensor = 0; + } + if ((sensor_cal->accel.status & INV_SENSOR_ON) && (sr > sensor_cal->accel.sample_rate_ms)) { + sr = sensor_cal->accel.sample_rate_ms; + use_sensor = 1; + } + if ((sensor_cal->compass.status & INV_SENSOR_ON) && (sr > sensor_cal->compass.sample_rate_ms)) { + sr = sensor_cal->compass.sample_rate_ms; + use_sensor = 2; + } + if ((sensor_cal->quat.status & INV_SENSOR_ON) && (sr > sensor_cal->quat.sample_rate_ms)) { + sr = sensor_cal->quat.sample_rate_ms; + use_sensor = 3; + } + + // Only output 9-axis if all 9 sensors are on. + if (sensor_cal->quat.status & INV_SENSOR_ON) { + // If quaternion sensor is on, gyros are not required as quaternion already has that part + if ((sensor_cal->accel.status & sensor_cal->compass.status & INV_SENSOR_ON) == 0) { + use_sensor = -1; + } + } else { + if ((sensor_cal->gyro.status & sensor_cal->accel.status & sensor_cal->compass.status & INV_SENSOR_ON) == 0) { + use_sensor = -1; + } + } + + switch (use_sensor) { + case 0: + hal_out.nine_axis_status = (sensor_cal->gyro.status & INV_NEW_DATA) ? 1 : 0; + hal_out.nav_timestamp = sensor_cal->gyro.timestamp; + break; + case 1: + hal_out.nine_axis_status = (sensor_cal->accel.status & INV_NEW_DATA) ? 1 : 0; + hal_out.nav_timestamp = sensor_cal->accel.timestamp; + break; + case 2: + hal_out.nine_axis_status = (sensor_cal->compass.status & INV_NEW_DATA) ? 1 : 0; + hal_out.nav_timestamp = sensor_cal->compass.timestamp; + break; + case 3: + hal_out.nine_axis_status = (sensor_cal->quat.status & INV_NEW_DATA) ? 1 : 0; + hal_out.nav_timestamp = sensor_cal->quat.timestamp; + break; + default: + hal_out.nine_axis_status = 0; // Don't output quaternion related info + break; + } + + /* Converts fixed point to uT. Fixed point has 1 uT = 2^16. + * So this is: 1 / 2^16*/ + #define COMPASS_CONVERSION 1.52587890625e-005f + + inv_get_compass_set(compass, &accuracy, &(hal_out.mag_timestamp) ); + hal_out.accuracy_mag = (int ) accuracy; + + for (i=0; i<3; i++) { + if ((sensor_cal->compass.status & (INV_NEW_DATA | INV_CONTIGUOUS)) == + INV_NEW_DATA ) { + // set the state variables to match output with input + inv_calc_state_to_match_output(&hal_out.lp_filter[i], (float ) compass[i]); + } + + if ((sensor_cal->compass.status & (INV_NEW_DATA | INV_RAW_DATA)) == + (INV_NEW_DATA | INV_RAW_DATA) ) { + + hal_out.compass_float[i] = inv_biquad_filter_process(&hal_out.lp_filter[i], + (float ) compass[i]) * COMPASS_CONVERSION; + + } else if ((sensor_cal->compass.status & INV_NEW_DATA) == INV_NEW_DATA ) { + hal_out.compass_float[i] = (float ) compass[i] * COMPASS_CONVERSION; + } + + } + return INV_SUCCESS; +} + +/** Turns off generation of HAL outputs. +* @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_stop_hal_outputs(void) +{ + inv_error_t result; + result = inv_unregister_data_cb(inv_generate_hal_outputs); + return result; +} + +/** Turns on generation of HAL outputs. This should be called after inv_stop_hal_outputs() +* to turn generation of HAL outputs back on. It is automatically called by inv_enable_hal_outputs(). +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_start_hal_outputs(void) +{ + inv_error_t result; + result = + inv_register_data_cb(inv_generate_hal_outputs, + INV_PRIORITY_HAL_OUTPUTS, + INV_GYRO_NEW | INV_ACCEL_NEW | INV_MAG_NEW); + return result; +} +/* file name: lowPassFilterCoeff_1_6.c */ +float compass_low_pass_filter_coeff[5] = +{+2.000000000000f, +1.000000000000f, -1.279632424998f, +0.477592250073f, +0.049489956269f}; + +/** Initializes hal outputs class. This is called automatically by the +* enable function. It may be called any time the feature is enabled, but +* is typically not needed to be called by outside callers. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_init_hal_outputs(void) +{ + int i; + memset(&hal_out, 0, sizeof(hal_out)); + for (i=0; i<3; i++) { + inv_init_biquad_filter(&hal_out.lp_filter[i], compass_low_pass_filter_coeff); + } + + return INV_SUCCESS; +} + +/** Turns on creation and storage of HAL type results. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_enable_hal_outputs(void) +{ + inv_error_t result; + + // don't need to check the result for inv_init_hal_outputs + // since it's always INV_SUCCESS + inv_init_hal_outputs(); + + result = inv_register_mpl_start_notification(inv_start_hal_outputs); + return result; +} + +/** Turns off creation and storage of HAL type results. +*/ +inv_error_t inv_disable_hal_outputs(void) +{ + inv_error_t result; + + inv_stop_hal_outputs(); // Ignore error if we have already stopped this + result = inv_unregister_mpl_start_notification(inv_start_hal_outputs); + return result; +} + +/** + * @} + */ diff --git a/bsp/boards/mimsy2-cc2538/hal_outputs.h b/bsp/boards/mimsy2-cc2538/hal_outputs.h new file mode 100644 index 0000000000..a899beb04b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/hal_outputs.h @@ -0,0 +1,45 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" + +#ifndef INV_HAL_OUTPUTS_H__ +#define INV_HAL_OUTPUTS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + int inv_get_sensor_type_orientation(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_accelerometer(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_gyroscope(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_gyroscope_raw(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_magnetic_field(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_rotation_vector(float *values, int8_t *accuracy, + inv_time_t * timestamp); + + int inv_get_sensor_type_linear_acceleration(float *values, + int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_gravity(float *values, int8_t *accuracy, + inv_time_t * timestamp); + + inv_error_t inv_enable_hal_outputs(void); + inv_error_t inv_disable_hal_outputs(void); + inv_error_t inv_init_hal_outputs(void); + inv_error_t inv_start_hal_outputs(void); + inv_error_t inv_stop_hal_outputs(void); + +#ifdef __cplusplus +} +#endif + +#endif // INV_HAL_OUTPUTS_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/headers/MPU9250_RegisterMap.h b/bsp/boards/mimsy2-cc2538/headers/MPU9250_RegisterMap.h new file mode 100644 index 0000000000..c5c5fc6921 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/MPU9250_RegisterMap.h @@ -0,0 +1,219 @@ +/****************************************************************************** +MPU9250_RegisterMap.h - MPU-9250 Digital Motion Processor Arduino Library +Jim Lindblom @ SparkFun Electronics +original creation date: November 23, 2016 +https://github.com/sparkfun/SparkFun_MPU9250_DMP_Arduino_Library + +This library implements motion processing functions of Invensense's MPU-9250. +It is based on their Emedded MotionDriver 6.12 library. + https://www.invensense.com/developers/software-downloads/ + +Development environment specifics: +Arduino IDE 1.6.12 +SparkFun 9DoF Razor IMU M0 + +Supported Platforms: +- ATSAMD21 (Arduino Zero, SparkFun SAMD21 Breakouts) +******************************************************************************/ +#ifndef _MPU9250_REGISTER_MAP_H_ +#define _MPU9250_REGISTER_MAP_H_ + +enum mpu9250_register { + MPU9250_SELF_TEST_X_GYRO = 0x00, + MPU9250_SELF_TEST_Y_GYRO = 0x01, + MPU9250_SELF_TEST_Z_GYRO = 0x02, + MPU9250_SELF_TEST_X_ACCEL = 0x0D, + MPU9250_SELF_TEST_Y_ACCEL = 0x0E, + MPU9250_SELF_TEST_Z_ACCEL = 0x0F, + MPU9250_XG_OFFSET_H = 0x13, + MPU9250_XG_OFFSET_L = 0x14, + MPU9250_YG_OFFSET_H = 0x15, + MPU9250_YG_OFFSET_L = 0x16, + MPU9250_ZG_OFFSET_H = 0x17, + MPU9250_ZG_OFFSET_L = 0x18, + MPU9250_SMPLRT_DIV = 0x19, + MPU9250_CONFIG = 0x1A, + MPU9250_GYRO_CONFIG = 0x1B, + MPU9250_ACCEL_CONFIG = 0x1C, + MPU9250_ACCEL_CONFIG_2 = 0x1D, + MPU9250_LP_ACCEL_ODR = 0x1E, + MPU9250_WOM_THR = 0x1F, + MPU9250_FIFO_EN = 0x23, + MPU9250_I2C_MST_CTRL = 0x24, + MPU9250_I2C_SLV0_ADDR = 0x25, + MPU9250_I2C_SLV0_REG = 0x26, + MPU9250_I2C_SLV0_CTRL = 0x27, + MPU9250_I2C_SLV1_ADDR = 0x28, + MPU9250_I2C_SLV1_REG = 0x29, + MPU9250_I2C_SLV1_CTRL = 0x2A, + MPU9250_I2C_SLV2_ADDR = 0x2B, + MPU9250_I2C_SLV2_REG = 0x2C, + MPU9250_I2C_SLV2_CTRL = 0x2D, + MPU9250_I2C_SLV3_ADDR = 0x2E, + MPU9250_I2C_SLV3_REG = 0x2F, + MPU9250_I2C_SLV3_CTRL = 0x30, + MPU9250_I2C_SLV4_ADDR = 0x31, + MPU9250_I2C_SLV4_REG = 0x32, + MPU9250_I2C_SLV4_DO = 0x33, + MPU9250_I2C_SLV4_CTRL = 0x34, + MPU9250_I2C_SLV4_DI = 0x35, + MPU9250_I2C_MST_STATUS = 0x36, + MPU9250_INT_PIN_CFG = 0x37, + MPU9250_INT_ENABLE = 0x38, + MPU9250_INT_STATUS = 0x3A, + MPU9250_ACCEL_XOUT_H = 0x3B, + MPU9250_ACCEL_XOUT_L = 0x3C, + MPU9250_ACCEL_YOUT_H = 0x3D, + MPU9250_ACCEL_YOUT_L = 0x3E, + MPU9250_ACCEL_ZOUT_H = 0x3F, + MPU9250_ACCEL_ZOUT_L = 0x40, + MPU9250_TEMP_OUT_H = 0x41, + MPU9250_TEMP_OUT_L = 0x42, + MPU9250_GYRO_XOUT_H = 0x43, + MPU9250_GYRO_XOUT_L = 0x44, + MPU9250_GYRO_YOUT_H = 0x45, + MPU9250_GYRO_YOUT_L = 0x46, + MPU9250_GYRO_ZOUT_H = 0x47, + MPU9250_GYRO_ZOUT_L = 0x48, + MPU9250_EXT_SENS_DATA_00 = 0x49, + MPU9250_EXT_SENS_DATA_01 = 0x4A, + MPU9250_EXT_SENS_DATA_02 = 0x4B, + MPU9250_EXT_SENS_DATA_03 = 0x4C, + MPU9250_EXT_SENS_DATA_04 = 0x4D, + MPU9250_EXT_SENS_DATA_05 = 0x4E, + MPU9250_EXT_SENS_DATA_06 = 0x4F, + MPU9250_EXT_SENS_DATA_07 = 0x50, + MPU9250_EXT_SENS_DATA_08 = 0x51, + MPU9250_EXT_SENS_DATA_09 = 0x52, + MPU9250_EXT_SENS_DATA_10 = 0x53, + MPU9250_EXT_SENS_DATA_11 = 0x54, + MPU9250_EXT_SENS_DATA_12 = 0x55, + MPU9250_EXT_SENS_DATA_13 = 0x56, + MPU9250_EXT_SENS_DATA_14 = 0x57, + MPU9250_EXT_SENS_DATA_15 = 0x58, + MPU9250_EXT_SENS_DATA_16 = 0x59, + MPU9250_EXT_SENS_DATA_17 = 0x5A, + MPU9250_EXT_SENS_DATA_18 = 0x5B, + MPU9250_EXT_SENS_DATA_19 = 0x5C, + MPU9250_EXT_SENS_DATA_20 = 0x5D, + MPU9250_EXT_SENS_DATA_21 = 0x5E, + MPU9250_EXT_SENS_DATA_22 = 0x5F, + MPU9250_EXT_SENS_DATA_23 = 0x60, + MPU9250_I2C_SLV0_DO = 0x63, + MPU9250_I2C_SLV1_DO = 0x64, + MPU9250_I2C_SLV2_DO = 0x65, + MPU9250_I2C_SLV3_DO = 0x66, + MPU9250_I2C_MST_DELAY_CTRL =0x67, + MPU9250_SIGNAL_PATH_RESET = 0x68, + MPU9250_MOT_DETECT_CTRL = 0x69, + MPU9250_USER_CTRL = 0x6A, + MPU9250_PWR_MGMT_1 = 0x6B, + MPU9250_PWR_MGMT_2 = 0x6C, + MPU9250_FIFO_COUNTH = 0x72, + MPU9250_FIFO_COUNTL = 0x73, + MPU9250_FIFO_R_W = 0x74, + MPU9250_WHO_AM_I = 0x75, + MPU9250_XA_OFFSET_H = 0x77, + MPU9250_XA_OFFSET_L = 0x78, + MPU9250_YA_OFFSET_H = 0x7A, + MPU9250_YA_OFFSET_L = 0x7B, + MPU9250_ZA_OFFSET_H = 0x7D, + MPU9250_ZA_OFFSET_L = 0x7E +}; + +enum interrupt_status_bits { + INT_STATUS_RAW_DATA_RDY_INT = 0, + INT_STATUS_FSYNC_INT = 3, + INT_STATUS_FIFO_OVERFLOW_INT = 4, + INT_STATUS_WOM_INT = 6, +}; + +enum gyro_config_bits { + GYRO_CONFIG_FCHOICE_B = 0, + GYRO_CONFIG_GYRO_FS_SEL = 3, + GYRO_CONFIG_ZGYRO_CTEN = 5, + GYRO_CONFIG_YGYRO_CTEN = 6, + GYRO_CONFIG_XGYRO_CTEN = 7, +}; +#define MPU9250_GYRO_FS_SEL_MASK 0x3 +#define MPU9250_GYRO_FCHOICE_MASK 0x3 + +enum accel_config_bit { + ACCEL_CONFIG_ACCEL_FS_SEL = 3, + ACCEL_CONFIG_AZ_ST_EN = 5, + ACCEL_CONFIG_AY_ST_EN = 6, + ACCEL_CONFIG_AX_ST_EN = 7, +}; +#define MPU9250_ACCEL_FS_SEL_MASK 0x3 + +enum accel_config_2_bits { + ACCEL_CONFIG_2_A_DLPFCFG = 0, + ACCEL_CONFIG_2_ACCEL_FCHOICE_B = 3, +}; + +enum pwr_mgmt_1_bits { + PWR_MGMT_1_CLKSEL = 0, + PWR_MGMT_1_PD_PTAT = 3, + PWR_MGMT_1_GYRO_STANDBY = 4, + PWR_MGMT_1_CYCLE = 5, + PWR_MGMT_1_SLEEP = 6, + PWR_MGMT_1_H_RESET = 7 +}; + +enum pwr_mgmt_2_bits { + PWR_MGMT_2_DISABLE_ZG = 0, + PWR_MGMT_2_DISABLE_YG = 1, + PWR_MGMT_2_DISABLE_XG = 2, + PWR_MGMT_2_DISABLE_ZA = 3, + PWR_MGMT_2_DISABLE_YA = 4, + PWR_MGMT_2_DISABLE_XA = 5, +}; + +enum int_enable_bits { + INT_ENABLE_RAW_RDY_EN = 0, + INT_ENABLE_FSYNC_INT_EN = 3, + INT_ENABLE_FIFO_OVERFLOW_EN = 4, + INT_ENABLE_WOM_EN = 6, +}; + +enum int_pin_cfg_bits { + INT_PIN_CFG_BYPASS_EN = 1, + INT_PIN_CFG_FSYNC_INT_MODE_EN = 2, + INT_PIN_CFG_ACTL_FSYNC = 3, + INT_PIN_CFG_INT_ANYRD_2CLEAR = 4, + INT_PIN_CFG_LATCH_INT_EN = 5, + INT_PIN_CFG_OPEN = 6, + INT_PIN_CFG_ACTL = 7, +}; +#define INT_PIN_CFG_INT_MASK 0xF0 + +#define MPU9250_WHO_AM_I_RESULT 0x71 + +enum ak8963_register { + AK8963_WIA = 0x0, + AK8963_INFO = 0x1, + AK8963_ST1 = 0x2, + AK8963_HXL = 0x3, + AK8963_HXH = 0x4, + AK8963_HYL = 0x5, + AK8963_HYH = 0x6, + AK8963_HZL = 0x7, + AK8963_HZH = 0x8, + AK8963_ST2 = 0x9, + AK8963_CNTL = 0xA, + AK8963_RSV = 0xB, + AK8963_ASTC = 0xC, + AK8963_TS1 = 0xD, + AK8963_TS2 = 0xE, + AK8963_I2CDIS = 0xF, + AK8963_ASAX = 0x10, + AK8963_ASAY = 0x11, + AK8963_ASAZ = 0x12, +}; +#define MAG_CTRL_OP_MODE_MASK 0xF + +#define AK8963_ST1_DRDY_BIT 0 + +#define AK8963_WHO_AM_I_RESULT 0x48 + +#endif // _MPU9250_REGISTER_MAP_H_ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_aes.h b/bsp/boards/mimsy2-cc2538/headers/hw_aes.h new file mode 100644 index 0000000000..d1d23e2078 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_aes.h @@ -0,0 +1,4379 @@ +/****************************************************************************** +* Filename: hw_aes.h +* Revised: $Date: 2013-04-12 15:10:54 +0200 (Fri, 12 Apr 2013) $ +* Revision: $Revision: 9735 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_AES_H__ +#define __HW_AES_H__ + +//***************************************************************************** +// +// The following are defines for the AES register offsets. +// +//***************************************************************************** +#define AES_DMAC_CH0_CTRL 0x4008B000 // Channel control This register + // is used for channel enabling and + // priority selection. When a + // channel is disabled, it becomes + // inactive only when all ongoing + // requests are finished. +#define AES_DMAC_CH0_EXTADDR 0x4008B004 // Channel external address +#define AES_DMAC_CH0_DMALENGTH \ + 0x4008B00C // Channel DMA length + +#define AES_DMAC_STATUS 0x4008B018 // DMAC status This register + // provides the actual state of + // each DMA channel. It also + // reports port errors in case + // these were received by the + // master interface module during + // the data transfer. +#define AES_DMAC_SWRES 0x4008B01C // DMAC software reset register + // Software reset is used to reset + // the DMAC to stop all transfers + // and clears the port error status + // register. After the software + // reset is performed, all the + // channels are disabled and no new + // requests are performed by the + // channels. The DMAC waits for the + // existing (active) requests to + // finish and accordingly sets the + // DMAC status registers. +#define AES_DMAC_CH1_CTRL 0x4008B020 // Channel control This register + // is used for channel enabling and + // priority selection. When a + // channel is disabled, it becomes + // inactive only when all ongoing + // requests are finished. +#define AES_DMAC_CH1_EXTADDR 0x4008B024 // Channel external address +#define AES_DMAC_CH1_DMALENGTH \ + 0x4008B02C // Channel DMA length + +#define AES_DMAC_MST_RUNPARAMS \ + 0x4008B078 // DMAC master run-time parameters + // This register defines all the + // run-time parameters for the AHB + // master interface port. These + // parameters are required for the + // proper functioning of the + // EIP-101m AHB master adapter. + +#define AES_DMAC_PERSR 0x4008B07C // DMAC port error raw status + // register This register provides + // the actual status of individual + // port errors. It also indicates + // which channel is serviced by an + // external AHB port (which is + // frozen by a port error). A port + // error aborts operations on all + // serviced channels (channel + // enable bit is forced to 0) and + // prevents further transfers via + // that port until the error is + // cleared by writing to the + // DMAC_SWRES register. +#define AES_DMAC_OPTIONS 0x4008B0F8 // DMAC options register These + // registers contain information + // regarding the different options + // configured in this DMAC. +#define AES_DMAC_VERSION 0x4008B0FC // DMAC version register This + // register contains an indication + // (or signature) of the EIP type + // of this DMAC, as well as the + // hardware version/patch numbers. +#define AES_KEY_STORE_WRITE_AREA \ + 0x4008B400 // Key store write area register + // This register defines where the + // keys should be written in the + // key store RAM. After writing + // this register, the key store + // module is ready to receive the + // keys through a DMA operation. In + // case the key data transfer + // triggered an error in the key + // store, the error will be + // available in the interrupt + // status register after the DMA is + // finished. The key store + // write-error is asserted when the + // programmed/selected area is not + // completely written. This error + // is also asserted when the DMA + // operation writes to ram areas + // that are not selected. The key + // store RAM is divided into 8 + // areas of 128 bits. 192-bit keys + // written in the key store RAM + // should start on boundaries of + // 256 bits. This means that + // writing a 192-bit key to the key + // store RAM must be done by + // writing 256 bits of data with + // the 64 most-significant bits set + // to 0. These bits are ignored by + // the AES engine. + +#define AES_KEY_STORE_WRITTEN_AREA \ + 0x4008B404 // Key store written area register + // This register shows which areas + // of the key store RAM contain + // valid written keys. When a new + // key needs to be written to the + // key store, on a location that is + // already occupied by a valid key, + // this key area must be cleared + // first. This can be done by + // writing this register before the + // new key is written to the key + // store memory. Attempting to + // write to a key area that already + // contains a valid key is not + // allowed and results in an error. + +#define AES_KEY_STORE_SIZE 0x4008B408 // Key store size register This + // register defines the size of the + // keys that are written with DMA. + // This register should be + // configured before writing to the + // KEY_STORE_WRITE_AREA register. +#define AES_KEY_STORE_READ_AREA \ + 0x4008B40C // Key store read area register + // This register selects the key + // store RAM area from where the + // key needs to be read that will + // be used for an AES operation. + // The operation directly starts + // after writing this register. + // When the operation is finished, + // the status of the key store read + // operation is available in the + // interrupt status register. Key + // store read error is asserted + // when a RAM area is selected + // which does not contain valid + // written key. + +#define AES_AES_KEY2_0 0x4008B500 // AES_KEY2_0 / AES_GHASH_H_IN_0 + // Second Key / GHASH Key + // (internal, but clearable) The + // following registers are not + // accessible through the host for + // reading and writing. They are + // used to store internally + // calculated key information and + // intermediate results. However, + // when the host performs a write + // to the any of the respective + // AES_KEY2_n or AES_KEY3_n + // addresses, respectively the + // whole 128-bit AES_KEY2_n or + // AES_KEY3_n register is cleared + // to 0s. The AES_GHASH_H_IN_n + // registers (required for GHASH, + // which is part of GCM) are mapped + // to the AES_KEY2_n registers. The + // (intermediate) authentication + // result for GCM and CCM is stored + // in the AES_KEY3_n register. +#define AES_AES_KEY2_1 0x4008B504 // AES_KEY2_1 / AES_GHASH_H_IN_1 + // Second Key / GHASH Key + // (internal, but clearable) The + // following registers are not + // accessible through the host for + // reading and writing. They are + // used to store internally + // calculated key information and + // intermediate results. However, + // when the host performs a write + // to the any of the respective + // AES_KEY2_n or AES_KEY3_n + // addresses, respectively the + // whole 128-bit AES_KEY2_n or + // AES_KEY3_n register is cleared + // to 0s. The AES_GHASH_H_IN_n + // registers (required for GHASH, + // which is part of GCM) are mapped + // to the AES_KEY2_n registers. The + // (intermediate) authentication + // result for GCM and CCM is stored + // in the AES_KEY3_n register. +#define AES_AES_KEY2_2 0x4008B508 // AES_KEY2_2 / AES_GHASH_H_IN_2 + // Second Key / GHASH Key + // (internal, but clearable) The + // following registers are not + // accessible through the host for + // reading and writing. They are + // used to store internally + // calculated key information and + // intermediate results. However, + // when the host performs a write + // to the any of the respective + // AES_KEY2_n or AES_KEY3_n + // addresses, respectively the + // whole 128-bit AES_KEY2_n or + // AES_KEY3_n register is cleared + // to 0s. The AES_GHASH_H_IN_n + // registers (required for GHASH, + // which is part of GCM) are mapped + // to the AES_KEY2_n registers. The + // (intermediate) authentication + // result for GCM and CCM is stored + // in the AES_KEY3_n register. +#define AES_AES_KEY2_3 0x4008B50C // AES_KEY2_3 / AES_GHASH_H_IN_3 + // Second Key / GHASH Key + // (internal, but clearable) The + // following registers are not + // accessible through the host for + // reading and writing. They are + // used to store internally + // calculated key information and + // intermediate results. However, + // when the host performs a write + // to the any of the respective + // AES_KEY2_n or AES_KEY3_n + // addresses, respectively the + // whole 128-bit AES_KEY2_n or + // AES_KEY3_n register is cleared + // to 0s. The AES_GHASH_H_IN_n + // registers (required for GHASH, + // which is part of GCM) are mapped + // to the AES_KEY2_n registers. The + // (intermediate) authentication + // result for GCM and CCM is stored + // in the AES_KEY3_n register. +#define AES_AES_KEY3_0 0x4008B510 // AES_KEY3_0 / AES_KEY2_4 Third + // Key / Second Key (internal, but + // clearable) The following + // registers are not accessible + // through the host for reading and + // writing. They are used to store + // internally calculated key + // information and intermediate + // results. However, when the host + // performs a write to the any of + // the respective AES_KEY2_n or + // AES_KEY3_n addresses, + // respectively the whole 128-bit + // AES_KEY2_n or AES_KEY3_n + // register is cleared to 0s. The + // AES_GHASH_H_IN_n registers + // (required for GHASH, which is + // part of GCM) are mapped to the + // AES_KEY2_n registers. The + // (intermediate) authentication + // result for GCM and CCM is stored + // in the AES_KEY3_n register. +#define AES_AES_KEY3_1 0x4008B514 // AES_KEY3_1 / AES_KEY2_5 Third + // Key / Second Key (internal, but + // clearable) The following + // registers are not accessible + // through the host for reading and + // writing. They are used to store + // internally calculated key + // information and intermediate + // results. However, when the host + // performs a write to the any of + // the respective AES_KEY2_n or + // AES_KEY3_n addresses, + // respectively the whole 128-bit + // AES_KEY2_n or AES_KEY3_n + // register is cleared to 0s. The + // AES_GHASH_H_IN_n registers + // (required for GHASH, which is + // part of GCM) are mapped to the + // AES_KEY2_n registers. The + // (intermediate) authentication + // result for GCM and CCM is stored + // in the AES_KEY3_n register. +#define AES_AES_KEY3_2 0x4008B518 // AES_KEY3_2 / AES_KEY2_6 Third + // Key / Second Key (internal, but + // clearable) The following + // registers are not accessible + // through the host for reading and + // writing. They are used to store + // internally calculated key + // information and intermediate + // results. However, when the host + // performs a write to the any of + // the respective AES_KEY2_n or + // AES_KEY3_n addresses, + // respectively the whole 128-bit + // AES_KEY2_n or AES_KEY3_n + // register is cleared to 0s. The + // AES_GHASH_H_IN_n registers + // (required for GHASH, which is + // part of GCM) are mapped to the + // AES_KEY2_n registers. The + // (intermediate) authentication + // result for GCM and CCM is stored + // in the AES_KEY3_n register. +#define AES_AES_KEY3_3 0x4008B51C // AES_KEY3_3 / AES_KEY2_7 Third + // Key / Second Key (internal, but + // clearable) The following + // registers are not accessible + // through the host for reading and + // writing. They are used to store + // internally calculated key + // information and intermediate + // results. However, when the host + // performs a write to the any of + // the respective AES_KEY2_n or + // AES_KEY3_n addresses, + // respectively the whole 128-bit + // AES_KEY2_n or AES_KEY3_n + // register is cleared to 0s. The + // AES_GHASH_H_IN_n registers + // (required for GHASH, which is + // part of GCM) are mapped to the + // AES_KEY2_n registers. The + // (intermediate) authentication + // result for GCM and CCM is stored + // in the AES_KEY3_n register. +#define AES_AES_IV_0 0x4008B540 // AES initialization vector + // registers These registers are + // used to provide and read the IV + // from the AES engine. +#define AES_AES_IV_1 0x4008B544 // AES initialization vector + // registers These registers are + // used to provide and read the IV + // from the AES engine. +#define AES_AES_IV_2 0x4008B548 // AES initialization vector + // registers These registers are + // used to provide and read the IV + // from the AES engine. +#define AES_AES_IV_3 0x4008B54C // AES initialization vector + // registers These registers are + // used to provide and read the IV + // from the AES engine. +#define AES_AES_CTRL 0x4008B550 // AES input/output buffer control + // and mode register This register + // specifies the AES mode of + // operation for the EIP-120t. + // Electronic codebook (ECB) mode + // is automatically selected if + // bits [28:5] of this register are + // all 0. +#define AES_AES_C_LENGTH_0 0x4008B554 // AES crypto length registers + // (LSW) These registers are used + // to write the Length values to + // the EIP-120t. While processing, + // the length values decrement to + // 0. If both lengths are 0, the + // data stream is finished and a + // new context is requested. For + // basic AES modes (ECB, CBC, and + // CTR), a crypto length of 0 can + // be written if multiple streams + // need to be processed with the + // same key. Writing 0 length + // results in continued data + // requests until a new context is + // written. For the other modes + // (CBC-MAC, GCM, and CCM) no (new) + // data requests are done if the + // length decrements to or equals + // 0. It is advised to write a new + // length per packet. If the length + // registers decrement to 0, no new + // data is processed until a new + // context or length value is + // written. When writing a new mode + // without writing the length + // registers, the length register + // values from the previous context + // is reused. +#define AES_AES_C_LENGTH_1 0x4008B558 // AES crypto length registers + // (MSW) These registers are used + // to write the Length values to + // the EIP-120t. While processing, + // the length values decrement to + // 0. If both lengths are 0, the + // data stream is finished and a + // new context is requested. For + // basic AES modes (ECB, CBC, and + // CTR), a crypto length of 0 can + // be written if multiple streams + // need to be processed with the + // same key. Writing 0 length + // results in continued data + // requests until a new context is + // written. For the other modes + // (CBC-MAC, GCM and CCM) no (new) + // data requests are done if the + // length decrements to or equals + // 0. It is advised to write a new + // length per packet. If the length + // registers decrement to 0, no new + // data is processed until a new + // context or length value is + // written. When writing a new mode + // without writing the length + // registers, the length register + // values from the previous context + // is reused. +#define AES_AES_AUTH_LENGTH 0x4008B55C // Authentication length register +#define AES_AES_DATA_IN_OUT_0 0x4008B560 // Data input/output registers The + // data registers are typically + // accessed through the DMA and not + // with host writes and/or reads. + // However, for debugging purposes + // the data input/output registers + // can be accessed via host write + // and read operations. The + // registers are used to buffer the + // input/output data blocks to/from + // the EIP-120t. Note: The data + // input buffer (AES_DATA_IN_n) and + // data output buffer + // (AES_DATA_OUT_n) are mapped to + // the same address locations. + // Writes (both DMA and host) to + // these addresses load the Input + // Buffer while reads pull from the + // Output Buffer. Therefore, for + // write access, the data input + // buffer is written; for read + // access, the data output buffer + // is read. The data input buffer + // must be written before starting + // an operation. The data output + // buffer contains valid data on + // completion of an operation. + // Therefore, any 128-bit data + // block can be split over multiple + // 32-bit word transfers; these can + // be mixed with other host + // transfers over the external + // interface. +#define AES_AES_DATA_IN_OUT_1 0x4008B564 // Data Input/Output Registers The + // data registers are typically + // accessed via DMA and not with + // host writes and/or reads. + // However, for debugging purposes + // the Data Input/Output Registers + // can be accessed via host write + // and read operations. The + // registers are used to buffer the + // input/output data blocks to/from + // the EIP-120t. Note: The data + // input buffer (AES_DATA_IN_n) and + // data output buffer + // (AES_DATA_OUT_n) are mapped to + // the same address locations. + // Writes (both DMA and host) to + // these addresses load the Input + // Buffer while reads pull from the + // Output Buffer. Therefore, for + // write access, the data input + // buffer is written; for read + // access, the data output buffer + // is read. The data input buffer + // must be written before starting + // an operation. The data output + // buffer contains valid data on + // completion of an operation. + // Therefore, any 128-bit data + // block can be split over multiple + // 32-bit word transfers; these can + // be mixed with other host + // transfers over the external + // interface. +#define AES_AES_DATA_IN_OUT_2 0x4008B568 // Data Input/Output Registers The + // data registers are typically + // accessed via DMA and not with + // host writes and/or reads. + // However, for debugging purposes + // the Data Input/Output Registers + // can be accessed via host write + // and read operations. The + // registers are used to buffer the + // input/output data blocks to/from + // the EIP-120t. Note: The data + // input buffer (AES_DATA_IN_n) and + // data output buffer + // (AES_DATA_OUT_n) are mapped to + // the same address locations. + // Writes (both DMA and host) to + // these addresses load the Input + // Buffer while reads pull from the + // Output Buffer. Therefore, for + // write access, the data input + // buffer is written; for read + // access, the data output buffer + // is read. The data input buffer + // must be written before starting + // an operation. The data output + // buffer contains valid data on + // completion of an operation. + // Therefore, any 128-bit data + // block can be split over multiple + // 32-bit word transfers; these can + // be mixed with other host + // transfers over the external + // interface. +#define AES_AES_DATA_IN_OUT_3 0x4008B56C // Data Input/Output Registers The + // data registers are typically + // accessed via DMA and not with + // host writes and/or reads. + // However, for debugging purposes + // the Data Input/Output Registers + // can be accessed via host write + // and read operations. The + // registers are used to buffer the + // input/output data blocks to/from + // the EIP-120t. Note: The data + // input buffer (AES_DATA_IN_n) and + // data output buffer + // (AES_DATA_OUT_n) are mapped to + // the same address locations. + // Writes (both DMA and host) to + // these addresses load the Input + // Buffer while reads pull from the + // Output Buffer. Therefore, for + // write access, the data input + // buffer is written; for read + // access, the data output buffer + // is read. The data input buffer + // must be written before starting + // an operation. The data output + // buffer contains valid data on + // completion of an operation. + // Therefore, any 128-bit data + // block can be split over multiple + // 32-bit word transfers; these can + // be mixed with other host + // transfers over the external + // interface. +#define AES_AES_TAG_OUT_0 0x4008B570 // TAG registers The tag registers + // can be accessed via DMA or + // directly with host reads. These + // registers buffer the TAG from + // the EIP-120t. The registers are + // shared with the intermediate + // authentication result registers, + // but cannot be read until the + // processing is finished. While + // processing, a read from these + // registers returns 0s. If an + // operation does not return a TAG, + // reading from these registers + // returns an IV. If an operation + // returns a TAG plus an IV and + // both need to be read by the + // host, the host must first read + // the TAG followed by the IV. + // Reading these in reverse order + // will return the IV twice. +#define AES_AES_TAG_OUT_1 0x4008B574 // TAG registers The tag registers + // can be accessed via DMA or + // directly with host reads. These + // registers buffer the TAG from + // the EIP-120t. The registers are + // shared with the intermediate + // authentication result registers, + // but cannot be read until the + // processing is finished. While + // processing, a read from these + // registers returns 0s. If an + // operation does not return a TAG, + // reading from these registers + // returns an IV. If an operation + // returns a TAG plus an IV and + // both need to be read by the + // host, the host must first read + // the TAG followed by the IV. + // Reading these in reverse order + // returns the IV twice. +#define AES_AES_TAG_OUT_2 0x4008B578 // TAG registers The tag registers + // can be accessed via DMA or + // directly with host reads. These + // registers buffer the TAG from + // the EIP-120t. The registers are + // shared with the intermediate + // authentication result registers, + // but cannot be read until the + // processing is finished. While + // processing, a read from these + // registers returns 0s. If an + // operation does not return a TAG, + // reading from these registers + // returns an IV. If an operation + // returns a TAG plus an IV and + // both need to be read by the + // host, the host must first read + // the TAG followed by the IV. + // Reading these in reverse order + // returns the IV twice. +#define AES_AES_TAG_OUT_3 0x4008B57C // TAG registers The tag registers + // can be accessed via DMA or + // directly with host reads. These + // registers buffer the TAG from + // the EIP-120t. The registers are + // shared with the intermediate + // authentication result registers, + // but cannot be read until the + // processing is finished. While + // processing, a read from these + // registers returns 0s. If an + // operation does not return a TAG, + // reading from these registers + // returns an IV. If an operation + // returns a TAG plus an IV and + // both need to be read by the + // host, the host must first read + // the TAG followed by the IV. + // Reading these in reverse order + // returns the IV twice. +#define AES_HASH_DATA_IN_0 0x4008B600 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_1 0x4008B604 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_2 0x4008B608 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_3 0x4008B60C // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_4 0x4008B610 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_5 0x4008B614 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_6 0x4008B618 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_7 0x4008B61C // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_8 0x4008B620 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_9 0x4008B624 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_10 0x4008B628 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_11 0x4008B62C // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_12 0x4008B630 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_13 0x4008B634 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_14 0x4008B638 // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_DATA_IN_15 0x4008B63C // HASH data input registers The + // data input registers should be + // used to provide input data to + // the hash module through the + // slave interface. +#define AES_HASH_IO_BUF_CTRL 0x4008B640 // Input/output buffer control and + // status register This register + // pair shares a single address + // location and contains bits that + // control and monitor the data + // flow between the host and the + // hash engine. +#define AES_HASH_MODE_IN 0x4008B644 // Hash mode register +#define AES_HASH_LENGTH_IN_L 0x4008B648 // Hash length register +#define AES_HASH_LENGTH_IN_H 0x4008B64C // Hash length register +#define AES_HASH_DIGEST_A 0x4008B650 // Hash digest registers The hash + // digest registers consist of + // eight 32-bit registers, named + // HASH_DIGEST_A to HASH_DIGEST_H. + // After processing a message, the + // output digest can be read from + // these registers. These registers + // can be written with an + // intermediate hash result for + // continued hash operations. +#define AES_HASH_DIGEST_B 0x4008B654 // Hash digest registers The hash + // digest registers consist of + // eight 32-bit registers, named + // HASH_DIGEST_A to HASH_DIGEST_H. + // After processing a message, the + // output digest can be read from + // these registers. These registers + // can be written with an + // intermediate hash result for + // continued hash operations. +#define AES_HASH_DIGEST_C 0x4008B658 // Hash digest registers The hash + // digest registers consist of + // eight 32-bit registers, named + // HASH_DIGEST_A to HASH_DIGEST_H. + // After processing a message, the + // output digest can be read from + // these registers. These registers + // can be written with an + // intermediate hash result for + // continued hash operations. +#define AES_HASH_DIGEST_D 0x4008B65C // Hash digest registers The hash + // digest registers consist of + // eight 32-bit registers, named + // HASH_DIGEST_A to HASH_DIGEST_H. + // After processing a message, the + // output digest can be read from + // these registers. These registers + // can be written with an + // intermediate hash result for + // continued hash operations. +#define AES_HASH_DIGEST_E 0x4008B660 // Hash digest registers The hash + // digest registers consist of + // eight 32-bit registers, named + // HASH_DIGEST_A to HASH_DIGEST_H. + // After processing a message, the + // output digest can be read from + // these registers. These registers + // can be written with an + // intermediate hash result for + // continued hash operations. +#define AES_HASH_DIGEST_F 0x4008B664 // Hash digest registers The hash + // digest registers consist of + // eight 32-bit registers, named + // HASH_DIGEST_A to HASH_DIGEST_H. + // After processing a message, the + // output digest can be read from + // these registers. These registers + // can be written with an + // intermediate hash result for + // continued hash operations. +#define AES_HASH_DIGEST_G 0x4008B668 // Hash digest registers The hash + // digest registers consist of + // eight 32-bit registers, named + // HASH_DIGEST_A to HASH_DIGEST_H. + // After processing a message, the + // output digest can be read from + // these registers. These registers + // can be written with an + // intermediate hash result for + // continued hash operations. +#define AES_HASH_DIGEST_H 0x4008B66C // Hash digest registers The hash + // digest registers consist of + // eight 32-bit registers, named + // HASH_DIGEST_A to HASH_DIGEST_H. + // After processing a message, the + // output digest can be read from + // these registers. These registers + // can be written with an + // intermediate hash result for + // continued hash operations. +#define AES_CTRL_ALG_SEL 0x4008B700 // Algorithm select This algorithm + // selection register configures + // the internal destination of the + // DMA controller. +#define AES_CTRL_PROT_EN 0x4008B704 // Master PROT privileged access + // enable This register enables the + // second bit (bit [1]) of the AHB + // HPROT bus of the AHB master + // interface when a read action of + // key(s) is performed on the AHB + // master interface for writing + // keys into the store module. +#define AES_CTRL_SW_RESET 0x4008B740 // Software reset +#define AES_CTRL_INT_CFG 0x4008B780 // Interrupt configuration +#define AES_CTRL_INT_EN 0x4008B784 // Interrupt enable +#define AES_CTRL_INT_CLR 0x4008B788 // Interrupt clear +#define AES_CTRL_INT_SET 0x4008B78C // Interrupt set +#define AES_CTRL_INT_STAT 0x4008B790 // Interrupt status +#define AES_CTRL_OPTIONS 0x4008B7F8 // Options register +#define AES_CTRL_VERSION 0x4008B7FC // Version register + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_CH0_CTRL register. +// +//***************************************************************************** +#define AES_DMAC_CH0_CTRL_PRIO 0x00000002 // Channel priority 0: Low 1: High + // If both channels have the same + // priority, access of the channels + // to the external port is + // arbitrated using the round robin + // scheme. If one channel has a + // high priority and another one + // low, the channel with the high + // priority is served first, in + // case of simultaneous access + // requests. +#define AES_DMAC_CH0_CTRL_PRIO_M \ + 0x00000002 +#define AES_DMAC_CH0_CTRL_PRIO_S 1 +#define AES_DMAC_CH0_CTRL_EN 0x00000001 // Channel enable 0: Disabled 1: + // Enable Note: Disabling an active + // channel interrupts the DMA + // operation. The ongoing block + // transfer completes, but no new + // transfers are requested. +#define AES_DMAC_CH0_CTRL_EN_M 0x00000001 +#define AES_DMAC_CH0_CTRL_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_CH0_EXTADDR register. +// +//***************************************************************************** +#define AES_DMAC_CH0_EXTADDR_ADDR_M \ + 0xFFFFFFFF // Channel external address value + // When read during operation, it + // holds the last updated external + // address after being sent to the + // master interface. + +#define AES_DMAC_CH0_EXTADDR_ADDR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_CH0_DMALENGTH register. +// +//***************************************************************************** +#define AES_DMAC_CH0_DMALENGTH_DMALEN_M \ + 0x0000FFFF // Channel DMA length in bytes + // During configuration, this + // register contains the DMA + // transfer length in bytes. During + // operation, it contains the last + // updated value of the DMA + // transfer length after being sent + // to the master interface. Note: + // Setting this register to a + // nonzero value starts the + // transfer if the channel is + // enabled. Therefore, this + // register must be written last + // when setting up a DMA channel. + +#define AES_DMAC_CH0_DMALENGTH_DMALEN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_STATUS register. +// +//***************************************************************************** +#define AES_DMAC_STATUS_PORT_ERR \ + 0x00020000 // Reflects possible transfer + // errors on the AHB port. + +#define AES_DMAC_STATUS_PORT_ERR_M \ + 0x00020000 +#define AES_DMAC_STATUS_PORT_ERR_S 17 +#define AES_DMAC_STATUS_CH1_ACT 0x00000002 // A value of 1 indicates that + // channel 1 is active (DMA + // transfer on-going). +#define AES_DMAC_STATUS_CH1_ACT_M \ + 0x00000002 +#define AES_DMAC_STATUS_CH1_ACT_S 1 +#define AES_DMAC_STATUS_CH0_ACT 0x00000001 // A value of 1 indicates that + // channel 0 is active (DMA + // transfer on-going). +#define AES_DMAC_STATUS_CH0_ACT_M \ + 0x00000001 +#define AES_DMAC_STATUS_CH0_ACT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_SWRES register. +// +//***************************************************************************** +#define AES_DMAC_SWRES_SWRES 0x00000001 // Software reset enable 0 = + // Disabled 1 = Enabled + // (self-cleared to 0) Completion + // of the software reset must be + // checked through the DMAC_STATUS + // register. +#define AES_DMAC_SWRES_SWRES_M 0x00000001 +#define AES_DMAC_SWRES_SWRES_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_CH1_CTRL register. +// +//***************************************************************************** +#define AES_DMAC_CH1_CTRL_PRIO 0x00000002 // Channel priority 0: Low 1: High + // If both channels have the same + // priority, access of the channels + // to the external port is + // arbitrated using the round robin + // scheme. If one channel has a + // high priority and another one + // low, the channel with the high + // priority is served first, in + // case of simultaneous access + // requests. +#define AES_DMAC_CH1_CTRL_PRIO_M \ + 0x00000002 +#define AES_DMAC_CH1_CTRL_PRIO_S 1 +#define AES_DMAC_CH1_CTRL_EN 0x00000001 // Channel enable 0: Disabled 1: + // Enable Note: Disabling an active + // channel interrupts the DMA + // operation. The ongoing block + // transfer completes, but no new + // transfers are requested. +#define AES_DMAC_CH1_CTRL_EN_M 0x00000001 +#define AES_DMAC_CH1_CTRL_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_CH1_EXTADDR register. +// +//***************************************************************************** +#define AES_DMAC_CH1_EXTADDR_ADDR_M \ + 0xFFFFFFFF // Channel external address value. + // When read during operation, it + // holds the last updated external + // address after being sent to the + // master interface. + +#define AES_DMAC_CH1_EXTADDR_ADDR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_CH1_DMALENGTH register. +// +//***************************************************************************** +#define AES_DMAC_CH1_DMALENGTH_DMALEN_M \ + 0x0000FFFF // Channel DMA length in bytes. + // During configuration, this + // register contains the DMA + // transfer length in bytes. During + // operation, it contains the last + // updated value of the DMA + // transfer length after being sent + // to the master interface. Note: + // Setting this register to a + // nonzero value starts the + // transfer if the channel is + // enabled. Therefore, this + // register must be written last + // when setting up a DMA channel. + +#define AES_DMAC_CH1_DMALENGTH_DMALEN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_MST_RUNPARAMS register. +// +//***************************************************************************** +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_M \ + 0x0000F000 // Maximum burst size that can be + // performed on the AHB bus 0010b = + // 4 bytes (default) 0011b = 8 + // bytes 0100b = 16 bytes 0101b = + // 32 bytes 0110b = 64 bytes Others + // = Reserved + +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_S 12 +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_IDLE_EN \ + 0x00000800 // Idle insertion between + // consecutive burst transfers on + // AHB 0: No Idle insertion 1: Idle + // insertion + +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_IDLE_EN_M \ + 0x00000800 +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_IDLE_EN_S 11 +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_INCR_EN \ + 0x00000400 // Burst length type of AHB + // transfer 0: Unspecified length + // burst transfers 1: Fixed length + // burst or single transfers + +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_INCR_EN_M \ + 0x00000400 +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_INCR_EN_S 10 +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_LOCK_EN \ + 0x00000200 // Locked transform on AHB 0: + // Transfers are not locked 1: + // Transfers are locked + +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_LOCK_EN_M \ + 0x00000200 +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_LOCK_EN_S 9 +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BIGEND \ + 0x00000100 // Endianess for the AHB master 0: + // Little endian 1: Big endian + +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BIGEND_M \ + 0x00000100 +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BIGEND_S 8 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_PERSR register. +// +//***************************************************************************** +#define AES_DMAC_PERSR_PORT1_AHB_ERROR \ + 0x00001000 // A value of 1 indicates that the + // EIP-101 has detected an AHB bus + // error + +#define AES_DMAC_PERSR_PORT1_AHB_ERROR_M \ + 0x00001000 +#define AES_DMAC_PERSR_PORT1_AHB_ERROR_S 12 +#define AES_DMAC_PERSR_PORT1_CHANNEL \ + 0x00000200 // Indicates which channel has + // serviced last (channel 0 or + // channel 1) by AHB master port. + +#define AES_DMAC_PERSR_PORT1_CHANNEL_M \ + 0x00000200 +#define AES_DMAC_PERSR_PORT1_CHANNEL_S 9 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_OPTIONS register. +// +//***************************************************************************** +#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_M \ + 0x00000F00 // Number of channels implemented, + // value in the range 1-8. + +#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_S 8 +#define AES_DMAC_OPTIONS_NR_OF_PORTS_M \ + 0x00000007 // Number of ports implemented, + // value in range 1-4. + +#define AES_DMAC_OPTIONS_NR_OF_PORTS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_DMAC_VERSION register. +// +//***************************************************************************** +#define AES_DMAC_VERSION_HW_MAJOR_VERSION_M \ + 0x0F000000 // Major version number + +#define AES_DMAC_VERSION_HW_MAJOR_VERSION_S 24 +#define AES_DMAC_VERSION_HW_MINOR_VERSION_M \ + 0x00F00000 // Minor version number + +#define AES_DMAC_VERSION_HW_MINOR_VERSION_S 20 +#define AES_DMAC_VERSION_HW_PATCH_LEVEL_M \ + 0x000F0000 // Patch level Starts at 0 at + // first delivery of this version + +#define AES_DMAC_VERSION_HW_PATCH_LEVEL_S 16 +#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_M \ + 0x0000FF00 // Bit-by-bit complement of the + // EIP_NUMBER field bits. + +#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_S 8 +#define AES_DMAC_VERSION_EIP_NUMBER_M \ + 0x000000FF // Binary encoding of the + // EIP-number of this DMA + // controller (209) + +#define AES_DMAC_VERSION_EIP_NUMBER_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_KEY_STORE_WRITE_AREA register. +// +//***************************************************************************** +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA7 \ + 0x00000080 // Each RAM_AREAx represents an + // area of 128 bits. Select the key + // store RAM area(s) where the + // key(s) needs to be written 0: + // RAM_AREA7 is not selected to be + // written. 1: RAM_AREA7 is + // selected to be written. Writing + // to multiple RAM locations is + // possible only when the selected + // RAM areas are sequential. Keys + // that require more than one RAM + // locations (key size is 192 or + // 256 bits), must start at one of + // the following areas: RAM_AREA0, + // RAM_AREA2, RAM_AREA4, or + // RAM_AREA6. + +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA7_M \ + 0x00000080 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA7_S 7 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA6 \ + 0x00000040 // Each RAM_AREAx represents an + // area of 128 bits. Select the key + // store RAM area(s) where the + // key(s) needs to be written 0: + // RAM_AREA6 is not selected to be + // written. 1: RAM_AREA6 is + // selected to be written. Writing + // to multiple RAM locations is + // possible only when the selected + // RAM areas are sequential. Keys + // that require more than one RAM + // locations (key size is 192 or + // 256 bits), must start at one of + // the following areas: RAM_AREA0, + // RAM_AREA2, RAM_AREA4, or + // RAM_AREA6. + +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA6_M \ + 0x00000040 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA6_S 6 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA5 \ + 0x00000020 // Each RAM_AREAx represents an + // area of 128 bits. Select the key + // store RAM area(s) where the + // key(s) needs to be written 0: + // RAM_AREA5 is not selected to be + // written. 1: RAM_AREA5 is + // selected to be written. Writing + // to multiple RAM locations is + // possible only when the selected + // RAM areas are sequential. Keys + // that require more than one RAM + // locations (key size is 192 or + // 256 bits), must start at one of + // the following areas: RAM_AREA0, + // RAM_AREA2, RAM_AREA4, or + // RAM_AREA6. + +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA5_M \ + 0x00000020 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA5_S 5 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA4 \ + 0x00000010 // Each RAM_AREAx represents an + // area of 128 bits. Select the key + // store RAM area(s) where the + // key(s) needs to be written 0: + // RAM_AREA4 is not selected to be + // written. 1: RAM_AREA4 is + // selected to be written. Writing + // to multiple RAM locations is + // possible only when the selected + // RAM areas are sequential. Keys + // that require more than one RAM + // locations (key size is 192 or + // 256 bits), must start at one of + // the following areas: RAM_AREA0, + // RAM_AREA2, RAM_AREA4, or + // RAM_AREA6. + +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA4_M \ + 0x00000010 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA4_S 4 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA3 \ + 0x00000008 // Each RAM_AREAx represents an + // area of 128 bits. Select the key + // store RAM area(s) where the + // key(s) needs to be written 0: + // RAM_AREA3 is not selected to be + // written. 1: RAM_AREA3 is + // selected to be written. Writing + // to multiple RAM locations is + // possible only when the selected + // RAM areas are sequential. Keys + // that require more than one RAM + // locations (key size is 192 or + // 256 bits), must start at one of + // the following areas: RAM_AREA0, + // RAM_AREA2, RAM_AREA4, or + // RAM_AREA6. + +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA3_M \ + 0x00000008 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA3_S 3 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA2 \ + 0x00000004 // Each RAM_AREAx represents an + // area of 128 bits. Select the key + // store RAM area(s) where the + // key(s) needs to be written 0: + // RAM_AREA2 is not selected to be + // written. 1: RAM_AREA2 is + // selected to be written. Writing + // to multiple RAM locations is + // possible only when the selected + // RAM areas are sequential. Keys + // that require more than one RAM + // locations (key size is 192 or + // 256 bits), must start at one of + // the following areas: RAM_AREA0, + // RAM_AREA2, RAM_AREA4, or + // RAM_AREA6. + +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA2_M \ + 0x00000004 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA2_S 2 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA1 \ + 0x00000002 // Each RAM_AREAx represents an + // area of 128 bits. Select the key + // store RAM area(s) where the + // key(s) needs to be written 0: + // RAM_AREA1 is not selected to be + // written. 1: RAM_AREA1 is + // selected to be written. Writing + // to multiple RAM locations is + // possible only when the selected + // RAM areas are sequential. Keys + // that require more than one RAM + // locations (key size is 192 or + // 256 bits), must start at one of + // the following areas: RAM_AREA0, + // RAM_AREA2, RAM_AREA4, or + // RAM_AREA6. + +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA1_M \ + 0x00000002 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA1_S 1 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA0 \ + 0x00000001 // Each RAM_AREAx represents an + // area of 128 bits. Select the key + // store RAM area(s) where the + // key(s) needs to be written 0: + // RAM_AREA0 is not selected to be + // written. 1: RAM_AREA0 is + // selected to be written. Writing + // to multiple RAM locations is + // possible only when the selected + // RAM areas are sequential. Keys + // that require more than one RAM + // locations (key size is 192 or + // 256 bits), must start at one of + // the following areas: RAM_AREA0, + // RAM_AREA2, RAM_AREA4, or + // RAM_AREA6. + +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA0_M \ + 0x00000001 +#define AES_KEY_STORE_WRITE_AREA_RAM_AREA0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_KEY_STORE_WRITTEN_AREA register. +// +//***************************************************************************** +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN7 \ + 0x00000080 // Read operation: 0: This RAM + // area is not written with valid + // key information. 1: This RAM + // area is written with valid key + // information. Each individual + // ram_area_writtenx bit can be + // reset by writing 1. Note: This + // register is reset on a soft + // reset from the master control + // module. After a soft reset, all + // keys must be rewritten to the + // key store memory. + +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN7_M \ + 0x00000080 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN7_S 7 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN6 \ + 0x00000040 // Read operation: 0: This RAM + // area is not written with valid + // key information. 1: This RAM + // area is written with valid key + // information. Each individual + // ram_area_writtenx bit can be + // reset by writing 1. Note: This + // register is reset on a soft + // reset from the master control + // module. After a soft reset, all + // keys must be rewritten to the + // key store memory. + +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN6_M \ + 0x00000040 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN6_S 6 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN5 \ + 0x00000020 // Read operation: 0: This RAM + // area is not written with valid + // key information. 1: This RAM + // area is written with valid key + // information. Each individual + // ram_area_writtenx bit can be + // reset by writing 1. Note: This + // register is reset on a soft + // reset from the master control + // module. After a soft reset, all + // keys must be rewritten to the + // key store memory. + +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN5_M \ + 0x00000020 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN5_S 5 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN4 \ + 0x00000010 // Read operation: 0: This RAM + // area is not written with valid + // key information. 1: This RAM + // area is written with valid key + // information. Each individual + // ram_area_writtenx bit can be + // reset by writing 1. Note: This + // register is reset on a soft + // reset from the master control + // module. After a soft reset, all + // keys must be rewritten to the + // key store memory. + +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN4_M \ + 0x00000010 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN4_S 4 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN3 \ + 0x00000008 // Read operation: 0: This RAM + // area is not written with valid + // key information. 1: This RAM + // area is written with valid key + // information. Each individual + // ram_area_writtenx bit can be + // reset by writing 1. Note: This + // register is reset on a soft + // reset from the master control + // module. After a soft reset, all + // keys must be rewritten to the + // key store memory. + +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN3_M \ + 0x00000008 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN3_S 3 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN2 \ + 0x00000004 // Read operation: 0: This RAM + // area is not written with valid + // key information. 1: This RAM + // area is written with valid key + // information. Each individual + // ram_area_writtenx bit can be + // reset by writing 1. Note: This + // register is reset on a soft + // reset from the master control + // module. After a soft reset, all + // keys must be rewritten to the + // key store memory. + +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN2_M \ + 0x00000004 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN2_S 2 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN1 \ + 0x00000002 // Read operation: 0: This RAM + // area is not written with valid + // key information. 1: This RAM + // area is written with valid key + // information. Each individual + // ram_area_writtenx bit can be + // reset by writing 1. Note: This + // register is reset on a soft + // reset from the master control + // module. After a soft reset, all + // keys must be rewritten to the + // key store memory. + +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN1_M \ + 0x00000002 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN1_S 1 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN0 \ + 0x00000001 // Read operation: 0: This RAM + // area is not written with valid + // key information. 1: This RAM + // area is written with valid key + // information. Each individual + // ram_area_writtenx bit can be + // reset by writing 1. Note: This + // register is reset on a soft + // reset from the master control + // module. After a soft reset, all + // keys must be rewritten to the + // key store memory. + +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN0_M \ + 0x00000001 +#define AES_KEY_STORE_WRITTEN_AREA_RAM_AREA_WRITTEN0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_KEY_STORE_SIZE register. +// +//***************************************************************************** +#define AES_KEY_STORE_SIZE_KEY_SIZE_M \ + 0x00000003 // Key size: 00: Reserved 01: 128 + // bits 10: 192 bits 11: 256 bits + // When writing this to this + // register, the + // KEY_STORE_WRITTEN_AREA register + // is reset. + +#define AES_KEY_STORE_SIZE_KEY_SIZE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_KEY_STORE_READ_AREA register. +// +//***************************************************************************** +#define AES_KEY_STORE_READ_AREA_BUSY \ + 0x80000000 // Key store operation busy status + // flag (read only): 0: Operation + // is complete. 1: Operation is not + // completed and the key store is + // busy. + +#define AES_KEY_STORE_READ_AREA_BUSY_M \ + 0x80000000 +#define AES_KEY_STORE_READ_AREA_BUSY_S 31 +#define AES_KEY_STORE_READ_AREA_RAM_AREA_M \ + 0x0000000F // Selects the area of the key + // store RAM from where the key + // needs to be read that will be + // writen to the AES engine + // RAM_AREA: 0000: RAM_AREA0 0001: + // RAM_AREA1 0010: RAM_AREA2 0011: + // RAM_AREA3 0100: RAM_AREA4 0101: + // RAM_AREA5 0110: RAM_AREA6 0111: + // RAM_AREA7 1000: no RAM area + // selected 1001-1111: Reserved RAM + // areas RAM_AREA0, RAM_AREA2, + // RAM_AREA4 and RAM_AREA6 are the + // only valid read areas for 192 + // and 256 bits key sizes. Only RAM + // areas that contain valid written + // keys can be selected. + +#define AES_KEY_STORE_READ_AREA_RAM_AREA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_KEY2_0 register. +// +//***************************************************************************** +#define AES_AES_KEY2_0_AES_KEY2_M \ + 0xFFFFFFFF // AES_KEY2/AES_GHASH_H[31:0] For + // GCM: -[127:0] - GHASH_H - The + // internally calculated GHASH key + // is stored in these registers. + // Only used for modes that use the + // GHASH function (GCM). -[255:128] + // - This register is used to store + // intermediate values and is + // initialized with 0s when loading + // a new key. For CCM: -[255:0] - + // This register is used to store + // intermediate values. For + // CBC-MAC: -[255:0] - ZEROES - + // This register must remain 0. + +#define AES_AES_KEY2_0_AES_KEY2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_KEY2_1 register. +// +//***************************************************************************** +#define AES_AES_KEY2_1_AES_KEY2_M \ + 0xFFFFFFFF // AES_KEY2/AES_GHASH_H[63:32] For + // GCM: -[127:0] - GHASH_H - The + // internally calculated GHASH key + // is stored in these registers. + // Only used for modes that use the + // GHASH function (GCM). -[255:128] + // - This register is used to store + // intermediate values and is + // initialized with 0s when loading + // a new key. For CCM: -[255:0] - + // This register is used to store + // intermediate values. For + // CBC-MAC: -[255:0] - ZEROES - + // This register must remain 0. + +#define AES_AES_KEY2_1_AES_KEY2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_KEY2_2 register. +// +//***************************************************************************** +#define AES_AES_KEY2_2_AES_KEY2_M \ + 0xFFFFFFFF // AES_KEY2/AES_GHASH_H[95:64] For + // GCM: -[127:0] - GHASH_H - The + // internally calculated GHASH key + // is stored in these registers. + // Only used for modes that use the + // GHASH function (GCM). -[255:128] + // - This register is used to store + // intermediate values and is + // initialized with 0s when loading + // a new key. For CCM: -[255:0] - + // This register is used to store + // intermediate values. For + // CBC-MAC: -[255:0] - ZEROES - + // This register must remain 0. + +#define AES_AES_KEY2_2_AES_KEY2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_KEY2_3 register. +// +//***************************************************************************** +#define AES_AES_KEY2_3_AES_KEY2_M \ + 0xFFFFFFFF // AES_KEY2/AES_GHASH_H[127:96] + // For GCM: -[127:0] - GHASH_H - + // The internally calculated GHASH + // key is stored in these + // registers. Only used for modes + // that use the GHASH function + // (GCM). -[255:128] - This + // register is used to store + // intermediate values and is + // initialized with 0s when loading + // a new key. For CCM: -[255:0] - + // This register is used to store + // intermediate values. For + // CBC-MAC: -[255:0] - ZEROES - + // This register must remain 0. + +#define AES_AES_KEY2_3_AES_KEY2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_KEY3_0 register. +// +//***************************************************************************** +#define AES_AES_KEY3_0_AES_KEY3_M \ + 0xFFFFFFFF // + // AES_KEY3[31:0]/AES_KEY2[159:128] + // For GCM: -[127:0] - GHASH_H - + // The internally calculated GHASH + // key is stored in these + // registers. Only used for modes + // that use the GHASH function + // (GCM). -[255:128] - This + // register is used to store + // intermediate values and is + // initialized with 0s when loading + // a new key. For CCM: -[255:0] - + // This register is used to store + // intermediate values. For + // CBC-MAC: -[255:0] - ZEROES - + // This register must remain 0. + +#define AES_AES_KEY3_0_AES_KEY3_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_KEY3_1 register. +// +//***************************************************************************** +#define AES_AES_KEY3_1_AES_KEY3_M \ + 0xFFFFFFFF // + // AES_KEY3[63:32]/AES_KEY2[191:160] + // For GCM: -[127:0] - GHASH_H - + // The internally calculated GHASH + // key is stored in these + // registers. Only used for modes + // that use the GHASH function + // (GCM). -[255:128] - This + // register is used to store + // intermediate values and is + // initialized with 0s when loading + // a new key. For CCM: -[255:0] - + // This register is used to store + // intermediate values. For + // CBC-MAC: -[255:0] - ZEROES - + // This register must remain 0. + +#define AES_AES_KEY3_1_AES_KEY3_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_KEY3_2 register. +// +//***************************************************************************** +#define AES_AES_KEY3_2_AES_KEY3_M \ + 0xFFFFFFFF // + // AES_KEY3[95:64]/AES_KEY2[223:192] + // For GCM: -[127:0] - GHASH_H - + // The internally calculated GHASH + // key is stored in these + // registers. Only used for modes + // that use the GHASH function + // (GCM). -[255:128] - This + // register is used to store + // intermediate values and is + // initialized with 0s when loading + // a new key. For CCM: -[255:0] - + // This register is used to store + // intermediate values. For + // CBC-MAC: -[255:0] - ZEROES - + // This register must remain 0. + +#define AES_AES_KEY3_2_AES_KEY3_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_KEY3_3 register. +// +//***************************************************************************** +#define AES_AES_KEY3_3_AES_KEY3_M \ + 0xFFFFFFFF // + // AES_KEY3[127:96]/AES_KEY2[255:224] + // For GCM: -[127:0] - GHASH_H - + // The internally calculated GHASH + // key is stored in these + // registers. Only used for modes + // that use the GHASH function + // (GCM). -[255:128] - This + // register is used to store + // intermediate values and is + // initialized with 0s when loading + // a new key. For CCM: -[255:0] - + // This register is used to store + // intermediate values. For + // CBC-MAC: -[255:0] - ZEROES - + // This register must remain 0. + +#define AES_AES_KEY3_3_AES_KEY3_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the AES_AES_IV_0 register. +// +//***************************************************************************** +#define AES_AES_IV_0_AES_IV_M 0xFFFFFFFF // AES_IV[31:0] Initialization + // vector Used for regular non-ECB + // modes (CBC/CTR): -[127:0] - + // AES_IV - For regular AES + // operations (CBC and CTR) these + // registers must be written with a + // new 128-bit IV. After an + // operation, these registers + // contain the latest 128-bit + // result IV, generated by the + // EIP-120t. If CTR mode is + // selected, this value is + // incremented with 0x1: After + // first use - When a new data + // block is submitted to the engine + // For GCM: -[127:0] - AES_IV - For + // GCM operations, these registers + // must be written with a new + // 128-bit IV. After an operation, + // these registers contain the + // updated 128-bit result IV, + // generated by the EIP-120t. Note + // that bits [127:96] of the IV + // represent the initial counter + // value (which is 1 for GCM) and + // must therefore be initialized to + // 0x01000000. This value is + // incremented with 0x1: After + // first use - When a new data + // block is submitted to the + // engine. For CCM: -[127:0] - A0: + // For CCM this field must be + // written with value A0, this + // value is the concatenation of: + // A0-flags (5-bits of 0 and 3-bits + // 'L'), Nonce and counter value. + // 'L' must be a copy from the 'L' + // value of the AES_CTRL register. + // This 'L' indicates the width of + // the Nonce and counter. The + // loaded counter must be + // initialized to 0. The total + // width of A0 is 128-bit. For + // CBC-MAC: -[127:0] - Zeroes - For + // CBC-MAC this register must be + // written with 0s at the start of + // each operation. After an + // operation, these registers + // contain the 128-bit TAG output, + // generated by the EIP-120t. +#define AES_AES_IV_0_AES_IV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the AES_AES_IV_1 register. +// +//***************************************************************************** +#define AES_AES_IV_1_AES_IV_M 0xFFFFFFFF // AES_IV[63:32] Initialization + // vector Used for regular non-ECB + // modes (CBC/CTR): -[127:0] - + // AES_IV - For regular AES + // operations (CBC and CTR) these + // registers must be written with a + // new 128-bit IV. After an + // operation, these registers + // contain the latest 128-bit + // result IV, generated by the + // EIP-120t. If CTR mode is + // selected, this value is + // incremented with 0x1: After + // first use - When a new data + // block is submitted to the engine + // For GCM: -[127:0] - AES_IV - For + // GCM operations, these registers + // must be written with a new + // 128-bit IV. After an operation, + // these registers contain the + // updated 128-bit result IV, + // generated by the EIP-120t. Note + // that bits [127:96] of the IV + // represent the initial counter + // value (which is 1 for GCM) and + // must therefore be initialized to + // 0x01000000. This value is + // incremented with 0x1: After + // first use - When a new data + // block is submitted to the + // engine. For CCM: -[127:0] - A0: + // For CCM this field must be + // written with value A0, this + // value is the concatenation of: + // A0-flags (5-bits of 0 and 3-bits + // 'L'), Nonce and counter value. + // 'L' must be a copy from the 'L' + // value of the AES_CTRL register. + // This 'L' indicates the width of + // the Nonce and counter. The + // loaded counter must be + // initialized to 0. The total + // width of A0 is 128-bit. For + // CBC-MAC: -[127:0] - Zeroes - For + // CBC-MAC this register must be + // written with 0s at the start of + // each operation. After an + // operation, these registers + // contain the 128-bit TAG output, + // generated by the EIP-120t. +#define AES_AES_IV_1_AES_IV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the AES_AES_IV_2 register. +// +//***************************************************************************** +#define AES_AES_IV_2_AES_IV_M 0xFFFFFFFF // AES_IV[95:64] Initialization + // vector Used for regular non-ECB + // modes (CBC/CTR): -[127:0] - + // AES_IV - For regular AES + // operations (CBC and CTR) these + // registers must be written with a + // new 128-bit IV. After an + // operation, these registers + // contain the latest 128-bit + // result IV, generated by the + // EIP-120t. If CTR mode is + // selected, this value is + // incremented with 0x1: After + // first use - When a new data + // block is submitted to the engine + // For GCM: -[127:0] - AES_IV - For + // GCM operations, these registers + // must be written with a new + // 128-bit IV. After an operation, + // these registers contain the + // updated 128-bit result IV, + // generated by the EIP-120t. Note + // that bits [127:96] of the IV + // represent the initial counter + // value (which is 1 for GCM) and + // must therefore be initialized to + // 0x01000000. This value is + // incremented with 0x1: After + // first use - When a new data + // block is submitted to the + // engine. For CCM: -[127:0] - A0: + // For CCM this field must be + // written with value A0, this + // value is the concatenation of: + // A0-flags (5-bits of 0 and 3-bits + // 'L'), Nonce and counter value. + // 'L' must be a copy from the 'L' + // value of the AES_CTRL register. + // This 'L' indicates the width of + // the Nonce and counter. The + // loaded counter must be + // initialized to 0. The total + // width of A0 is 128-bit. For + // CBC-MAC: -[127:0] - Zeroes - For + // CBC-MAC this register must be + // written with 0s at the start of + // each operation. After an + // operation, these registers + // contain the 128-bit TAG output, + // generated by the EIP-120t. +#define AES_AES_IV_2_AES_IV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the AES_AES_IV_3 register. +// +//***************************************************************************** +#define AES_AES_IV_3_AES_IV_M 0xFFFFFFFF // AES_IV[127:96] Initialization + // vector Used for regular non-ECB + // modes (CBC/CTR): -[127:0] - + // AES_IV - For regular AES + // operations (CBC and CTR) these + // registers must be written with a + // new 128-bit IV. After an + // operation, these registers + // contain the latest 128-bit + // result IV, generated by the + // EIP-120t. If CTR mode is + // selected, this value is + // incremented with 0x1: After + // first use - When a new data + // block is submitted to the engine + // For GCM: -[127:0] - AES_IV - For + // GCM operations, these registers + // must be written with a new + // 128-bit IV. After an operation, + // these registers contain the + // updated 128-bit result IV, + // generated by the EIP-120t. Note + // that bits [127:96] of the IV + // represent the initial counter + // value (which is 1 for GCM) and + // must therefore be initialized to + // 0x01000000. This value is + // incremented with 0x1: After + // first use - When a new data + // block is submitted to the + // engine. For CCM: -[127:0] - A0: + // For CCM this field must be + // written with value A0, this + // value is the concatenation of: + // A0-flags (5-bits of 0 and 3-bits + // 'L'), Nonce and counter value. + // 'L' must be a copy from the 'L' + // value of the AES_CTRL register. + // This 'L' indicates the width of + // the Nonce and counter. The + // loaded counter must be + // initialized to 0. The total + // width of A0 is 128-bit. For + // CBC-MAC: -[127:0] - Zeroes - For + // CBC-MAC this register must be + // written with 0s at the start of + // each operation. After an + // operation, these registers + // contain the 128-bit TAG output, + // generated by the EIP-120t. +#define AES_AES_IV_3_AES_IV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the AES_AES_CTRL register. +// +//***************************************************************************** +#define AES_AES_CTRL_context_ready \ + 0x80000000 // If 1, this read-only status bit + // indicates that the context data + // registers can be overwritten and + // the host is permitted to write + // the next context. + +#define AES_AES_CTRL_context_ready_M \ + 0x80000000 +#define AES_AES_CTRL_context_ready_S 31 +#define AES_AES_CTRL_saved_context_ready \ + 0x40000000 // If 1, this status bit indicates + // that an AES authentication TAG + // and/or IV block(s) is/are + // available for the host to + // retrieve. This bit is only + // asserted if the save_context bit + // is set to 1. The bit is mutual + // exclusive with the context_ready + // bit. Writing one clears the bit + // to 0, indicating the AES core + // can start its next operation. + // This bit is also cleared when + // the 4th word of the output TAG + // and/or IV is read. Note: All + // other mode bit writes are + // ignored when this mode bit is + // written with 1. Note: This bit + // is controlled automatically by + // the EIP-120t for TAG read DMA + // operations. + +#define AES_AES_CTRL_saved_context_ready_M \ + 0x40000000 +#define AES_AES_CTRL_saved_context_ready_S 30 +#define AES_AES_CTRL_save_context \ + 0x20000000 // This bit indicates that an + // authentication TAG or result IV + // needs to be stored as a result + // context. Typically this bit must + // be set for authentication modes + // returning a TAG (CBC-MAC, GCM + // and CCM), or for basic + // encryption modes that require + // future continuation with the + // current result IV. If this bit + // is set, the engine retains its + // full context until the TAG + // and/or IV registers are read. + // The TAG or IV must be read + // before the AES engine can start + // a new operation. + +#define AES_AES_CTRL_save_context_M \ + 0x20000000 +#define AES_AES_CTRL_save_context_S 29 +#define AES_AES_CTRL_CCM_M_M 0x01C00000 // Defines M, which indicates the + // length of the authentication + // field for CCM operations; the + // authentication field length + // equals two times (the value of + // CCM-M plus one). Note: The + // EIP-120t always returns a + // 128-bit authentication field, of + // which the M least significant + // bytes are valid. All values are + // supported. +#define AES_AES_CTRL_CCM_M_S 22 +#define AES_AES_CTRL_CCM_L_M 0x00380000 // Defines L, which indicates the + // width of the length field for + // CCM operations; the length field + // in bytes equals the value of + // CMM-L plus one. All values are + // supported. +#define AES_AES_CTRL_CCM_L_S 19 +#define AES_AES_CTRL_CCM 0x00040000 // If set to 1, AES-CCM is + // selected AES-CCM is a combined + // mode, using AES for + // authentication and encryption. + // Note: Selecting AES-CCM mode + // requires writing of the AAD + // length register after all other + // registers. Note: The CTR mode + // bit in this register must also + // be set to 1 to enable AES-CTR; + // selecting other AES modes than + // CTR mode is invalid. +#define AES_AES_CTRL_CCM_M 0x00040000 +#define AES_AES_CTRL_CCM_S 18 +#define AES_AES_CTRL_GCM_M 0x00030000 // Set these bits to 11 to select + // AES-GCM mode. AES-GCM is a + // combined mode, using the Galois + // field multiplier GF(2 to the + // power of 128) for authentication + // and AES-CTR mode for encryption. + // Note: The CTR mode bit in this + // register must also be set to 1 + // to enable AES-CTR Bit + // combination description: 00 = No + // GCM mode 01 = Reserved, do not + // select 10 = Reserved, do not + // select 11 = Autonomous GHASH + // (both H- and Y0-encrypted + // calculated internally) Note: The + // EIP-120t-1 configuration only + // supports mode 11 (autonomous + // GHASH), other GCM modes are not + // allowed. +#define AES_AES_CTRL_GCM_S 16 +#define AES_AES_CTRL_CBC_MAC 0x00008000 // Set to 1 to select AES-CBC MAC + // mode. The direction bit must be + // set to 1 for this mode. + // Selecting this mode requires + // writing the length register + // after all other registers. +#define AES_AES_CTRL_CBC_MAC_M 0x00008000 +#define AES_AES_CTRL_CBC_MAC_S 15 +#define AES_AES_CTRL_ctr_width_M \ + 0x00000180 // Specifies the counter width for + // AES-CTR mode 00 = 32-bit counter + // 01 = 64-bit counter 10 = 96-bit + // counter 11 = 128-bit counter + +#define AES_AES_CTRL_ctr_width_S 7 +#define AES_AES_CTRL_CTR 0x00000040 // If set to 1, AES counter mode + // (CTR) is selected. Note: This + // bit must also be set for GCM and + // CCM, when encryption/decryption + // is required. +#define AES_AES_CTRL_CTR_M 0x00000040 +#define AES_AES_CTRL_CTR_S 6 +#define AES_AES_CTRL_CBC 0x00000020 // If set to 1, + // cipher-block-chaining (CBC) mode + // is selected. +#define AES_AES_CTRL_CBC_M 0x00000020 +#define AES_AES_CTRL_CBC_S 5 +#define AES_AES_CTRL_key_size_M 0x00000018 // This read-only field specifies + // the key size. The key size is + // automatically configured when a + // new key is loaded through the + // key store module. 00 = N/A - + // Reserved 01 = 128-bit 10 = + // 192-bit 11 = 256-bit +#define AES_AES_CTRL_key_size_S 3 +#define AES_AES_CTRL_direction 0x00000004 // If set to 1 an encrypt + // operation is performed. If set + // to 0 a decrypt operation is + // performed. This bit must be + // written with a 1 when CBC-MAC is + // selected. +#define AES_AES_CTRL_direction_M \ + 0x00000004 +#define AES_AES_CTRL_direction_S 2 +#define AES_AES_CTRL_input_ready \ + 0x00000002 // If 1, this status bit indicates + // that the 16-byte AES input + // buffer is empty. The host is + // permitted to write the next + // block of data. Writing 0 clears + // the bit to 0 and indicates that + // the AES core can use the + // provided input data block. + // Writing 1 to this bit is + // ignored. Note: For DMA + // operations, this bit is + // automatically controlled by the + // EIP-120t. After reset, this bit + // is 0. After writing a context, + // this bit becomes 1. + +#define AES_AES_CTRL_input_ready_M \ + 0x00000002 +#define AES_AES_CTRL_input_ready_S 1 +#define AES_AES_CTRL_output_ready \ + 0x00000001 // If 1, this status bit indicates + // that an AES output block is + // available to be retrieved by the + // host. Writing 0 clears the bit + // to 0 and indicates that output + // data is read by the host. The + // AES core can provide a next + // output data block. Writing 1 to + // this bit is ignored. Note: For + // DMA operations, this bit is + // automatically controlled by the + // EIP-120t. + +#define AES_AES_CTRL_output_ready_M \ + 0x00000001 +#define AES_AES_CTRL_output_ready_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_C_LENGTH_0 register. +// +//***************************************************************************** +#define AES_AES_C_LENGTH_0_C_LENGTH_M \ + 0xFFFFFFFF // C_LENGTH[31:0] Bits [60:0] of + // the crypto length registers (LSW + // and MSW) store the cryptographic + // data length in bytes for all + // modes. Once processing with this + // context is started, this length + // decrements to 0. Data lengths up + // to (261: 1) bytes are allowed. + // For GCM, any value up to 236 - + // 32 bytes can be used. This is + // because a 32-bit counter mode is + // used; the maximum number of + // 128-bit blocks is 232 - 2, + // resulting in a maximum number of + // bytes of 236 - 32. A write to + // this register triggers the + // engine to start using this + // context. This is valid for all + // modes except GCM and CCM. Note: + // For the combined modes (GCM and + // CCM), this length does not + // include the authentication only + // data; the authentication length + // is specified in the + // AES_AUTH_LENGTH register below. + // All modes must have a length + // greater than 0. For the combined + // modes, it is allowed to have one + // of the lengths equal to 0. For + // the basic encryption modes (ECB, + // CBC, and CTR) it is allowed to + // program zero to the length + // field; in that case the length + // is assumed infinite. All data + // must be byte (8-bit) aligned for + // stream cipher modes; bit aligned + // data streams are not supported + // by the EIP-120t. For block + // cipher modes, the data length + // must be programmed in multiples + // of the block cipher size, 16 + // bytes. For a host read + // operation, these registers + // return all-0s. + +#define AES_AES_C_LENGTH_0_C_LENGTH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_C_LENGTH_1 register. +// +//***************************************************************************** +#define AES_AES_C_LENGTH_1_C_LENGTH_M \ + 0x1FFFFFFF // C_LENGTH[60:32] Bits [60:0] of + // the crypto length registers (LSW + // and MSW) store the cryptographic + // data length in bytes for all + // modes. Once processing with this + // context is started, this length + // decrements to 0. Data lengths up + // to (261: 1) bytes are allowed. + // For GCM, any value up to 236 - + // 32 bytes can be used. This is + // because a 32-bit counter mode is + // used; the maximum number of + // 128-bit blocks is 232 - 2, + // resulting in a maximum number of + // bytes of 236 - 32. A write to + // this register triggers the + // engine to start using this + // context. This is valid for all + // modes except GCM and CCM. Note: + // For the combined modes (GCM and + // CCM), this length does not + // include the authentication only + // data; the authentication length + // is specified in the + // AES_AUTH_LENGTH register below. + // All modes must have a length + // greater than 0. For the combined + // modes, it is allowed to have one + // of the lengths equal to 0. For + // the basic encryption modes (ECB, + // CBC, and CTR) it is allowed to + // program zero to the length + // field; in that case the length + // is assumed infinite. All data + // must be byte (8-bit) aligned for + // stream cipher modes; bit aligned + // data streams are not supported + // by the EIP-120t. For block + // cipher modes, the data length + // must be programmed in multiples + // of the block cipher size, 16 + // bytes. For a host read + // operation, these registers + // return all-0s. + +#define AES_AES_C_LENGTH_1_C_LENGTH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_AUTH_LENGTH register. +// +//***************************************************************************** +#define AES_AES_AUTH_LENGTH_AUTH_LENGTH_M \ + 0xFFFFFFFF // Bits [31:0] of the + // authentication length register + // store the authentication data + // length in bytes for combined + // modes only (GCM or CCM). + // Supported AAD-lengths for CCM + // are from 0 to (2^16 - 2^8) + // bytes. For GCM any value up to + // (2^32 - 1) bytes can be used. + // Once processing with this + // context is started, this length + // decrements to 0. A write to this + // register triggers the engine to + // start using this context for GCM + // and CCM. For a host read + // operation, these registers + // return all-0s. + +#define AES_AES_AUTH_LENGTH_AUTH_LENGTH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_DATA_IN_OUT_0 register. +// +//***************************************************************************** +#define AES_AES_DATA_IN_OUT_0_AES_DATA_IN_OUT_M \ + 0xFFFFFFFF // AES input data[31:0] / AES + // output data[31:0] Data registers + // for input/output block data + // to/from the EIP-120t. For normal + // operations, this register is not + // used, since data input and + // output is transferred from and + // to the AES core via DMA. For a + // host write operation, these + // registers must be written with + // the 128-bit input block for the + // next AES operation. Writing at a + // word-aligned offset within this + // address range stores the word (4 + // bytes) of data into the + // corresponding position of 4-word + // deep (16 bytes = 128-bit AES + // block) data input buffer. This + // buffer is used for the next AES + // operation. If the last data + // block is not completely filled + // with valid data (see notes + // below), it is allowed to write + // only the words with valid data. + // Next AES operation is triggered + // by writing to the input_ready + // flag of the AES_CTRL register. + // For a host read operation, these + // registers contain the 128-bit + // output block from the latest AES + // operation. Reading from a + // word-aligned offset within this + // address range reads one word (4 + // bytes) of data out the 4-word + // deep (16 bytes = 128-bits AES + // block) data output buffer. The + // words (4 words, one full block) + // should be read before the core + // will move the next block to the + // data output buffer. To empty the + // data output buffer, the + // output_ready flag of the + // AES_CTRL register must be + // written. For the modes with + // authentication (CBC-MAC, GCM and + // CCM), the invalid (message) + // bytes/words can be written with + // any data. Note: AES typically + // operates on 128 bits block + // multiple input data. The CTR, + // GCM and CCM modes form an + // exception. The last block of a + // CTR-mode message may contain + // less than 128 bits (refer to + // [NIST 800-38A]). For GCM/CCM, + // the last block of both AAD and + // message data may contain less + // than 128 bits (refer to [NIST + // 800-38D]). The EIP-120t + // automatically pads or masks + // misaligned ending data blocks + // with 0s for GCM, CCM and + // CBC-MAC. For CTR mode, the + // remaining data in an unaligned + // data block is ignored. Note: The + // AAD / authentication only data + // is not copied to the output + // buffer but only used for + // authentication. + +#define AES_AES_DATA_IN_OUT_0_AES_DATA_IN_OUT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_DATA_IN_OUT_1 register. +// +//***************************************************************************** +#define AES_AES_DATA_IN_OUT_1_AES_DATA_IN_OUT_M \ + 0xFFFFFFFF // AES input data[63:32] / AES + // output data[63:32] Data + // registers for input/output block + // data to/from the EIP-120t. For + // normal operations, this register + // is not used, since data input + // and output is transferred from + // and to the AES core via DMA. For + // a host write operation, these + // registers must be written with + // the 128-bit input block for the + // next AES operation. Writing at a + // word-aligned offset within this + // address range stores the word (4 + // bytes) of data into the + // corresponding position of 4-word + // deep (16 bytes = 128-bit AES + // block) data input buffer. This + // buffer is used for the next AES + // operation. If the last data + // block is not completely filled + // with valid data (see notes + // below), it is allowed to write + // only the words with valid data. + // Next AES operation is triggered + // by writing to the input_ready + // flag of the AES_CTRL register. + // For a host read operation, these + // registers contain the 128-bit + // output block from the latest AES + // operation. Reading from a + // word-aligned offset within this + // address range reads one word (4 + // bytes) of data out the 4-word + // deep (16 bytes = 128-bits AES + // block) data output buffer. The + // words (4 words, one full block) + // should be read before the core + // will move the next block to the + // data output buffer. To empty the + // data output buffer, the + // output_ready flag of the + // AES_CTRL register must be + // written. For the modes with + // authentication (CBC-MAC, GCM and + // CCM), the invalid (message) + // bytes/words can be written with + // any data. Note: AES typically + // operates on 128 bits block + // multiple input data. The CTR, + // GCM and CCM modes form an + // exception. The last block of a + // CTR-mode message may contain + // less than 128 bits (refer to + // [NIST 800-38A]). For GCM/CCM, + // the last block of both AAD and + // message data may contain less + // than 128 bits (refer to [NIST + // 800-38D]). The EIP-120t + // automatically pads or masks + // misaligned ending data blocks + // with 0s for GCM, CCM and + // CBC-MAC. For CTR mode, the + // remaining data in an unaligned + // data block is ignored. Note: The + // AAD / authentication only data + // is not copied to the output + // buffer but only used for + // authentication. + +#define AES_AES_DATA_IN_OUT_1_AES_DATA_IN_OUT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_DATA_IN_OUT_2 register. +// +//***************************************************************************** +#define AES_AES_DATA_IN_OUT_2_AES_DATA_IN_OUT_M \ + 0xFFFFFFFF // AES input data[95:64] / AES + // output data[95:64] Data + // registers for input/output block + // data to/from the EIP-120t. For + // normal operations, this register + // is not used, since data input + // and output is transferred from + // and to the AES core via DMA. For + // a host write operation, these + // registers must be written with + // the 128-bit input block for the + // next AES operation. Writing at a + // word-aligned offset within this + // address range stores the word (4 + // bytes) of data into the + // corresponding position of 4-word + // deep (16 bytes = 128-bit AES + // block) data input buffer. This + // buffer is used for the next AES + // operation. If the last data + // block is not completely filled + // with valid data (see notes + // below), it is allowed to write + // only the words with valid data. + // Next AES operation is triggered + // by writing to the input_ready + // flag of the AES_CTRL register. + // For a host read operation, these + // registers contain the 128-bit + // output block from the latest AES + // operation. Reading from a + // word-aligned offset within this + // address range reads one word (4 + // bytes) of data out the 4-word + // deep (16 bytes = 128-bits AES + // block) data output buffer. The + // words (4 words, one full block) + // should be read before the core + // will move the next block to the + // data output buffer. To empty the + // data output buffer, the + // output_ready flag of the + // AES_CTRL register must be + // written. For the modes with + // authentication (CBC-MAC, GCM and + // CCM), the invalid (message) + // bytes/words can be written with + // any data. Note: AES typically + // operates on 128 bits block + // multiple input data. The CTR, + // GCM and CCM modes form an + // exception. The last block of a + // CTR-mode message may contain + // less than 128 bits (refer to + // [NIST 800-38A]). For GCM/CCM, + // the last block of both AAD and + // message data may contain less + // than 128 bits (refer to [NIST + // 800-38D]). The EIP-120t + // automatically pads or masks + // misaligned ending data blocks + // with 0s for GCM, CCM and + // CBC-MAC. For CTR mode, the + // remaining data in an unaligned + // data block is ignored. Note: The + // AAD / authentication only data + // is not copied to the output + // buffer but only used for + // authentication. + +#define AES_AES_DATA_IN_OUT_2_AES_DATA_IN_OUT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_DATA_IN_OUT_3 register. +// +//***************************************************************************** +#define AES_AES_DATA_IN_OUT_3_AES_DATA_IN_OUT_M \ + 0xFFFFFFFF // AES input data[127:96] / AES + // output data[127:96] Data + // registers for input/output block + // data to/from the EIP-120t. For + // normal operations, this register + // is not used, since data input + // and output is transferred from + // and to the AES core via DMA. For + // a host write operation, these + // registers must be written with + // the 128-bit input block for the + // next AES operation. Writing at a + // word-aligned offset within this + // address range stores the word (4 + // bytes) of data into the + // corresponding position of 4-word + // deep (16 bytes = 128-bit AES + // block) data input buffer. This + // buffer is used for the next AES + // operation. If the last data + // block is not completely filled + // with valid data (see notes + // below), it is allowed to write + // only the words with valid data. + // Next AES operation is triggered + // by writing to the input_ready + // flag of the AES_CTRL register. + // For a host read operation, these + // registers contain the 128-bit + // output block from the latest AES + // operation. Reading from a + // word-aligned offset within this + // address range reads one word (4 + // bytes) of data out the 4-word + // deep (16 bytes = 128-bits AES + // block) data output buffer. The + // words (4 words, one full block) + // should be read before the core + // will move the next block to the + // data output buffer. To empty the + // data output buffer, the + // output_ready flag of the + // AES_CTRL register must be + // written. For the modes with + // authentication (CBC-MAC, GCM and + // CCM), the invalid (message) + // bytes/words can be written with + // any data. Note: AES typically + // operates on 128 bits block + // multiple input data. The CTR, + // GCM and CCM modes form an + // exception. The last block of a + // CTR-mode message may contain + // less than 128 bits (refer to + // [NIST 800-38A]). For GCM/CCM, + // the last block of both AAD and + // message data may contain less + // than 128 bits (refer to [NIST + // 800-38D]). The EIP-120t + // automatically pads or masks + // misaligned ending data blocks + // with 0s for GCM, CCM and + // CBC-MAC. For CTR mode, the + // remaining data in an unaligned + // data block is ignored. Note: The + // AAD / authentication only data + // is not copied to the output + // buffer but only used for + // authentication. + +#define AES_AES_DATA_IN_OUT_3_AES_DATA_IN_OUT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_TAG_OUT_0 register. +// +//***************************************************************************** +#define AES_AES_TAG_OUT_0_AES_TAG_M \ + 0xFFFFFFFF // AES_TAG[31:0] Bits [31:0] of + // the AES_TAG registers store the + // authentication value for the + // combined and authentication only + // modes. For a host read + // operation, these registers + // contain the last 128-bit TAG + // output of the EIP-120t; the TAG + // is available until the next + // context is written. This + // register will only contain valid + // data if the TAG is available and + // when the store_ready bit from + // AES_CTRL register is set. During + // processing or for + // operations/modes that do not + // return a TAG, reads from this + // register return data from the IV + // register. + +#define AES_AES_TAG_OUT_0_AES_TAG_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_TAG_OUT_1 register. +// +//***************************************************************************** +#define AES_AES_TAG_OUT_1_AES_TAG_M \ + 0xFFFFFFFF // AES_TAG[63:32] For a host read + // operation, these registers + // contain the last 128-bit TAG + // output of the EIP-120t; the TAG + // is available until the next + // context is written. This + // register contains valid data + // only if the TAG is available and + // when the store_ready bit from + // AES_CTRL register is set. During + // processing or for + // operations/modes that do not + // return a TAG, reads from this + // register return data from the IV + // register. + +#define AES_AES_TAG_OUT_1_AES_TAG_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_TAG_OUT_2 register. +// +//***************************************************************************** +#define AES_AES_TAG_OUT_2_AES_TAG_M \ + 0xFFFFFFFF // AES_TAG[95:64] For a host read + // operation, these registers + // contain the last 128-bit TAG + // output of the EIP-120t; the TAG + // is available until the next + // context is written. This + // register contains valid data + // only if the TAG is available and + // when the store_ready bit from + // AES_CTRL register is set. During + // processing or for + // operations/modes that do not + // return a TAG, reads from this + // register return data from the IV + // register. + +#define AES_AES_TAG_OUT_2_AES_TAG_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_AES_TAG_OUT_3 register. +// +//***************************************************************************** +#define AES_AES_TAG_OUT_3_AES_TAG_M \ + 0xFFFFFFFF // AES_TAG[127:96] For a host read + // operation, these registers + // contain the last 128-bit TAG + // output of the EIP-120t; the TAG + // is available until the next + // context is written. This + // register contains valid data + // only if the TAG is available and + // when the store_ready bit from + // AES_CTRL register is set. During + // processing or for + // operations/modes that do not + // return a TAG, reads from this + // register return data from the IV + // register. + +#define AES_AES_TAG_OUT_3_AES_TAG_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_0 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_0_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[31:0] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_0_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_1 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_1_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[63:32] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_1_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_2 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_2_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[95:64] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_2_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_3 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_3_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[127:96] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_3_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_4 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_4_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[159:128] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_4_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_5 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_5_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[191:160] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_5_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_6 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_6_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[223:192] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_6_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_7 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_7_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[255:224] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_7_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_8 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_8_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[287:256] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_8_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_9 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_9_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[319:288] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_9_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_10 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_10_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[351:320] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_10_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_11 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_11_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[383:352] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_11_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_12 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_12_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[415:384] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_12_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_13 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_13_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[447:416] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_13_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_14 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_14_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[479:448] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_14_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DATA_IN_15 register. +// +//***************************************************************************** +#define AES_HASH_DATA_IN_15_HASH_DATA_IN_M \ + 0xFFFFFFFF // HASH_DATA_IN[511:480] These + // registers must be written with + // the 512-bit input data. The data + // lines are connected directly to + // the data input of the hash + // module and hence into the + // engine's internal data buffer. + // Writing to each of the registers + // triggers a corresponding 32-bit + // write enable to the internal + // buffer. Note: The host may only + // write the input data buffer when + // the rfd_in bit of the + // HASH_IO_BUF_CTRL register is + // high. If the rfd_in bit is 0, + // the engine is busy with + // processing. During processing, + // it is not allowed to write new + // input data. For message lengths + // larger than 64 bytes, multiple + // blocks of data are written to + // this input buffer using a + // handshake through flags of the + // HASH_IO_BUF_CTRL register. All + // blocks except the last are + // required to be 512 bits in size. + // If the last block is not 512 + // bits long, only the least + // significant bits of data must be + // written, but they must be padded + // with 0s to the next 32-bit + // boundary. Host read operations + // from these register addresses + // return 0s. + +#define AES_HASH_DATA_IN_15_HASH_DATA_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_IO_BUF_CTRL register. +// +//***************************************************************************** +#define AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE \ + 0x00000080 // Note: This bit must only be + // used when data is supplied + // through the DMA. It should not + // be used when data is supplied + // through the slave interface. + // This bit indicates whether the + // hash engine has to pad the + // message, received through the + // DMA and finalize the hash. When + // set to 1, the hash engine pads + // the last block using the + // programmed length. After + // padding, the final hash result + // is calculated. When set to 0, + // the hash engine treats the last + // written block as block-size + // aligned and calculates the + // intermediate digest. This bit is + // automatically cleared when the + // last DMA data block is arrived + // in the hash engine. + +#define AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE_M \ + 0x00000080 +#define AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE_S 7 +#define AES_HASH_IO_BUF_CTRL_GET_DIGEST \ + 0x00000040 // Note: The bit description below + // is only applicable when data is + // sent through the slave + // interface. This bit must be set + // to 0 when data is received + // through the DMA. This bit + // indicates whether the hash + // engine should provide the hash + // digest. When provided + // simultaneously with data_in_av, + // the hash digest is provided + // after processing the data that + // is currently in the HASH_DATA_IN + // register. When provided without + // data_in_av, the current internal + // digest buffer value is copied to + // the HASH_DIGEST_n registers. The + // host must write a 1 to this bit + // to make the intermediate hash + // digest available. Writing 0 to + // this bit has no effect. This bit + // is automatically cleared (that + // is, reads 0) when the hash + // engine has processed the + // contents of the HASH_DATA_IN + // register. In the period between + // this bit is set by the host and + // the actual HASH_DATA_IN + // processing, this bit reads 1. + +#define AES_HASH_IO_BUF_CTRL_GET_DIGEST_M \ + 0x00000040 +#define AES_HASH_IO_BUF_CTRL_GET_DIGEST_S 6 +#define AES_HASH_IO_BUF_CTRL_PAD_MESSAGE \ + 0x00000020 // Note: The bit description below + // is only applicable when data is + // sent through the slave + // interface. This bit must be set + // to 0 when data is received + // through the DMA. This bit + // indicates that the HASH_DATA_IN + // registers hold the last data of + // the message and hash padding + // must be applied. The host must + // write this bit to 1 in order to + // indicate to the hash engine that + // the HASH_DATA_IN register + // currently holds the last data of + // the message. When pad_message is + // set to 1, the hash engine will + // add padding bits to the data + // currently in the HASH_DATA_IN + // register. When the last message + // block is smaller than 512 bits, + // the pad_message bit must be set + // to 1 together with the + // data_in_av bit. When the last + // message block is equal to 512 + // bits, pad_message may be set + // together with data_in_av. In + // this case the pad_message bit + // may also be set after the last + // data block has been written to + // the hash engine (so when the + // rfd_in bit has become 1 again + // after writing the last data + // block). Writing 0 to this bit + // has no effect. This bit is + // automatically cleared (i.e. + // reads 0) by the hash engine. + // This bit reads 1 between the + // time it was set by the host and + // the hash engine interpreted its + // value. + +#define AES_HASH_IO_BUF_CTRL_PAD_MESSAGE_M \ + 0x00000020 +#define AES_HASH_IO_BUF_CTRL_PAD_MESSAGE_S 5 +#define AES_HASH_IO_BUF_CTRL_RFD_IN \ + 0x00000004 // Note: The bit description below + // is only applicable when data is + // sent through the slave + // interface. This bit can be + // ignored when data is received + // through the DMA. Read-only + // status of the input buffer of + // the hash engine. When 1, the + // input buffer of the hash engine + // can accept new data; the + // HASH_DATA_IN registers can + // safely be populated with new + // data. When 0, the input buffer + // of the hash engine is processing + // the data that is currently in + // HASH_DATA_IN; writing new data + // to these registers is not + // allowed. + +#define AES_HASH_IO_BUF_CTRL_RFD_IN_M \ + 0x00000004 +#define AES_HASH_IO_BUF_CTRL_RFD_IN_S 2 +#define AES_HASH_IO_BUF_CTRL_DATA_IN_AV \ + 0x00000002 // Note: The bit description below + // is only applicable when data is + // sent through the slave + // interface. This bit must be set + // to 0 when data is received + // through the DMA. This bit + // indicates that the HASH_DATA_IN + // registers contain new input data + // for processing. The host must + // write a 1 to this bit to start + // processing the data in + // HASH_DATA_IN; the hash engine + // will process the new data as + // soon as it is ready for it + // (rfd_in bit is 1). Writing 0 to + // this bit has no effect. This bit + // is automatically cleared (i.e. + // reads as 0) when the hash engine + // starts processing the + // HASH_DATA_IN contents. This bit + // reads 1 between the time it was + // set by the host and the hash + // engine actually starts + // processing the input data block. + +#define AES_HASH_IO_BUF_CTRL_DATA_IN_AV_M \ + 0x00000002 +#define AES_HASH_IO_BUF_CTRL_DATA_IN_AV_S 1 +#define AES_HASH_IO_BUF_CTRL_OUTPUT_FULL \ + 0x00000001 // Indicates that the output + // buffer registers (HASH_DIGEST_n) + // are available for reading by the + // host. When this bit reads 0, the + // output buffer registers are + // released; the hash engine is + // allowed to write new data to it. + // In this case, the registers + // should not be read by the host. + // When this bit reads 1, the hash + // engine has stored the result of + // the latest hash operation in the + // output buffer registers. As long + // as this bit reads 1, the host + // may read output buffer registers + // and the hash engine is prevented + // from writing new data to the + // output buffer. After retrieving + // the hash result data from the + // output buffer, the host must + // write a 1 to this bit to clear + // it. This makes the digest output + // buffer available for the hash + // engine to store new hash + // results. Writing 0 to this bit + // has no effect. Note: If this bit + // is asserted (1) no new operation + // should be started before the + // digest is retrieved from the + // hash engine and this bit is + // cleared (0). + +#define AES_HASH_IO_BUF_CTRL_OUTPUT_FULL_M \ + 0x00000001 +#define AES_HASH_IO_BUF_CTRL_OUTPUT_FULL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_MODE_IN register. +// +//***************************************************************************** +#define AES_HASH_MODE_IN_SHA256_MODE \ + 0x00000008 // The host must write this bit + // with 1 before processing a hash + // session. + +#define AES_HASH_MODE_IN_SHA256_MODE_M \ + 0x00000008 +#define AES_HASH_MODE_IN_SHA256_MODE_S 3 +#define AES_HASH_MODE_IN_NEW_HASH \ + 0x00000001 // When set to 1, it indicates + // that the hash engine must start + // processing a new hash session. + // The HASH_DIGEST_n registers will + // automatically be loaded with the + // initial hash algorithm constants + // of the selected hash algorithm. + // When this bit is 0 while the + // hash processing is started, the + // initial hash algorithm constants + // are not loaded in the + // HASH_DIGEST_n registers. The + // hash engine will start + // processing with the digest that + // is currently in its internal + // HASH_DIGEST_n registers. This + // bit is automatically cleared + // when hash processing is started. + +#define AES_HASH_MODE_IN_NEW_HASH_M \ + 0x00000001 +#define AES_HASH_MODE_IN_NEW_HASH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_LENGTH_IN_L register. +// +//***************************************************************************** +#define AES_HASH_LENGTH_IN_L_LENGTH_IN_M \ + 0xFFFFFFFF // LENGTH_IN[31:0] Message length + // registers. The content of these + // registers is used by the hash + // engine during the message + // padding phase of the hash + // session. The data lines of this + // registers are directly connected + // to the interface of the hash + // engine. For a write operation by + // the host, these registers should + // be written with the message + // length in bits. Final hash + // operations: The total input data + // length must be programmed for + // new hash operations that require + // finalization (padding). The + // input data must be provided + // through the slave or DMA + // interface. Continued hash + // operations (finalized): For + // continued hash operations that + // require finalization, the total + // message length must be + // programmed, including the length + // of previously hashed data that + // corresponds to the written input + // digest. Non-final hash + // operations: For hash operations + // that do not require finalization + // (input data length is multiple + // of 512-bits which is SHA-256 + // data block size), the length + // field does not need to be + // programmed since not used by the + // operation. If the message length + // in bits is below (2^32-1), then + // only HASH_LENGTH_IN_L needs to + // be written. The hardware + // automatically sets + // HASH_LENGTH_IN_H to 0s in this + // case. The host may write the + // length register at any time + // during the hash session when the + // rfd_in bit of the + // HASH_IO_BUF_CTRL is high. The + // length register must be written + // before the last data of the + // active hash session is written + // into the hash engine. host read + // operations from these register + // locations will return 0s. Note: + // When getting data from DMA, this + // register must be programmed + // before DMA is programmed to + // start. + +#define AES_HASH_LENGTH_IN_L_LENGTH_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_LENGTH_IN_H register. +// +//***************************************************************************** +#define AES_HASH_LENGTH_IN_H_LENGTH_IN_M \ + 0xFFFFFFFF // LENGTH_IN[63:32] Message length + // registers. The content of these + // registers is used by the hash + // engine during the message + // padding phase of the hash + // session. The data lines of this + // registers are directly connected + // to the interface of the hash + // engine. For a write operation by + // the host, these registers should + // be written with the message + // length in bits. Final hash + // operations: The total input data + // length must be programmed for + // new hash operations that require + // finalization (padding). The + // input data must be provided + // through the slave or DMA + // interface. Continued hash + // operations (finalized): For + // continued hash operations that + // require finalization, the total + // message length must be + // programmed, including the length + // of previously hashed data that + // corresponds to the written input + // digest. Non-final hash + // operations: For hash operations + // that do not require finalization + // (input data length is multiple + // of 512-bits which is SHA-256 + // data block size), the length + // field does not need to be + // programmed since not used by the + // operation. If the message length + // in bits is below (2^32-1), then + // only HASH_LENGTH_IN_L needs to + // be written. The hardware + // automatically sets + // HASH_LENGTH_IN_H to 0s in this + // case. The host may write the + // length register at any time + // during the hash session when the + // rfd_in bit of the + // HASH_IO_BUF_CTRL is high. The + // length register must be written + // before the last data of the + // active hash session is written + // into the hash engine. host read + // operations from these register + // locations will return 0s. Note: + // When getting data from DMA, this + // register must be programmed + // before DMA is programmed to + // start. + +#define AES_HASH_LENGTH_IN_H_LENGTH_IN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DIGEST_A register. +// +//***************************************************************************** +#define AES_HASH_DIGEST_A_HASH_DIGEST_M \ + 0xFFFFFFFF // HASH_DIGEST[31:0] Hash digest + // registers Write operation: + // Continued hash: These registers + // should be written with the + // context data, before the start + // of a resumed hash session (the + // new_hash bit in the HASH_MODE + // register is 0 when starting a + // hash session). New hash: When + // initiating a new hash session + // (the new_hash bit in the + // HASH_MODE register is high), the + // internal digest registers are + // automatically set to the SHA-256 + // algorithm constant and these + // register should not be written. + // Reading from these registers + // provides the intermediate hash + // result (non-final hash + // operation) or the final hash + // result (final hash operation) + // after data processing. + +#define AES_HASH_DIGEST_A_HASH_DIGEST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DIGEST_B register. +// +//***************************************************************************** +#define AES_HASH_DIGEST_B_HASH_DIGEST_M \ + 0xFFFFFFFF // HASH_DIGEST[63:32] Hash digest + // registers Write operation: + // Continued hash: These registers + // should be written with the + // context data, before the start + // of a resumed hash session (the + // new_hash bit in the HASH_MODE + // register is 0 when starting a + // hash session). New hash: When + // initiating a new hash session + // (the new_hash bit in the + // HASH_MODE register is high), the + // internal digest registers are + // automatically set to the SHA-256 + // algorithm constant and these + // register should not be written. + // Reading from these registers + // provides the intermediate hash + // result (non-final hash + // operation) or the final hash + // result (final hash operation) + // after data processing. + +#define AES_HASH_DIGEST_B_HASH_DIGEST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DIGEST_C register. +// +//***************************************************************************** +#define AES_HASH_DIGEST_C_HASH_DIGEST_M \ + 0xFFFFFFFF // HASH_DIGEST[95:64] Hash digest + // registers Write operation: + // Continued hash: These registers + // should be written with the + // context data, before the start + // of a resumed hash session (the + // new_hash bit in the HASH_MODE + // register is 0 when starting a + // hash session). New hash: When + // initiating a new hash session + // (the new_hash bit in the + // HASH_MODE register is high), the + // internal digest registers are + // automatically set to the SHA-256 + // algorithm constant and these + // register should not be written. + // Reading from these registers + // provides the intermediate hash + // result (non-final hash + // operation) or the final hash + // result (final hash operation) + // after data processing. + +#define AES_HASH_DIGEST_C_HASH_DIGEST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DIGEST_D register. +// +//***************************************************************************** +#define AES_HASH_DIGEST_D_HASH_DIGEST_M \ + 0xFFFFFFFF // HASH_DIGEST[127:96] Hash digest + // registers Write operation: + // Continued hash: These registers + // should be written with the + // context data, before the start + // of a resumed hash session (the + // new_hash bit in the HASH_MODE + // register is 0 when starting a + // hash session). New hash: When + // initiating a new hash session + // (the new_hash bit in the + // HASH_MODE register is high), the + // internal digest registers are + // automatically set to the SHA-256 + // algorithm constant and these + // register should not be written. + // Reading from these registers + // provides the intermediate hash + // result (non-final hash + // operation) or the final hash + // result (final hash operation) + // after data processing. + +#define AES_HASH_DIGEST_D_HASH_DIGEST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DIGEST_E register. +// +//***************************************************************************** +#define AES_HASH_DIGEST_E_HASH_DIGEST_M \ + 0xFFFFFFFF // HASH_DIGEST[159:128] Hash + // digest registers Write + // operation: Continued hash: These + // registers should be written with + // the context data, before the + // start of a resumed hash session + // (the new_hash bit in the + // HASH_MODE register is 0 when + // starting a hash session). New + // hash: When initiating a new hash + // session (the new_hash bit in the + // HASH_MODE register is high), the + // internal digest registers are + // automatically set to the SHA-256 + // algorithm constant and these + // register should not be written. + // Reading from these registers + // provides the intermediate hash + // result (non-final hash + // operation) or the final hash + // result (final hash operation) + // after data processing. + +#define AES_HASH_DIGEST_E_HASH_DIGEST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DIGEST_F register. +// +//***************************************************************************** +#define AES_HASH_DIGEST_F_HASH_DIGEST_M \ + 0xFFFFFFFF // HASH_DIGEST[191:160] Hash + // digest registers Write + // operation: Continued hash: These + // registers should be written with + // the context data, before the + // start of a resumed hash session + // (the new_hash bit in the + // HASH_MODE register is 0 when + // starting a hash session). New + // hash: When initiating a new hash + // session (the new_hash bit in the + // HASH_MODE register is high), the + // internal digest registers are + // automatically set to the SHA-256 + // algorithm constant and these + // register should not be written. + // Reading from these registers + // provides the intermediate hash + // result (non-final hash + // operation) or the final hash + // result (final hash operation) + // after data processing. + +#define AES_HASH_DIGEST_F_HASH_DIGEST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DIGEST_G register. +// +//***************************************************************************** +#define AES_HASH_DIGEST_G_HASH_DIGEST_M \ + 0xFFFFFFFF // HASH_DIGEST[223:192] Hash + // digest registers Write + // operation: Continued hash: These + // registers should be written with + // the context data, before the + // start of a resumed hash session + // (the new_hash bit in the + // HASH_MODE register is 0 when + // starting a hash session). New + // hash: When initiating a new hash + // session (the new_hash bit in the + // HASH_MODE register is high), the + // internal digest registers are + // automatically set to the SHA-256 + // algorithm constant and these + // register should not be written. + // Reading from these registers + // provides the intermediate hash + // result (non-final hash + // operation) or the final hash + // result (final hash operation) + // after data processing. + +#define AES_HASH_DIGEST_G_HASH_DIGEST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_HASH_DIGEST_H register. +// +//***************************************************************************** +#define AES_HASH_DIGEST_H_HASH_DIGEST_M \ + 0xFFFFFFFF // HASH_DIGEST[255:224] Hash + // digest registers Write + // operation: Continued hash: These + // registers should be written with + // the context data, before the + // start of a resumed hash session + // (the new_hash bit in the + // HASH_MODE register is 0 when + // starting a hash session). New + // hash: When initiating a new hash + // session (the new_hash bit in the + // HASH_MODE register is high), the + // internal digest registers are + // automatically set to the SHA-256 + // algorithm constant and these + // register should not be written. + // Reading from these registers + // provides the intermediate hash + // result (non-final hash + // operation) or the final hash + // result (final hash operation) + // after data processing. + +#define AES_HASH_DIGEST_H_HASH_DIGEST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_ALG_SEL register. +// +//***************************************************************************** +#define AES_CTRL_ALG_SEL_TAG 0x80000000 // If this bit is cleared to 0, + // the DMA operation involves only + // data. If this bit is set, the + // DMA operation includes a TAG + // (Authentication Result / + // Digest). For SHA-256 operation, + // a DMA must be set up for both + // input data and TAG. For any + // other selected module, setting + // this bit only allows a DMA that + // reads the TAG. No data allowed + // to be transferred to or from the + // selected module via the DMA. +#define AES_CTRL_ALG_SEL_TAG_M 0x80000000 +#define AES_CTRL_ALG_SEL_TAG_S 31 +#define AES_CTRL_ALG_SEL_HASH 0x00000004 // If set to one, selects the hash + // engine as destination for the + // DMA The maximum transfer size to + // DMA engine is set to 64 bytes + // for reading and 32 bytes for + // writing (the latter is only + // applicable if the hash result is + // written out through the DMA). +#define AES_CTRL_ALG_SEL_HASH_M 0x00000004 +#define AES_CTRL_ALG_SEL_HASH_S 2 +#define AES_CTRL_ALG_SEL_AES 0x00000002 // If set to one, selects the AES + // engine as source/destination for + // the DMA The read and write + // maximum transfer size to the DMA + // engine is set to 16 bytes. +#define AES_CTRL_ALG_SEL_AES_M 0x00000002 +#define AES_CTRL_ALG_SEL_AES_S 1 +#define AES_CTRL_ALG_SEL_KEYSTORE \ + 0x00000001 // If set to one, selects the Key + // Store as destination for the DMA + // The maximum transfer size to DMA + // engine is set to 32 bytes + // (however transfers of 16, 24 and + // 32 bytes are allowed) + +#define AES_CTRL_ALG_SEL_KEYSTORE_M \ + 0x00000001 +#define AES_CTRL_ALG_SEL_KEYSTORE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_PROT_EN register. +// +//***************************************************************************** +#define AES_CTRL_PROT_EN_PROT_EN \ + 0x00000001 // If this bit is cleared to 0, + // m_h_prot[1] on the AHB mater + // interface always remains 0. If + // this bit is set to one, the + // m_h_prot[1] signal on the master + // AHB bus is asserted to 1 if an + // AHB read operation is performed, + // using DMA, with the key store + // module as destination. + +#define AES_CTRL_PROT_EN_PROT_EN_M \ + 0x00000001 +#define AES_CTRL_PROT_EN_PROT_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_SW_RESET register. +// +//***************************************************************************** +#define AES_CTRL_SW_RESET_SW_RESET \ + 0x00000001 // If this bit is set to 1, the + // following modules are reset: - + // Master control internal state is + // reset. That includes interrupt, + // error status register, and + // result available interrupt + // generation FSM. - Key store + // module state is reset. That + // includes clearing the written + // area flags; therefore, the keys + // must be reloaded to the key + // store module. Writing 0 has no + // effect. The bit is self cleared + // after executing the reset. + +#define AES_CTRL_SW_RESET_SW_RESET_M \ + 0x00000001 +#define AES_CTRL_SW_RESET_SW_RESET_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_INT_CFG register. +// +//***************************************************************************** +#define AES_CTRL_INT_CFG_LEVEL 0x00000001 // If this bit is 0, the interrupt + // output is a pulse. If this bit + // is set to 1, the interrupt is a + // level interrupt that must be + // cleared by writing the interrupt + // clear register. This bit is + // applicable for both interrupt + // output signals. +#define AES_CTRL_INT_CFG_LEVEL_M \ + 0x00000001 +#define AES_CTRL_INT_CFG_LEVEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_INT_EN register. +// +//***************************************************************************** +#define AES_CTRL_INT_EN_DMA_IN_DONE \ + 0x00000002 // If this bit is set to 0, the + // DMA input done (irq_dma_in_done) + // interrupt output is disabled and + // remains 0. If this bit is set to + // 1, the DMA input done interrupt + // output is enabled. + +#define AES_CTRL_INT_EN_DMA_IN_DONE_M \ + 0x00000002 +#define AES_CTRL_INT_EN_DMA_IN_DONE_S 1 +#define AES_CTRL_INT_EN_RESULT_AV \ + 0x00000001 // If this bit is set to 0, the + // result available (irq_result_av) + // interrupt output is disabled and + // remains 0. If this bit is set to + // 1, the result available + // interrupt output is enabled. + +#define AES_CTRL_INT_EN_RESULT_AV_M \ + 0x00000001 +#define AES_CTRL_INT_EN_RESULT_AV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_INT_CLR register. +// +//***************************************************************************** +#define AES_CTRL_INT_CLR_DMA_BUS_ERR \ + 0x80000000 // If 1 is written to this bit, + // the DMA bus error status is + // cleared. Writing 0 has no + // effect. + +#define AES_CTRL_INT_CLR_DMA_BUS_ERR_M \ + 0x80000000 +#define AES_CTRL_INT_CLR_DMA_BUS_ERR_S 31 +#define AES_CTRL_INT_CLR_KEY_ST_WR_ERR \ + 0x40000000 // If 1 is written to this bit, + // the key store write error status + // is cleared. Writing 0 has no + // effect. + +#define AES_CTRL_INT_CLR_KEY_ST_WR_ERR_M \ + 0x40000000 +#define AES_CTRL_INT_CLR_KEY_ST_WR_ERR_S 30 +#define AES_CTRL_INT_CLR_KEY_ST_RD_ERR \ + 0x20000000 // If 1 is written to this bit, + // the key store read error status + // is cleared. Writing 0 has no + // effect. + +#define AES_CTRL_INT_CLR_KEY_ST_RD_ERR_M \ + 0x20000000 +#define AES_CTRL_INT_CLR_KEY_ST_RD_ERR_S 29 +#define AES_CTRL_INT_CLR_DMA_IN_DONE \ + 0x00000002 // If 1 is written to this bit, + // the DMA in done + // (irq_dma_in_done) interrupt + // output is cleared. Writing 0 has + // no effect. Note that clearing an + // interrupt makes sense only if + // the interrupt output is + // programmed as level (refer to + // CTRL_INT_CFG). + +#define AES_CTRL_INT_CLR_DMA_IN_DONE_M \ + 0x00000002 +#define AES_CTRL_INT_CLR_DMA_IN_DONE_S 1 +#define AES_CTRL_INT_CLR_RESULT_AV \ + 0x00000001 // If 1 is written to this bit, + // the result available + // (irq_result_av) interrupt output + // is cleared. Writing 0 has no + // effect. Note that clearing an + // interrupt makes sense only if + // the interrupt output is + // programmed as level (refer to + // CTRL_INT_CFG). + +#define AES_CTRL_INT_CLR_RESULT_AV_M \ + 0x00000001 +#define AES_CTRL_INT_CLR_RESULT_AV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_INT_SET register. +// +//***************************************************************************** +#define AES_CTRL_INT_SET_DMA_IN_DONE \ + 0x00000002 // If 1 is written to this bit, + // the DMA data in done + // (irq_dma_in_done) interrupt + // output is set to one. Writing 0 + // has no effect. If the interrupt + // configuration register is + // programmed to pulse, clearing + // the DMA data in done + // (irq_dma_in_done) interrupt is + // not needed. If it is programmed + // to level, clearing the interrupt + // output should be done by writing + // the interrupt clear register + // (CTRL_INT_CLR). + +#define AES_CTRL_INT_SET_DMA_IN_DONE_M \ + 0x00000002 +#define AES_CTRL_INT_SET_DMA_IN_DONE_S 1 +#define AES_CTRL_INT_SET_RESULT_AV \ + 0x00000001 // If 1 is written to this bit, + // the result available + // (irq_result_av) interrupt output + // is set to one. Writing 0 has no + // effect. If the interrupt + // configuration register is + // programmed to pulse, clearing + // the result available + // (irq_result_av) interrupt is not + // needed. If it is programmed to + // level, clearing the interrupt + // output should be done by writing + // the interrupt clear register + // (CTRL_INT_CLR). + +#define AES_CTRL_INT_SET_RESULT_AV_M \ + 0x00000001 +#define AES_CTRL_INT_SET_RESULT_AV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_INT_STAT register. +// +//***************************************************************************** +#define AES_CTRL_INT_STAT_DMA_BUS_ERR \ + 0x80000000 // This bit is set when a DMA bus + // error is detected during a DMA + // operation. The value of this + // register is held until it is + // cleared through the CTRL_INT_CLR + // register. Note: This error is + // asserted if an error is detected + // on the AHB master interface + // during a DMA operation. + +#define AES_CTRL_INT_STAT_DMA_BUS_ERR_M \ + 0x80000000 +#define AES_CTRL_INT_STAT_DMA_BUS_ERR_S 31 +#define AES_CTRL_INT_STAT_KEY_ST_WR_ERR \ + 0x40000000 // This bit is set when a write + // error is detected during the DMA + // write operation to the key store + // memory. The value of this + // register is held until it is + // cleared through the CTRL_INT_CLR + // register. Note: This error is + // asserted if a DMA operation does + // not cover a full key area or + // more areas are written than + // expected. + +#define AES_CTRL_INT_STAT_KEY_ST_WR_ERR_M \ + 0x40000000 +#define AES_CTRL_INT_STAT_KEY_ST_WR_ERR_S 30 +#define AES_CTRL_INT_STAT_KEY_ST_RD_ERR \ + 0x20000000 // This bit is set when a read + // error is detected during the + // read of a key from the key + // store, while copying it to the + // AES core. The value of this + // register is held until it is + // cleared through the CTRL_INT_CLR + // register. Note: This error is + // asserted if a key location is + // selected in the key store that + // is not available. + +#define AES_CTRL_INT_STAT_KEY_ST_RD_ERR_M \ + 0x20000000 +#define AES_CTRL_INT_STAT_KEY_ST_RD_ERR_S 29 +#define AES_CTRL_INT_STAT_DMA_IN_DONE \ + 0x00000002 // This read only bit returns the + // actual DMA data in done + // (irq_data_in_done) interrupt + // status of the DMA data in done + // interrupt output pin + // (irq_data_in_done). + +#define AES_CTRL_INT_STAT_DMA_IN_DONE_M \ + 0x00000002 +#define AES_CTRL_INT_STAT_DMA_IN_DONE_S 1 +#define AES_CTRL_INT_STAT_RESULT_AV \ + 0x00000001 // This read only bit returns the + // actual result available + // (irq_result_av) interrupt status + // of the result available + // interrupt output pin + // (irq_result_av). + +#define AES_CTRL_INT_STAT_RESULT_AV_M \ + 0x00000001 +#define AES_CTRL_INT_STAT_RESULT_AV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_OPTIONS register. +// +//***************************************************************************** +#define AES_CTRL_OPTIONS_TYPE_M 0xFF000000 // This field is 0x01 for the + // TYPE1 device. +#define AES_CTRL_OPTIONS_TYPE_S 24 +#define AES_CTRL_OPTIONS_AHBINTERFACE \ + 0x00010000 // AHB interface is available If + // this bit is 0, the EIP-120t has + // a TCM interface. + +#define AES_CTRL_OPTIONS_AHBINTERFACE_M \ + 0x00010000 +#define AES_CTRL_OPTIONS_AHBINTERFACE_S 16 +#define AES_CTRL_OPTIONS_SHA_256 \ + 0x00000100 // The HASH core supports SHA-256. + +#define AES_CTRL_OPTIONS_SHA_256_M \ + 0x00000100 +#define AES_CTRL_OPTIONS_SHA_256_S 8 +#define AES_CTRL_OPTIONS_AES_CCM \ + 0x00000080 // AES-CCM is available as a + // single operation. + +#define AES_CTRL_OPTIONS_AES_CCM_M \ + 0x00000080 +#define AES_CTRL_OPTIONS_AES_CCM_S 7 +#define AES_CTRL_OPTIONS_AES_GCM \ + 0x00000040 // AES-GCM is available as a + // single operation. + +#define AES_CTRL_OPTIONS_AES_GCM_M \ + 0x00000040 +#define AES_CTRL_OPTIONS_AES_GCM_S 6 +#define AES_CTRL_OPTIONS_AES_256 \ + 0x00000020 // AES core supports 256-bit keys + // Note: If both AES-128 and + // AES-256 are set to one, the AES + // core supports 192-bit keys as + // well. + +#define AES_CTRL_OPTIONS_AES_256_M \ + 0x00000020 +#define AES_CTRL_OPTIONS_AES_256_S 5 +#define AES_CTRL_OPTIONS_AES_128 \ + 0x00000010 // AES core supports 128-bit keys. + +#define AES_CTRL_OPTIONS_AES_128_M \ + 0x00000010 +#define AES_CTRL_OPTIONS_AES_128_S 4 +#define AES_CTRL_OPTIONS_HASH 0x00000004 // HASH Core is available. +#define AES_CTRL_OPTIONS_HASH_M 0x00000004 +#define AES_CTRL_OPTIONS_HASH_S 2 +#define AES_CTRL_OPTIONS_AES 0x00000002 // AES core is available. +#define AES_CTRL_OPTIONS_AES_M 0x00000002 +#define AES_CTRL_OPTIONS_AES_S 1 +#define AES_CTRL_OPTIONS_KEYSTORE \ + 0x00000001 // KEY STORE is available. + +#define AES_CTRL_OPTIONS_KEYSTORE_M \ + 0x00000001 +#define AES_CTRL_OPTIONS_KEYSTORE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// AES_CTRL_VERSION register. +// +//***************************************************************************** +#define AES_CTRL_VERSION_MAJOR_VERSION_M \ + 0x0F000000 // Major version number + +#define AES_CTRL_VERSION_MAJOR_VERSION_S 24 +#define AES_CTRL_VERSION_MINOR_VERSION_M \ + 0x00F00000 // Minor version number + +#define AES_CTRL_VERSION_MINOR_VERSION_S 20 +#define AES_CTRL_VERSION_PATCH_LEVEL_M \ + 0x000F0000 // Patch level Starts at 0 at + // first delivery of this version + +#define AES_CTRL_VERSION_PATCH_LEVEL_S 16 +#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_M \ + 0x0000FF00 // These bits simply contain the + // complement of bits [7:0] (0x87), + // used by a driver to ascertain + // that the EIP-120t register is + // indeed read. + +#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_S 8 +#define AES_CTRL_VERSION_EIP_NUMBER_M \ + 0x000000FF // These bits encode the EIP + // number for the EIP-120t, this + // field contains the value 120 + // (decimal) or 0x78. + +#define AES_CTRL_VERSION_EIP_NUMBER_S 0 + + +#endif // __HW_AES_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_ana_regs.h b/bsp/boards/mimsy2-cc2538/headers/hw_ana_regs.h new file mode 100644 index 0000000000..a3cee7db34 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_ana_regs.h @@ -0,0 +1,86 @@ +/****************************************************************************** +* Filename: hw_ana_regs.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_ANA_REGS_H__ +#define __HW_ANA_REGS_H__ + +//***************************************************************************** +// +// The following are defines for the ANA_REGS register offsets. +// +//***************************************************************************** +#define ANA_REGS_O_IVCTRL 0x00000004 // Analog control register + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// ANA_REGS_O_IVCTRL register. +// +//***************************************************************************** +#define ANA_REGS_IVCTRL_DAC_CURR_CTRL_M \ + 0x00000030 // Controls bias current to DAC + // 00: 100% IVREF, 0% IREF bias 01: + // 60% IVREF, 40% IREF bias 10: 40% + // IVREF, 60% IREF bias 11: 0% + // IVREF, 100% IREF bias + +#define ANA_REGS_IVCTRL_DAC_CURR_CTRL_S 4 +#define ANA_REGS_IVCTRL_LODIV_BIAS_CTRL \ + 0x00000008 // Controls bias current to LODIV + // 1: PTAT bias 0: IVREF bias + +#define ANA_REGS_IVCTRL_LODIV_BIAS_CTRL_M \ + 0x00000008 +#define ANA_REGS_IVCTRL_LODIV_BIAS_CTRL_S 3 +#define ANA_REGS_IVCTRL_TXMIX_DC_CTRL \ + 0x00000004 // Controls DC bias in TXMIX + +#define ANA_REGS_IVCTRL_TXMIX_DC_CTRL_M \ + 0x00000004 +#define ANA_REGS_IVCTRL_TXMIX_DC_CTRL_S 2 +#define ANA_REGS_IVCTRL_PA_BIAS_CTRL_M \ + 0x00000003 // Controls bias current to PA 00: + // IREF bias 01: IREF and IVREF + // bias (CC2530 mode) 10: PTAT bias + // 11: Increased PTAT slope bias + +#define ANA_REGS_IVCTRL_PA_BIAS_CTRL_S 0 + + +#endif // __HW_ANA_REGS_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_cctest.h b/bsp/boards/mimsy2-cc2538/headers/hw_cctest.h new file mode 100644 index 0000000000..a656005417 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_cctest.h @@ -0,0 +1,266 @@ +/****************************************************************************** +* Filename: hw_cctest.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_CCTEST_H__ +#define __HW_CCTEST_H__ + +//***************************************************************************** +// +// The following are defines for the CCTEST register offsets. +// +//***************************************************************************** +#define CCTEST_IO 0x44010000 // Output strength control +#define CCTEST_OBSSEL0 0x44010014 // Select output signal on + // observation output 0 +#define CCTEST_OBSSEL1 0x44010018 // Select output signal on + // observation output 1 +#define CCTEST_OBSSEL2 0x4401001C // Select output signal on + // observation output 2 +#define CCTEST_OBSSEL3 0x44010020 // Select output signal on + // observation output 3 +#define CCTEST_OBSSEL4 0x44010024 // Select output signal on + // observation output 4 +#define CCTEST_OBSSEL5 0x44010028 // Select output signal on + // observation output 5 +#define CCTEST_OBSSEL6 0x4401002C // Select output signal on + // observation output 6 +#define CCTEST_OBSSEL7 0x44010030 // Select output signal on + // observation output 7 +#define CCTEST_TR0 0x44010034 // Test register 0 +#define CCTEST_USBCTRL 0x44010050 // USB PHY stand-by control + + +//***************************************************************************** +// +// The following are defines for the bit fields in the CCTEST_IO register. +// +//***************************************************************************** +#define CCTEST_IO_SC 0x00000001 // I/O strength control bit Common + // to all digital output pads + // Should be set when unregulated + // voltage is below approximately + // 2.6 V. +#define CCTEST_IO_SC_M 0x00000001 +#define CCTEST_IO_SC_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// CCTEST_OBSSEL0 register. +// +//***************************************************************************** +#define CCTEST_OBSSEL0_EN 0x00000080 // Observation output 0 enable + // control for PC0 0: Observation + // output disabled 1: Observation + // output enabled Note: If enabled, + // this overwrites the standard + // GPIO behavior of PC0. +#define CCTEST_OBSSEL0_EN_M 0x00000080 +#define CCTEST_OBSSEL0_EN_S 7 +#define CCTEST_OBSSEL0_SEL_M 0x0000007F // n - obs_sigs[n] output on + // output 0: 0: rfc_obs_sig0 1: + // rfc_obs_sig1 2: rfc_obs_sig2 + // Others: Reserved +#define CCTEST_OBSSEL0_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// CCTEST_OBSSEL1 register. +// +//***************************************************************************** +#define CCTEST_OBSSEL1_EN 0x00000080 // Observation output 1 enable + // control for PC1 0: Observation + // output disabled 1: Observation + // output enabled Note: If enabled, + // this overwrites the standard + // GPIO behavior of PC1. +#define CCTEST_OBSSEL1_EN_M 0x00000080 +#define CCTEST_OBSSEL1_EN_S 7 +#define CCTEST_OBSSEL1_SEL_M 0x0000007F // n - obs_sigs[n] output on + // output 1: 0: rfc_obs_sig0 1: + // rfc_obs_sig1 2: rfc_obs_sig2 + // Others: Reserved +#define CCTEST_OBSSEL1_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// CCTEST_OBSSEL2 register. +// +//***************************************************************************** +#define CCTEST_OBSSEL2_EN 0x00000080 // Observation output 2 enable + // control for PC2 0: Observation + // output disabled 1: Observation + // output enabled Note: If enabled, + // this overwrites the standard + // GPIO behavior of PC2. +#define CCTEST_OBSSEL2_EN_M 0x00000080 +#define CCTEST_OBSSEL2_EN_S 7 +#define CCTEST_OBSSEL2_SEL_M 0x0000007F // n - obs_sigs[n] output on + // output 2: 0: rfc_obs_sig0 1: + // rfc_obs_sig1 2: rfc_obs_sig2 + // Others: Reserved +#define CCTEST_OBSSEL2_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// CCTEST_OBSSEL3 register. +// +//***************************************************************************** +#define CCTEST_OBSSEL3_EN 0x00000080 // Observation output 3 enable + // control for PC3 0: Observation + // output disabled 1: Observation + // output enabled Note: If enabled, + // this overwrites the standard + // GPIO behavior of PC3. +#define CCTEST_OBSSEL3_EN_M 0x00000080 +#define CCTEST_OBSSEL3_EN_S 7 +#define CCTEST_OBSSEL3_SEL_M 0x0000007F // n - obs_sigs[n] output on + // output 3: 0: rfc_obs_sig0 1: + // rfc_obs_sig1 2: rfc_obs_sig2 + // Others: Reserved +#define CCTEST_OBSSEL3_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// CCTEST_OBSSEL4 register. +// +//***************************************************************************** +#define CCTEST_OBSSEL4_EN 0x00000080 // Observation output 4 enable + // control for PC4 0: Observation + // output disabled 1: Observation + // output enabled Note: If enabled, + // this overwrites the standard + // GPIO behavior of PC4. +#define CCTEST_OBSSEL4_EN_M 0x00000080 +#define CCTEST_OBSSEL4_EN_S 7 +#define CCTEST_OBSSEL4_SEL_M 0x0000007F // n - obs_sigs[n] output on + // output 4: 0: rfc_obs_sig0 1: + // rfc_obs_sig1 2: rfc_obs_sig2 + // Others: Reserved +#define CCTEST_OBSSEL4_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// CCTEST_OBSSEL5 register. +// +//***************************************************************************** +#define CCTEST_OBSSEL5_EN 0x00000080 // Observation output 5 enable + // control for PC5 0: Observation + // output disabled 1: Observation + // output enabled Note: If enabled, + // this overwrites the standard + // GPIO behavior of PC5. +#define CCTEST_OBSSEL5_EN_M 0x00000080 +#define CCTEST_OBSSEL5_EN_S 7 +#define CCTEST_OBSSEL5_SEL_M 0x0000007F // n - obs_sigs[n] output on + // output 5: 0: rfc_obs_sig0 1: + // rfc_obs_sig1 2: rfc_obs_sig2 + // Others: Reserved +#define CCTEST_OBSSEL5_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// CCTEST_OBSSEL6 register. +// +//***************************************************************************** +#define CCTEST_OBSSEL6_EN 0x00000080 // Observation output 6 enable + // control for PC6 0: Observation + // output disabled 1: Observation + // output enabled Note: If enabled, + // this overwrites the standard + // GPIO behavior of PC6. +#define CCTEST_OBSSEL6_EN_M 0x00000080 +#define CCTEST_OBSSEL6_EN_S 7 +#define CCTEST_OBSSEL6_SEL_M 0x0000007F // n - obs_sigs[n] output on + // output 6: 0: rfc_obs_sig0 1: + // rfc_obs_sig1 2: rfc_obs_sig2 + // Others: Reserved +#define CCTEST_OBSSEL6_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// CCTEST_OBSSEL7 register. +// +//***************************************************************************** +#define CCTEST_OBSSEL7_EN 0x00000080 // Observation output 7 enable + // control for PC7 0: Observation + // output disabled 1: Observation + // output enabled Note: If enabled, + // this overwrites the standard + // GPIO behavior of PC7. +#define CCTEST_OBSSEL7_EN_M 0x00000080 +#define CCTEST_OBSSEL7_EN_S 7 +#define CCTEST_OBSSEL7_SEL_M 0x0000007F // n - obs_sigs[n] output on + // output 7: 0: rfc_obs_sig0 1: + // rfc_obs_sig1 2: rfc_obs_sig2 + // Others: Reserved +#define CCTEST_OBSSEL7_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the CCTEST_TR0 register. +// +//***************************************************************************** +#define CCTEST_TR0_ADCTM 0x00000002 // Set to 1 to connect the + // temperature sensor to the + // SOC_ADC. See also + // RFCORE_XREG_ATEST register + // description to enable the + // temperature sensor. +#define CCTEST_TR0_ADCTM_M 0x00000002 +#define CCTEST_TR0_ADCTM_S 1 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// CCTEST_USBCTRL register. +// +//***************************************************************************** +#define CCTEST_USBCTRL_USB_STB 0x00000001 // USB PHY stand-by override bit + // When this bit is cleared to 0 + // (default state) the USB module + // cannot change the stand-by mode + // of the PHY (USB pads) and the + // PHY is forced out of stand-by + // mode. This bit must be 1 as well + // as the stand-by control from the + // USB controller, before the mode + // of the PHY is stand-by. +#define CCTEST_USBCTRL_USB_STB_M \ + 0x00000001 +#define CCTEST_USBCTRL_USB_STB_S 0 + + +#endif // __HW_CCTEST_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_flash_ctrl.h b/bsp/boards/mimsy2-cc2538/headers/hw_flash_ctrl.h new file mode 100644 index 0000000000..e4e5d51984 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_flash_ctrl.h @@ -0,0 +1,449 @@ +/****************************************************************************** +* Filename: hw_flash_ctrl.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_FLASH_CTRL_H__ +#define __HW_FLASH_CTRL_H__ + +//***************************************************************************** +// +// The following are defines for the FLASH_CTRL register offsets. +// +//***************************************************************************** +#define FLASH_CTRL_FCTL 0x400D3008 // Flash control This register + // provides control and monitoring + // functions for the flash module. +#define FLASH_CTRL_FADDR 0x400D300C // Flash address The register sets + // the address to be written in + // flash memory. See the bitfield + // descriptions for formatting + // information. +#define FLASH_CTRL_FWDATA 0x400D3010 // Flash data This register + // contains the 32-bits of data to + // be written to the flash location + // selected in FADDR. +#define FLASH_CTRL_DIECFG0 0x400D3014 // These settings are a function + // of the FLASH information page + // bit settings, which are + // programmed during production + // test, and are subject for + // specific configuration for + // multiple device flavors of + // cc2538. +#define FLASH_CTRL_DIECFG1 0x400D3018 // These settings are a function + // of the FLASH information page + // bit settings, which are + // programmed during production + // test, and are subject for + // specific configuration for + // multiple device flavors of + // cc2538. +#define FLASH_CTRL_DIECFG2 0x400D301C // These settings are a function + // of the FLASH information page + // bit settings, which are + // programmed during production + // test, and are subject for + // specific configuration for + // multiple device flavors of + // cc2538. The DIE_*_REVISION + // registers are an exeception to + // this, as they are hardwired and + // are not part of the FLASH + // information page. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// FLASH_CTRL_FCTL register. +// +//***************************************************************************** +#define FLASH_CTRL_FCTL_UPPER_PAGE_ACCESS \ + 0x00000200 // Lock bit for lock bit page 0: + // Neither write nor erase not + // allowed 1: Both write and erase + // allowed + +#define FLASH_CTRL_FCTL_UPPER_PAGE_ACCESS_M \ + 0x00000200 +#define FLASH_CTRL_FCTL_UPPER_PAGE_ACCESS_S 9 +#define FLASH_CTRL_FCTL_SEL_INFO_PAGE \ + 0x00000100 // Flash erase or write operation + // on APB bus must assert this when + // accessing the information page + +#define FLASH_CTRL_FCTL_SEL_INFO_PAGE_M \ + 0x00000100 +#define FLASH_CTRL_FCTL_SEL_INFO_PAGE_S 8 +#define FLASH_CTRL_FCTL_BUSY 0x00000080 // Set when the WRITE or ERASE bit + // is set; that is, when the flash + // controller is busy +#define FLASH_CTRL_FCTL_BUSY_M 0x00000080 +#define FLASH_CTRL_FCTL_BUSY_S 7 +#define FLASH_CTRL_FCTL_FULL 0x00000040 // Write buffer full The CPU can + // write to FWDATA when this bit is + // 0 and WRITE is 1. This bit is + // cleared when BUSY is cleared. +#define FLASH_CTRL_FCTL_FULL_M 0x00000040 +#define FLASH_CTRL_FCTL_FULL_S 6 +#define FLASH_CTRL_FCTL_ABORT 0x00000020 // Abort status This bit is set to + // 1 when a write sequence or page + // erase is aborted. An operation + // is aborted when the accessed + // page is locked. Cleared when a + // write or page erase is started. + // If a write operation times out + // (because the FWDATA register is + // not written fast enough), the + // ABORT bit is not set even if the + // page is locked. If a page erase + // and a write operation are + // started simultaneously, the + // ABORT bit reflects the status of + // the last write operation. For + // example, if the page is locked + // and the write times out, the + // ABORT bit is not set because + // only the write operation times + // out. +#define FLASH_CTRL_FCTL_ABORT_M 0x00000020 +#define FLASH_CTRL_FCTL_ABORT_S 5 +#define FLASH_CTRL_FCTL_CM_M 0x0000000C // Cache Mode Disabling the cache + // increases the power consumption + // and reduces performance. + // Prefetching improves performance + // at the expense of a potential + // increase in power consumption. + // Real-time mode provides + // predictable flash read access + // time, the execution time is + // equal to cache disabled mode, + // but the power consumption is + // lower. 00: Cache disabled 01: + // Cache enabled 10: Cache enabled, + // with prefetch 11: Real-time mode + // Note: The read value always + // represents the current cache + // mode. Writing a new cache mode + // starts a cache mode change + // request that does not take + // effect until the controller is + // ready. Writes to this register + // are ignored if there is a + // current cache change request in + // progress. +#define FLASH_CTRL_FCTL_CM_S 2 +#define FLASH_CTRL_FCTL_WRITE 0x00000002 // Write bit Start a write + // sequence by setting this bit to + // 1. Cleared by hardware when the + // operation completes. Writes to + // this bit are ignored when + // FCTL.BUSY is 1. If FCTL.ERASE is + // set simultaneously with this + // bit, the erase operation is + // started first, then the write is + // started. +#define FLASH_CTRL_FCTL_WRITE_M 0x00000002 +#define FLASH_CTRL_FCTL_WRITE_S 1 +#define FLASH_CTRL_FCTL_ERASE 0x00000001 // Erase bit Start an erase + // operation by setting this bit to + // 1. Cleared by hardware when the + // operation completes. Writes to + // this bit are ignored when + // FCTL.BUSY is 1. If FCTL.WRITE is + // set simultaneously with this + // bit, the erase operation is + // started first, then the write is + // started. +#define FLASH_CTRL_FCTL_ERASE_M 0x00000001 +#define FLASH_CTRL_FCTL_ERASE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// FLASH_CTRL_FADDR register. +// +//***************************************************************************** +#define FLASH_CTRL_FADDR_FADDR_M \ + 0x0001FFFF // Bit number [16:9] selects one + // of 256 pages for page erase. Bit + // number [8:7] selects one of the + // 4 row in a given page Bit number + // [6:1] selects one of the 64-bit + // wide locations in a give row. + // Bit number [0] will select + // upper/lower 32-bits in a given + // 64-bit location - 64Kbytes --> + // Bits [16:14] will always be 0. - + // 128Kbytes --> Bits [16:15] will + // always be 0. - 256Kbytes --> Bit + // [16] will always be 0. - + // 384/512Kbytes --> All bits + // written and valid. Writes to + // this register will be ignored + // when any of FCTL.WRITE and + // FCTL.ERASE is set. FADDR should + // be written with byte addressable + // location of the Flash to be + // programmed. Read back value + // always reflects a 32-bit aligned + // address. When the register is + // read back, the value that was + // written to FADDR gets right + // shift by 2 to indicate 32-bit + // aligned address. In other words + // lower 2 bits are discarded while + // reading back the register. Out + // of range address results in roll + // over. There is no status signal + // generated by flash controller to + // indicate this. Firmware is + // responsible to managing the + // addresses correctly. + +#define FLASH_CTRL_FADDR_FADDR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// FLASH_CTRL_FWDATA register. +// +//***************************************************************************** +#define FLASH_CTRL_FWDATA_FWDATA_M \ + 0xFFFFFFFF // 32-bit flash write data Writes + // to this register are accepted + // only during a flash write + // sequence; that is, writes to + // this register after having + // written 1 to the FCTL.WRITE bit. + // New 32-bit data is written only + // if FCTL.FULL = 0. + +#define FLASH_CTRL_FWDATA_FWDATA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// FLASH_CTRL_DIECFG0 register. +// +//***************************************************************************** +#define FLASH_CTRL_DIECFG0_CHIPID_M \ + 0xFFFF0000 // Register copy of configuration + // bits Three clock cycles after + // reset is released, this bit + // field is equal to the field with + // the same name in the information + // page. + +#define FLASH_CTRL_DIECFG0_CHIPID_S 16 +#define FLASH_CTRL_DIECFG0_CLK_SEL_GATE_EN_N \ + 0x00000400 // Register copy of configuration + // bits Three clock cycles after + // reset is released, this bit is + // equal to the field with the same + // name in the information page. + +#define FLASH_CTRL_DIECFG0_CLK_SEL_GATE_EN_N_M \ + 0x00000400 +#define FLASH_CTRL_DIECFG0_CLK_SEL_GATE_EN_N_S 10 +#define FLASH_CTRL_DIECFG0_SRAM_SIZE_M \ + 0x00000380 // Register copy of configuration + // bits Three clock cycles after + // reset is released, this bit + // field is equal to the field with + // the same name in the information + // page. + +#define FLASH_CTRL_DIECFG0_SRAM_SIZE_S 7 +#define FLASH_CTRL_DIECFG0_FLASH_SIZE_M \ + 0x00000070 // Register copy of configuration + // bits Three clock cycles after + // reset is released, this bit + // field is equal to the field with + // the same name in the information + // page. + +#define FLASH_CTRL_DIECFG0_FLASH_SIZE_S 4 +#define FLASH_CTRL_DIECFG0_USB_ENABLE \ + 0x00000008 // Register copy of configuration + // bits Three clock cycles after + // reset is released, this bit is + // equal to the field with the same + // name in the information page. + +#define FLASH_CTRL_DIECFG0_USB_ENABLE_M \ + 0x00000008 +#define FLASH_CTRL_DIECFG0_USB_ENABLE_S 3 +#define FLASH_CTRL_DIECFG0_MASS_ERASE_ENABLE \ + 0x00000004 // Register copy of configuration + // bits Three clock cycles after + // reset is released, this bit is + // equal to the field with the same + // name in the information page. + +#define FLASH_CTRL_DIECFG0_MASS_ERASE_ENABLE_M \ + 0x00000004 +#define FLASH_CTRL_DIECFG0_MASS_ERASE_ENABLE_S 2 +#define FLASH_CTRL_DIECFG0_LOCK_FWT_N \ + 0x00000002 // Register copy of configuration + // bits Three clock cycles after + // reset is released, this bit is + // equal to the field with the same + // name in the information page. + +#define FLASH_CTRL_DIECFG0_LOCK_FWT_N_M \ + 0x00000002 +#define FLASH_CTRL_DIECFG0_LOCK_FWT_N_S 1 +#define FLASH_CTRL_DIECFG0_LOCK_IP_N \ + 0x00000001 // Register copy of configuration + // bits Three clock cycles after + // reset is released, this bit is + // equal to the field with the same + // name in the information page. + +#define FLASH_CTRL_DIECFG0_LOCK_IP_N_M \ + 0x00000001 +#define FLASH_CTRL_DIECFG0_LOCK_IP_N_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// FLASH_CTRL_DIECFG1 register. +// +//***************************************************************************** +#define FLASH_CTRL_DIECFG1_I2C_EN \ + 0x01000000 // 1: I2C is enabled. 0: I2C is + // permanently disabled. + +#define FLASH_CTRL_DIECFG1_I2C_EN_M \ + 0x01000000 +#define FLASH_CTRL_DIECFG1_I2C_EN_S 24 +#define FLASH_CTRL_DIECFG1_UART1_EN \ + 0x00020000 // 1: UART1 is enabled. 0: UART1 + // is permanently disabled. + +#define FLASH_CTRL_DIECFG1_UART1_EN_M \ + 0x00020000 +#define FLASH_CTRL_DIECFG1_UART1_EN_S 17 +#define FLASH_CTRL_DIECFG1_UART0_EN \ + 0x00010000 // 1: UART0 is enabled. 0: UART0 + // is permanently disabled. + +#define FLASH_CTRL_DIECFG1_UART0_EN_M \ + 0x00010000 +#define FLASH_CTRL_DIECFG1_UART0_EN_S 16 +#define FLASH_CTRL_DIECFG1_SSI1_EN \ + 0x00000200 // 1: SSI1 is enabled. 0: SSI1 is + // permanently disabled. + +#define FLASH_CTRL_DIECFG1_SSI1_EN_M \ + 0x00000200 +#define FLASH_CTRL_DIECFG1_SSI1_EN_S 9 +#define FLASH_CTRL_DIECFG1_SSI0_EN \ + 0x00000100 // 1: SSI0 is enabled. 0: SSI0 is + // permanently disabled. + +#define FLASH_CTRL_DIECFG1_SSI0_EN_M \ + 0x00000100 +#define FLASH_CTRL_DIECFG1_SSI0_EN_S 8 +#define FLASH_CTRL_DIECFG1_GPTM3_EN \ + 0x00000008 // 1: GPTM3 is enabled. 0: GPTM3 + // is permanently disabled. + +#define FLASH_CTRL_DIECFG1_GPTM3_EN_M \ + 0x00000008 +#define FLASH_CTRL_DIECFG1_GPTM3_EN_S 3 +#define FLASH_CTRL_DIECFG1_GPTM2_EN \ + 0x00000004 // 1: GPTM2 is enabled. 0: GPTM2 + // is permanently disabled. + +#define FLASH_CTRL_DIECFG1_GPTM2_EN_M \ + 0x00000004 +#define FLASH_CTRL_DIECFG1_GPTM2_EN_S 2 +#define FLASH_CTRL_DIECFG1_GPTM1_EN \ + 0x00000002 // 1: GPTM1 is enabled. 0: GPTM1 + // is permanently disabled. + +#define FLASH_CTRL_DIECFG1_GPTM1_EN_M \ + 0x00000002 +#define FLASH_CTRL_DIECFG1_GPTM1_EN_S 1 +#define FLASH_CTRL_DIECFG1_GPTM0_EN \ + 0x00000001 // 1: GPTM0 is enabled. 0: GPTM0 + // is permanently disabled. + +#define FLASH_CTRL_DIECFG1_GPTM0_EN_M \ + 0x00000001 +#define FLASH_CTRL_DIECFG1_GPTM0_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// FLASH_CTRL_DIECFG2 register. +// +//***************************************************************************** +#define FLASH_CTRL_DIECFG2_DIE_MAJOR_REVISION_M \ + 0x0000F000 // Indicates the major revision + // (all layer change) number for + // the cc2538 0x0 - PG1.0 0x2 - + // PG2.0 + +#define FLASH_CTRL_DIECFG2_DIE_MAJOR_REVISION_S 12 +#define FLASH_CTRL_DIECFG2_DIE_MINOR_REVISION_M \ + 0x00000F00 // Indicates the minor revision + // (metla layer only) number for + // the cc2538 0x0 - PG1.0 or PG2.0 + +#define FLASH_CTRL_DIECFG2_DIE_MINOR_REVISION_S 8 +#define FLASH_CTRL_DIECFG2_RF_CORE_EN \ + 0x00000004 // 1: RF_CORE is enabled. 0: + // RF_CORE is permanently disabled. + +#define FLASH_CTRL_DIECFG2_RF_CORE_EN_M \ + 0x00000004 +#define FLASH_CTRL_DIECFG2_RF_CORE_EN_S 2 +#define FLASH_CTRL_DIECFG2_AES_EN \ + 0x00000002 // 1: AES is enabled. 0: AES is + // permanently disabled. + +#define FLASH_CTRL_DIECFG2_AES_EN_M \ + 0x00000002 +#define FLASH_CTRL_DIECFG2_AES_EN_S 1 +#define FLASH_CTRL_DIECFG2_PKA_EN \ + 0x00000001 // 1: PKA is enabled. 0: PKA is + // permanently disabled. + +#define FLASH_CTRL_DIECFG2_PKA_EN_M \ + 0x00000001 +#define FLASH_CTRL_DIECFG2_PKA_EN_S 0 + + +#endif // __HW_FLASH_CTRL_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_gpio.h b/bsp/boards/mimsy2-cc2538/headers/hw_gpio.h new file mode 100644 index 0000000000..f92dfbd463 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_gpio.h @@ -0,0 +1,1299 @@ +/****************************************************************************** +* Filename: hw_gpio.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_GPIO_H__ +#define __HW_GPIO_H__ + +//***************************************************************************** +// +// The following are defines for the GPIO register offsets. +// +//***************************************************************************** +#define GPIO_O_DATA 0x00000000 // This is the data register. In + // software control mode, values + // written in the GPIODATA register + // are transferred onto the GPOUT + // pins if the respective pins have + // been configured as outputs + // through the GPIODIR register. A + // read from GPIODATA returns the + // last bit value written if the + // respective pins are configured + // as output, or it returns the + // value on the corresponding input + // GPIN bit when these are + // configured as inputs. +#define GPIO_O_DIR 0x00000400 // The DIR register is the data + // direction register. All bits are + // cleared by a reset; therefore, + // the GPIO pins are input by + // default. +#define GPIO_O_IS 0x00000404 // The IS register is the + // interrupt sense register. +#define GPIO_O_IBE 0x00000408 // The IBE register is the + // interrupt both-edges register. + // When the corresponding bit in IS + // is set to detect edges, bits set + // to high in IBE configure the + // corresponding pin to detect both + // rising and falling edges, + // regardless of the corresponding + // bit in the IEV (interrupt event + // register). Clearing a bit + // configures the pin to be + // controlled by IEV. +#define GPIO_O_IEV 0x0000040C // The IEV register is the + // interrupt event register. Bits + // set to high in IEV configure the + // corresponding pin to detect + // rising edges or high levels, + // depending on the corresponding + // bit value in IS. Clearing a bit + // configures the pin to detect + // falling edges or low levels, + // depending on the corresponding + // bit value in IS. +#define GPIO_O_IE 0x00000410 // The IE register is the + // interrupt mask register. Bits + // set to high in IE allow the + // corresponding pins to trigger + // their individual interrupts and + // the combined GPIOINTR line. + // Clearing a bit disables + // interrupt triggering on that + // pin. +#define GPIO_O_RIS 0x00000414 // The RIS register is the raw + // interrupt status register. Bits + // read high in RIS reflect the + // status of interrupts trigger + // conditions detected (raw, before + // masking), indicating that all + // the requirements are met, before + // they are finally allowed to + // trigger by IE. Bits read as 0 + // indicate that corresponding + // input pins have not initiated an + // interrupt. +#define GPIO_O_MIS 0x00000418 // The MIS register is the masked + // interrupt status register. Bits + // read high in MIS reflect the + // status of input lines triggering + // an interrupt. Bits read as low + // indicate that either no + // interrupt has been generated, or + // the interrupt is masked. MIS is + // the state of the interrupt after + // masking. +#define GPIO_O_IC 0x0000041C // The IC register is the + // interrupt clear register. + // Writing 1 to a bit in this + // register clears the + // corresponding interrupt edge + // detection logic register. + // Writing 0 has no effect. +#define GPIO_O_AFSEL 0x00000420 // The AFSEL register is the mode + // control select register. Writing + // 1 to any bit in this register + // selects the hardware + // (peripheral) control for the + // corresponding GPIO line. All + // bits are cleared by a reset, + // therefore no GPIO line is set to + // hardware control by default. +#define GPIO_O_GPIOLOCK 0x00000520 // A write of the value 0x4C4F434B + // to the GPIOLOCK register unlocks + // the GPIO commit register + // (GPIOCR) for write access. A + // write of any other value + // reapplies the lock, preventing + // any register updates. Any write + // to the commit register (GPIOCR) + // causes the lock register to be + // locked. +#define GPIO_O_GPIOCR 0x00000524 // The GPIOCR register is the + // commit register. The value of + // the GPIOCR register determines + // which bits of the AFSEL register + // is committed when a write to the + // AFSEL register is performed. If + // a bit in the GPIOCR register is + // 0, the data being written to the + // corresponding bit in the AFSEL + // register is not committed and + // retains its previous value. If a + // bit in the GPIOCR register is + // set to 1, the data being written + // to the corresponding bit of the + // AFSEL register is committed to + // the register and will reflect + // the new value. The contents of + // the GPIOCR register can only be + // modified if the GPIOLOCK + // register is unlocked. Writes to + // the GPIOCR register will be + // ignored if the GPIOLOCK register + // is locked. Any write to the + // commit register causes the lock + // register to be locked. +#define GPIO_O_PMUX 0x00000700 // The PMUX register can be used + // to output external decouple + // control and clock_32k on I/O + // pins. Decouple control can be + // output on specific PB pins and + // clock_32k can be output on a + // specific PA or PB pin. These + // features override the current + // setting of the selected pin when + // enabled. The pin is set to + // output, pull-up and -down + // disabled, and analog mode + // disabled. +#define GPIO_O_P_EDGE_CTRL 0x00000704 // The port edge control register + // is used to control which edge of + // each port input causes that port + // to generate a power-up interrupt + // to the system. +#define GPIO_O_USB_CTRL 0x00000708 // This register is used to + // control which edge of the USB + // controller input generates a + // power-up interrupt to the + // system. +#define GPIO_O_PI_IEN 0x00000710 // The power-up interrupt enable + // register selects, for its + // corresponding port A-D pin, + // whether interrupts are enabled + // or disabled. +#define GPIO_O_IRQ_DETECT_ACK 0x00000718 // If the IRQ detect ACK register + // is read, the value returned can + // be used to determine which + // enabled I/O port is responsible + // for creating a power-up + // interrupt to the system. Writing + // the IRQ detect ACK register is + // used to clear any number of + // individual port bits that may be + // signaling that an edge was + // detected as configured by the + // port edge control register and + // the interrupt control register. + // There is a self-clearing + // function to this register that + // generates a reset pulse to clear + // any interrupt which has its + // corresponding bit set to 1. +#define GPIO_O_USB_IRQ_ACK 0x0000071C // Same functionality as + // IRQ_DETECT_ACK, but for USB +#define GPIO_O_IRQ_DETECT_UNMASK \ + 0x00000720 // Same functionality as + // IRQ_DETECT_ACK, but this + // register handles masked + // interrupts + + + +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_DATA register. +// +//***************************************************************************** +#define GPIO_DATA_DATA_M 0x000000FF // Input and output data +#define GPIO_DATA_DATA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_DIR register. +// +//***************************************************************************** +#define GPIO_DIR_DIR_M 0x000000FF // Bits set: Corresponding pin is + // output Bits cleared: + // Corresponding pin is input +#define GPIO_DIR_DIR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_IS register. +// +//***************************************************************************** +#define GPIO_IS_IS_M 0x000000FF // Bits set: Level on + // corresponding pin is detected + // Bits cleared: Edge on + // corresponding pin is detected +#define GPIO_IS_IS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_IBE register. +// +//***************************************************************************** +#define GPIO_IBE_IBE_M 0x000000FF // Bits set: Both edges on + // corresponding pin trigger an + // interrupt Bits cleared: + // Interrupt generation event is + // controlled by GPIOIEV Single + // edge: Determined by + // corresponding bit in GPIOIEV + // register +#define GPIO_IBE_IBE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_IEV register. +// +//***************************************************************************** +#define GPIO_IEV_IEV_M 0x000000FF // Bits set: Rising edges or high + // levels on corresponding pin + // trigger interrupts Bits cleared: + // Falling edges or low levels on + // corresponding pin trigger + // interrupts +#define GPIO_IEV_IEV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_IE register. +// +//***************************************************************************** +#define GPIO_IE_IE_M 0x000000FF // Bits set: Corresponding pin is + // not masked Bits cleared: + // Corresponding pin is masked +#define GPIO_IE_IE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_RIS register. +// +//***************************************************************************** +#define GPIO_RIS_RIS_M 0x000000FF // Reflects the status of + // interrupts trigger conditions + // detected on pins (raw, before + // masking) Bits set: Requirements + // met by corresponding pins Bits + // clear: Requirements not met +#define GPIO_RIS_RIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_MIS register. +// +//***************************************************************************** +#define GPIO_MIS_MIS_M 0x000000FF // Masked value of interrupt due + // to corresponding pin Bits clear: + // GPIO line interrupt not active + // Bits set: GPIO line asserting + // interrupt +#define GPIO_MIS_MIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_IC register. +// +//***************************************************************************** +#define GPIO_IC_IC_M 0x000000FF // Bit written as 1: Clears edge + // detection logic Bit written as + // 0: Has no effect +#define GPIO_IC_IC_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_AFSEL register. +// +//***************************************************************************** +#define GPIO_AFSEL_AFSEL_M 0x000000FF // Bit set: Enables hardware + // (peripheral) control mode Bit + // cleared: Enables software + // control mode +#define GPIO_AFSEL_AFSEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPIO_O_GPIOLOCK register. +// +//***************************************************************************** +#define GPIO_GPIOLOCK_LOCK_M 0xFFFFFFFF // A read of this register returns + // the following values: Locked: + // 0x00000001 Unlocked: 0x00000000 +#define GPIO_GPIOLOCK_LOCK_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_GPIOCR register. +// +//***************************************************************************** +#define GPIO_GPIOCR_CR_M 0x000000FF // On a bit-wise basis, any bit + // set allows the corresponding + // GPIOAFSEL bit to be set to its + // alternate function. +#define GPIO_GPIOCR_CR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_PMUX register. +// +//***************************************************************************** +#define GPIO_PMUX_CKOEN 0x00000080 // Clock out enable When this bit + // is set, the 32-kHz clock is + // routed to either PA[0] or PB[7] + // pins. PMUX.CKOPIN selects the + // pin to use. This overrides the + // current configuration setting + // for this pin. The pullup or + // pulldown is disabled and the + // direction is set to output for + // this pin. +#define GPIO_PMUX_CKOEN_M 0x00000080 +#define GPIO_PMUX_CKOEN_S 7 +#define GPIO_PMUX_CKOPIN 0x00000010 // Decouple control pin select + // This control only has relevance + // when CKOEN is set. When 0, PA[0] + // becomes the 32-kHz clock output. + // When 1, PB[7] becomes the 32-kHz + // clock output. +#define GPIO_PMUX_CKOPIN_M 0x00000010 +#define GPIO_PMUX_CKOPIN_S 4 +#define GPIO_PMUX_DCEN 0x00000008 // Decouple control enable When + // this bit is set, the on-die + // digital regulator status is + // routed to either PB[1] or PB[0] + // pins. PMUX.DCPIN selects the pin + // to use. This overrides the + // current configuration setting + // for this pin. The pullup or + // pulldown is disabled and the + // direction is set to output for + // this pin. +#define GPIO_PMUX_DCEN_M 0x00000008 +#define GPIO_PMUX_DCEN_S 3 +#define GPIO_PMUX_DCPIN 0x00000001 // Decouple control pin select + // This control has relevance only + // when DCEN is set. When 0, PB[1] + // becomes the on-die digital + // regulator status (1 indicates + // the on-die digital regulator is + // active); when 1, PB[0] becomes + // the on-die digital regulator + // status. NOTE: PB[1] and PB[0] + // can also be controlled with + // other override features. In + // priority order for PB[1]: When + // POR/BOD test mode is active, + // PB[1] becomes the active low + // brown-out detected indicator. + // When DCEN is set and DCPIN is + // not set, PB[1] becomes the + // on-dir digital regulator status. + // In priority order for PB[0]: + // When POR/BOD test mode is + // active, PB[0] becomes the + // power-on-reset indicator. When + // DCEN and DCPIN are set, PB[0] + // becomes the on-die digital + // regulator status. +#define GPIO_PMUX_DCPIN_M 0x00000001 +#define GPIO_PMUX_DCPIN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPIO_O_P_EDGE_CTRL register. +// +//***************************************************************************** +#define GPIO_P_EDGE_CTRL_PDIRC7 0x80000000 // Port D bit 7 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PDIRC7_M \ + 0x80000000 +#define GPIO_P_EDGE_CTRL_PDIRC7_S 31 +#define GPIO_P_EDGE_CTRL_PDIRC6 0x40000000 // Port D bit 6 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PDIRC6_M \ + 0x40000000 +#define GPIO_P_EDGE_CTRL_PDIRC6_S 30 +#define GPIO_P_EDGE_CTRL_PDIRC5 0x20000000 // Port D bit 5 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PDIRC5_M \ + 0x20000000 +#define GPIO_P_EDGE_CTRL_PDIRC5_S 29 +#define GPIO_P_EDGE_CTRL_PDIRC4 0x10000000 // Port D bit 4 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PDIRC4_M \ + 0x10000000 +#define GPIO_P_EDGE_CTRL_PDIRC4_S 28 +#define GPIO_P_EDGE_CTRL_PDIRC3 0x08000000 // Port D bit 3 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PDIRC3_M \ + 0x08000000 +#define GPIO_P_EDGE_CTRL_PDIRC3_S 27 +#define GPIO_P_EDGE_CTRL_PDIRC2 0x04000000 // Port D bit 2 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PDIRC2_M \ + 0x04000000 +#define GPIO_P_EDGE_CTRL_PDIRC2_S 26 +#define GPIO_P_EDGE_CTRL_PDIRC1 0x02000000 // Port D bit 1 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PDIRC1_M \ + 0x02000000 +#define GPIO_P_EDGE_CTRL_PDIRC1_S 25 +#define GPIO_P_EDGE_CTRL_PDIRC0 0x01000000 // Port D bit 0 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PDIRC0_M \ + 0x01000000 +#define GPIO_P_EDGE_CTRL_PDIRC0_S 24 +#define GPIO_P_EDGE_CTRL_PCIRC7 0x00800000 // Port C bit 7 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PCIRC7_M \ + 0x00800000 +#define GPIO_P_EDGE_CTRL_PCIRC7_S 23 +#define GPIO_P_EDGE_CTRL_PCIRC6 0x00400000 // Port C bit 6 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PCIRC6_M \ + 0x00400000 +#define GPIO_P_EDGE_CTRL_PCIRC6_S 22 +#define GPIO_P_EDGE_CTRL_PCIRC5 0x00200000 // Port C bit 5 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PCIRC5_M \ + 0x00200000 +#define GPIO_P_EDGE_CTRL_PCIRC5_S 21 +#define GPIO_P_EDGE_CTRL_PCIRC4 0x00100000 // Port C bit 4 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PCIRC4_M \ + 0x00100000 +#define GPIO_P_EDGE_CTRL_PCIRC4_S 20 +#define GPIO_P_EDGE_CTRL_PCIRC3 0x00080000 // Port C bit 3 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PCIRC3_M \ + 0x00080000 +#define GPIO_P_EDGE_CTRL_PCIRC3_S 19 +#define GPIO_P_EDGE_CTRL_PCIRC2 0x00040000 // Port C bit 2 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PCIRC2_M \ + 0x00040000 +#define GPIO_P_EDGE_CTRL_PCIRC2_S 18 +#define GPIO_P_EDGE_CTRL_PCIRC1 0x00020000 // Port C bit 1 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PCIRC1_M \ + 0x00020000 +#define GPIO_P_EDGE_CTRL_PCIRC1_S 17 +#define GPIO_P_EDGE_CTRL_PCIRC0 0x00010000 // Port C bit 0 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PCIRC0_M \ + 0x00010000 +#define GPIO_P_EDGE_CTRL_PCIRC0_S 16 +#define GPIO_P_EDGE_CTRL_PBIRC7 0x00008000 // Port B bit 7 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PBIRC7_M \ + 0x00008000 +#define GPIO_P_EDGE_CTRL_PBIRC7_S 15 +#define GPIO_P_EDGE_CTRL_PBIRC6 0x00004000 // Port B bit 6 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PBIRC6_M \ + 0x00004000 +#define GPIO_P_EDGE_CTRL_PBIRC6_S 14 +#define GPIO_P_EDGE_CTRL_PBIRC5 0x00002000 // Port B bit 5 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PBIRC5_M \ + 0x00002000 +#define GPIO_P_EDGE_CTRL_PBIRC5_S 13 +#define GPIO_P_EDGE_CTRL_PBIRC4 0x00001000 // Port B bit 4 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PBIRC4_M \ + 0x00001000 +#define GPIO_P_EDGE_CTRL_PBIRC4_S 12 +#define GPIO_P_EDGE_CTRL_PBIRC3 0x00000800 // Port B bit 3 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PBIRC3_M \ + 0x00000800 +#define GPIO_P_EDGE_CTRL_PBIRC3_S 11 +#define GPIO_P_EDGE_CTRL_PBIRC2 0x00000400 // Port B bit 2 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PBIRC2_M \ + 0x00000400 +#define GPIO_P_EDGE_CTRL_PBIRC2_S 10 +#define GPIO_P_EDGE_CTRL_PBIRC1 0x00000200 // Port B bit 1 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PBIRC1_M \ + 0x00000200 +#define GPIO_P_EDGE_CTRL_PBIRC1_S 9 +#define GPIO_P_EDGE_CTRL_PBIRC0 0x00000100 // Port B bit 0 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PBIRC0_M \ + 0x00000100 +#define GPIO_P_EDGE_CTRL_PBIRC0_S 8 +#define GPIO_P_EDGE_CTRL_PAIRC7 0x00000080 // Port A bit 7 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PAIRC7_M \ + 0x00000080 +#define GPIO_P_EDGE_CTRL_PAIRC7_S 7 +#define GPIO_P_EDGE_CTRL_PAIRC6 0x00000040 // Port A bit 6 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PAIRC6_M \ + 0x00000040 +#define GPIO_P_EDGE_CTRL_PAIRC6_S 6 +#define GPIO_P_EDGE_CTRL_PAIRC5 0x00000020 // Port A bit 5 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PAIRC5_M \ + 0x00000020 +#define GPIO_P_EDGE_CTRL_PAIRC5_S 5 +#define GPIO_P_EDGE_CTRL_PAIRC4 0x00000010 // Port A bit 4 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PAIRC4_M \ + 0x00000010 +#define GPIO_P_EDGE_CTRL_PAIRC4_S 4 +#define GPIO_P_EDGE_CTRL_PAIRC3 0x00000008 // Port A bit 3 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PAIRC3_M \ + 0x00000008 +#define GPIO_P_EDGE_CTRL_PAIRC3_S 3 +#define GPIO_P_EDGE_CTRL_PAIRC2 0x00000004 // Port A bit 2 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PAIRC2_M \ + 0x00000004 +#define GPIO_P_EDGE_CTRL_PAIRC2_S 2 +#define GPIO_P_EDGE_CTRL_PAIRC1 0x00000002 // Port A bit 1 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PAIRC1_M \ + 0x00000002 +#define GPIO_P_EDGE_CTRL_PAIRC1_S 1 +#define GPIO_P_EDGE_CTRL_PAIRC0 0x00000001 // Port A bit 0 interrupt request + // condition: 0: Rising 1: Falling + // edge +#define GPIO_P_EDGE_CTRL_PAIRC0_M \ + 0x00000001 +#define GPIO_P_EDGE_CTRL_PAIRC0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPIO_O_USB_CTRL register. +// +//***************************************************************************** +#define GPIO_USB_CTRL_USB_EDGE_CTL \ + 0x00000001 // Used to set the edge which + // triggers the USB power up + // interrupt 0: Rising 1: Falling + +#define GPIO_USB_CTRL_USB_EDGE_CTL_M \ + 0x00000001 +#define GPIO_USB_CTRL_USB_EDGE_CTL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPIO_O_PI_IEN register. +// +//***************************************************************************** +#define GPIO_PI_IEN_PDIEN7 0x80000000 // Port D bit 7 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PDIEN7_M 0x80000000 +#define GPIO_PI_IEN_PDIEN7_S 31 +#define GPIO_PI_IEN_PDIEN6 0x40000000 // Port D bit 6 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PDIEN6_M 0x40000000 +#define GPIO_PI_IEN_PDIEN6_S 30 +#define GPIO_PI_IEN_PDIEN5 0x20000000 // Port D bit 5 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PDIEN5_M 0x20000000 +#define GPIO_PI_IEN_PDIEN5_S 29 +#define GPIO_PI_IEN_PDIEN4 0x10000000 // Port D bit 4 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PDIEN4_M 0x10000000 +#define GPIO_PI_IEN_PDIEN4_S 28 +#define GPIO_PI_IEN_PDIEN3 0x08000000 // Port D bit 3 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PDIEN3_M 0x08000000 +#define GPIO_PI_IEN_PDIEN3_S 27 +#define GPIO_PI_IEN_PDIEN2 0x04000000 // Port D bit 2 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PDIEN2_M 0x04000000 +#define GPIO_PI_IEN_PDIEN2_S 26 +#define GPIO_PI_IEN_PDIEN1 0x02000000 // Port D bit 1 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PDIEN1_M 0x02000000 +#define GPIO_PI_IEN_PDIEN1_S 25 +#define GPIO_PI_IEN_PDIEN0 0x01000000 // Port D bit 0 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PDIEN0_M 0x01000000 +#define GPIO_PI_IEN_PDIEN0_S 24 +#define GPIO_PI_IEN_PCIEN7 0x00800000 // Port C bit 7 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PCIEN7_M 0x00800000 +#define GPIO_PI_IEN_PCIEN7_S 23 +#define GPIO_PI_IEN_PCIEN6 0x00400000 // Port C bit 6 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PCIEN6_M 0x00400000 +#define GPIO_PI_IEN_PCIEN6_S 22 +#define GPIO_PI_IEN_PCIEN5 0x00200000 // Port C bit 5 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PCIEN5_M 0x00200000 +#define GPIO_PI_IEN_PCIEN5_S 21 +#define GPIO_PI_IEN_PCIEN4 0x00100000 // Port C bit 4 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PCIEN4_M 0x00100000 +#define GPIO_PI_IEN_PCIEN4_S 20 +#define GPIO_PI_IEN_PCIEN3 0x00080000 // Port C bit 3 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PCIEN3_M 0x00080000 +#define GPIO_PI_IEN_PCIEN3_S 19 +#define GPIO_PI_IEN_PCIEN2 0x00040000 // Port C bit 2 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PCIEN2_M 0x00040000 +#define GPIO_PI_IEN_PCIEN2_S 18 +#define GPIO_PI_IEN_PCIEN1 0x00020000 // Port C bit 1 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PCIEN1_M 0x00020000 +#define GPIO_PI_IEN_PCIEN1_S 17 +#define GPIO_PI_IEN_PCIEN0 0x00010000 // Port C bit 0 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PCIEN0_M 0x00010000 +#define GPIO_PI_IEN_PCIEN0_S 16 +#define GPIO_PI_IEN_PBIEN7 0x00008000 // Port B bit 7 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PBIEN7_M 0x00008000 +#define GPIO_PI_IEN_PBIEN7_S 15 +#define GPIO_PI_IEN_PBIEN6 0x00004000 // Port B bit 6 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PBIEN6_M 0x00004000 +#define GPIO_PI_IEN_PBIEN6_S 14 +#define GPIO_PI_IEN_PBIEN5 0x00002000 // Port B bit 5 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PBIEN5_M 0x00002000 +#define GPIO_PI_IEN_PBIEN5_S 13 +#define GPIO_PI_IEN_PBIEN4 0x00001000 // Port B bit 4 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PBIEN4_M 0x00001000 +#define GPIO_PI_IEN_PBIEN4_S 12 +#define GPIO_PI_IEN_PBIEN3 0x00000800 // Port B bit 3 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PBIEN3_M 0x00000800 +#define GPIO_PI_IEN_PBIEN3_S 11 +#define GPIO_PI_IEN_PBIEN2 0x00000400 // Port B bit 2 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PBIEN2_M 0x00000400 +#define GPIO_PI_IEN_PBIEN2_S 10 +#define GPIO_PI_IEN_PBIEN1 0x00000200 // Port B bit 1 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PBIEN1_M 0x00000200 +#define GPIO_PI_IEN_PBIEN1_S 9 +#define GPIO_PI_IEN_PBIEN0 0x00000100 // Port B bit 0 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PBIEN0_M 0x00000100 +#define GPIO_PI_IEN_PBIEN0_S 8 +#define GPIO_PI_IEN_PAIEN7 0x00000080 // Port A bit 7 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PAIEN7_M 0x00000080 +#define GPIO_PI_IEN_PAIEN7_S 7 +#define GPIO_PI_IEN_PAIEN6 0x00000040 // Port A bit 6 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PAIEN6_M 0x00000040 +#define GPIO_PI_IEN_PAIEN6_S 6 +#define GPIO_PI_IEN_PAIEN5 0x00000020 // Port A bit 5 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PAIEN5_M 0x00000020 +#define GPIO_PI_IEN_PAIEN5_S 5 +#define GPIO_PI_IEN_PAIEN4 0x00000010 // Port A bit 4 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PAIEN4_M 0x00000010 +#define GPIO_PI_IEN_PAIEN4_S 4 +#define GPIO_PI_IEN_PAIEN3 0x00000008 // Port A bit 3 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PAIEN3_M 0x00000008 +#define GPIO_PI_IEN_PAIEN3_S 3 +#define GPIO_PI_IEN_PAIEN2 0x00000004 // Port A bit 2 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PAIEN2_M 0x00000004 +#define GPIO_PI_IEN_PAIEN2_S 2 +#define GPIO_PI_IEN_PAIEN1 0x00000002 // Port A bit 1 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PAIEN1_M 0x00000002 +#define GPIO_PI_IEN_PAIEN1_S 1 +#define GPIO_PI_IEN_PAIEN0 0x00000001 // Port A bit 0 interrupt enable: + // 1: Enabled 2: Disabled +#define GPIO_PI_IEN_PAIEN0_M 0x00000001 +#define GPIO_PI_IEN_PAIEN0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPIO_O_IRQ_DETECT_ACK register. +// +//***************************************************************************** +#define GPIO_IRQ_DETECT_ACK_PDIACK7 \ + 0x80000000 // Port D bit 7 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PDIACK7_M \ + 0x80000000 +#define GPIO_IRQ_DETECT_ACK_PDIACK7_S 31 +#define GPIO_IRQ_DETECT_ACK_PDIACK6 \ + 0x40000000 // Port D bit 6 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PDIACK6_M \ + 0x40000000 +#define GPIO_IRQ_DETECT_ACK_PDIACK6_S 30 +#define GPIO_IRQ_DETECT_ACK_PDIACK5 \ + 0x20000000 // Port D bit 5 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PDIACK5_M \ + 0x20000000 +#define GPIO_IRQ_DETECT_ACK_PDIACK5_S 29 +#define GPIO_IRQ_DETECT_ACK_PDIACK4 \ + 0x10000000 // Port D bit 4 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PDIACK4_M \ + 0x10000000 +#define GPIO_IRQ_DETECT_ACK_PDIACK4_S 28 +#define GPIO_IRQ_DETECT_ACK_PDIACK3 \ + 0x08000000 // Port D bit 3 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PDIACK3_M \ + 0x08000000 +#define GPIO_IRQ_DETECT_ACK_PDIACK3_S 27 +#define GPIO_IRQ_DETECT_ACK_PDIACK2 \ + 0x04000000 // Port D bit 2 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PDIACK2_M \ + 0x04000000 +#define GPIO_IRQ_DETECT_ACK_PDIACK2_S 26 +#define GPIO_IRQ_DETECT_ACK_PDIACK1 \ + 0x02000000 // Port D bit 1 masked interrupt + // status: 1: Detected0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PDIACK1_M \ + 0x02000000 +#define GPIO_IRQ_DETECT_ACK_PDIACK1_S 25 +#define GPIO_IRQ_DETECT_ACK_PDIACK0 \ + 0x01000000 // Port D bit 0 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PDIACK0_M \ + 0x01000000 +#define GPIO_IRQ_DETECT_ACK_PDIACK0_S 24 +#define GPIO_IRQ_DETECT_ACK_PCIACK7 \ + 0x00800000 // Port C bit 7 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PCIACK7_M \ + 0x00800000 +#define GPIO_IRQ_DETECT_ACK_PCIACK7_S 23 +#define GPIO_IRQ_DETECT_ACK_PCIACK6 \ + 0x00400000 // Port C bit 6 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PCIACK6_M \ + 0x00400000 +#define GPIO_IRQ_DETECT_ACK_PCIACK6_S 22 +#define GPIO_IRQ_DETECT_ACK_PCIACK5 \ + 0x00200000 // Port C bit 5 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PCIACK5_M \ + 0x00200000 +#define GPIO_IRQ_DETECT_ACK_PCIACK5_S 21 +#define GPIO_IRQ_DETECT_ACK_PCIACK4 \ + 0x00100000 // Port C bit 4 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PCIACK4_M \ + 0x00100000 +#define GPIO_IRQ_DETECT_ACK_PCIACK4_S 20 +#define GPIO_IRQ_DETECT_ACK_PCIACK3 \ + 0x00080000 // Port C bit 3 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PCIACK3_M \ + 0x00080000 +#define GPIO_IRQ_DETECT_ACK_PCIACK3_S 19 +#define GPIO_IRQ_DETECT_ACK_PCIACK2 \ + 0x00040000 // Port C bit 2 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PCIACK2_M \ + 0x00040000 +#define GPIO_IRQ_DETECT_ACK_PCIACK2_S 18 +#define GPIO_IRQ_DETECT_ACK_PCIACK1 \ + 0x00020000 // Port C bit 1 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PCIACK1_M \ + 0x00020000 +#define GPIO_IRQ_DETECT_ACK_PCIACK1_S 17 +#define GPIO_IRQ_DETECT_ACK_PCIACK0 \ + 0x00010000 // Port C bit 0 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PCIACK0_M \ + 0x00010000 +#define GPIO_IRQ_DETECT_ACK_PCIACK0_S 16 +#define GPIO_IRQ_DETECT_ACK_PBIACK7 \ + 0x00008000 // Port B bit 7 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PBIACK7_M \ + 0x00008000 +#define GPIO_IRQ_DETECT_ACK_PBIACK7_S 15 +#define GPIO_IRQ_DETECT_ACK_PBIACK6 \ + 0x00004000 // Port B bit 6 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PBIACK6_M \ + 0x00004000 +#define GPIO_IRQ_DETECT_ACK_PBIACK6_S 14 +#define GPIO_IRQ_DETECT_ACK_PBIACK5 \ + 0x00002000 // Port B bit 5 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PBIACK5_M \ + 0x00002000 +#define GPIO_IRQ_DETECT_ACK_PBIACK5_S 13 +#define GPIO_IRQ_DETECT_ACK_PBIACK4 \ + 0x00001000 // Port B bit 4 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PBIACK4_M \ + 0x00001000 +#define GPIO_IRQ_DETECT_ACK_PBIACK4_S 12 +#define GPIO_IRQ_DETECT_ACK_PBIACK3 \ + 0x00000800 // Port B bit 3 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PBIACK3_M \ + 0x00000800 +#define GPIO_IRQ_DETECT_ACK_PBIACK3_S 11 +#define GPIO_IRQ_DETECT_ACK_PBIACK2 \ + 0x00000400 // Port B bit 2 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PBIACK2_M \ + 0x00000400 +#define GPIO_IRQ_DETECT_ACK_PBIACK2_S 10 +#define GPIO_IRQ_DETECT_ACK_PBIACK1 \ + 0x00000200 // Port B bit 1 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PBIACK1_M \ + 0x00000200 +#define GPIO_IRQ_DETECT_ACK_PBIACK1_S 9 +#define GPIO_IRQ_DETECT_ACK_PBIACK0 \ + 0x00000100 // Port B bit 0 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PBIACK0_M \ + 0x00000100 +#define GPIO_IRQ_DETECT_ACK_PBIACK0_S 8 +#define GPIO_IRQ_DETECT_ACK_PAIACK7 \ + 0x00000080 // Port A bit 7 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PAIACK7_M \ + 0x00000080 +#define GPIO_IRQ_DETECT_ACK_PAIACK7_S 7 +#define GPIO_IRQ_DETECT_ACK_PAIACK6 \ + 0x00000040 // Port A bit 6 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PAIACK6_M \ + 0x00000040 +#define GPIO_IRQ_DETECT_ACK_PAIACK6_S 6 +#define GPIO_IRQ_DETECT_ACK_PAIACK5 \ + 0x00000020 // Port A bit 5 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PAIACK5_M \ + 0x00000020 +#define GPIO_IRQ_DETECT_ACK_PAIACK5_S 5 +#define GPIO_IRQ_DETECT_ACK_PAIACK4 \ + 0x00000010 // Port A bit 4 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PAIACK4_M \ + 0x00000010 +#define GPIO_IRQ_DETECT_ACK_PAIACK4_S 4 +#define GPIO_IRQ_DETECT_ACK_PAIACK3 \ + 0x00000008 // Port A bit 3 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PAIACK3_M \ + 0x00000008 +#define GPIO_IRQ_DETECT_ACK_PAIACK3_S 3 +#define GPIO_IRQ_DETECT_ACK_PAIACK2 \ + 0x00000004 // Port A bit 2 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PAIACK2_M \ + 0x00000004 +#define GPIO_IRQ_DETECT_ACK_PAIACK2_S 2 +#define GPIO_IRQ_DETECT_ACK_PAIACK1 \ + 0x00000002 // Port A bit 1 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PAIACK1_M \ + 0x00000002 +#define GPIO_IRQ_DETECT_ACK_PAIACK1_S 1 +#define GPIO_IRQ_DETECT_ACK_PAIACK0 \ + 0x00000001 // Port A bit 0 masked interrupt + // status: 1: Detected 0: Not + // detected + +#define GPIO_IRQ_DETECT_ACK_PAIACK0_M \ + 0x00000001 +#define GPIO_IRQ_DETECT_ACK_PAIACK0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPIO_O_USB_IRQ_ACK register. +// +//***************************************************************************** +#define GPIO_USB_IRQ_ACK_USBACK 0x00000001 // USB masked interrupt status: 1: + // Detected 0: Not detected +#define GPIO_USB_IRQ_ACK_USBACK_M \ + 0x00000001 +#define GPIO_USB_IRQ_ACK_USBACK_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPIO_O_IRQ_DETECT_UNMASK register. +// +//***************************************************************************** +#define GPIO_IRQ_DETECT_UNMASK_PDIACK7 \ + 0x80000000 // Port D bit 7 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PDIACK7_M \ + 0x80000000 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK7_S 31 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK6 \ + 0x40000000 // Port D bit 6 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PDIACK6_M \ + 0x40000000 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK6_S 30 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK5 \ + 0x20000000 // Port D bit 5 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PDIACK5_M \ + 0x20000000 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK5_S 29 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK4 \ + 0x10000000 // Port D bit 4 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PDIACK4_M \ + 0x10000000 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK4_S 28 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK3 \ + 0x08000000 // Port D bit 3 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PDIACK3_M \ + 0x08000000 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK3_S 27 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK2 \ + 0x04000000 // Port D bit 2 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PDIACK2_M \ + 0x04000000 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK2_S 26 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK1 \ + 0x02000000 // Port D bit 1 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PDIACK1_M \ + 0x02000000 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK1_S 25 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK0 \ + 0x01000000 // Port D bit 0 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PDIACK0_M \ + 0x01000000 +#define GPIO_IRQ_DETECT_UNMASK_PDIACK0_S 24 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK7 \ + 0x00800000 // Port C bit 7 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PCIACK7_M \ + 0x00800000 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK7_S 23 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK6 \ + 0x00400000 // Port C bit 6 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PCIACK6_M \ + 0x00400000 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK6_S 22 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK5 \ + 0x00200000 // Port C bit 5 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PCIACK5_M \ + 0x00200000 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK5_S 21 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK4 \ + 0x00100000 // Port C bit 4 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PCIACK4_M \ + 0x00100000 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK4_S 20 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK3 \ + 0x00080000 // Port C bit 3 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PCIACK3_M \ + 0x00080000 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK3_S 19 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK2 \ + 0x00040000 // Port C bit 2 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PCIACK2_M \ + 0x00040000 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK2_S 18 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK1 \ + 0x00020000 // Port C bit 1 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PCIACK1_M \ + 0x00020000 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK1_S 17 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK0 \ + 0x00010000 // Port C bit 0 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PCIACK0_M \ + 0x00010000 +#define GPIO_IRQ_DETECT_UNMASK_PCIACK0_S 16 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK7 \ + 0x00008000 // Port B bit 7 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PBIACK7_M \ + 0x00008000 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK7_S 15 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK6 \ + 0x00004000 // Port B bit 6 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PBIACK6_M \ + 0x00004000 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK6_S 14 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK5 \ + 0x00002000 // Port B bit 5 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PBIACK5_M \ + 0x00002000 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK5_S 13 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK4 \ + 0x00001000 // Port B bit 4 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PBIACK4_M \ + 0x00001000 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK4_S 12 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK3 \ + 0x00000800 // Port B bit 3 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PBIACK3_M \ + 0x00000800 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK3_S 11 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK2 \ + 0x00000400 // Port B bit 2 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PBIACK2_M \ + 0x00000400 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK2_S 10 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK1 \ + 0x00000200 // Port B bit 1 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PBIACK1_M \ + 0x00000200 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK1_S 9 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK0 \ + 0x00000100 // Port B bit 0 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PBIACK0_M \ + 0x00000100 +#define GPIO_IRQ_DETECT_UNMASK_PBIACK0_S 8 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK7 \ + 0x00000080 // Port A bit 7 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PAIACK7_M \ + 0x00000080 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK7_S 7 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK6 \ + 0x00000040 // Port A bit 6 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PAIACK6_M \ + 0x00000040 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK6_S 6 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK5 \ + 0x00000020 // Port A bit 5 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PAIACK5_M \ + 0x00000020 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK5_S 5 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK4 \ + 0x00000010 // Port A bit 4 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PAIACK4_M \ + 0x00000010 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK4_S 4 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK3 \ + 0x00000008 // Port A bit 3 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PAIACK3_M \ + 0x00000008 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK3_S 3 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK2 \ + 0x00000004 // Port A bit 2 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PAIACK2_M \ + 0x00000004 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK2_S 2 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK1 \ + 0x00000002 // Port A bit 1 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PAIACK1_M \ + 0x00000002 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK1_S 1 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK0 \ + 0x00000001 // Port A bit 0 unmasked interrupt + // status: 1: Detected 0: + // Undetected + +#define GPIO_IRQ_DETECT_UNMASK_PAIACK0_M \ + 0x00000001 +#define GPIO_IRQ_DETECT_UNMASK_PAIACK0_S 0 + + +#endif // __HW_GPIO_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_gptimer.h b/bsp/boards/mimsy2-cc2538/headers/hw_gptimer.h new file mode 100644 index 0000000000..739712e3bf --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_gptimer.h @@ -0,0 +1,1031 @@ +/****************************************************************************** +* Filename: hw_gptimer.h +* Revised: $Date: 2013-04-12 15:10:54 +0200 (Fri, 12 Apr 2013) $ +* Revision: $Revision: 9735 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_GPTIMER_H__ +#define __HW_GPTIMER_H__ + +//***************************************************************************** +// +// The following are defines for the GPTIMER register offsets. +// +//***************************************************************************** +#define GPTIMER_O_CFG 0x00000000 // GPTM configuration This + // register configures the global + // operation of the GPTM. The value + // written to this register + // determines whether the GPTM is + // in 32-bit mode (concatenated + // timers) or in 16-bit mode + // (individual, split timers). +#define GPTIMER_O_TAMR 0x00000004 // GPTM Timer A mode This register + // configures the GPTM based on the + // configuration selected in the + // CFG register. This register + // controls the modes for Timer A + // when it is used individually. + // When Timer A and Timer B are + // concatenated, this register + // controls the modes for both + // Timer A and Timer B, and the + // contents of TBMR are ignored. +#define GPTIMER_O_TBMR 0x00000008 // GPTM Timer B mode This register + // configures the GPTM based on the + // configuration selected in the + // CFG register. This register + // controls the modes for Timer B + // when it is used individually. + // When Timer A and Timer B are + // concatenated, this register is + // ignored and TBMR controls the + // modes for both Timer A and Timer + // B. +#define GPTIMER_O_CTL 0x0000000C // GPTM control This register is + // used alongside the CFG and TnMR + // registers to fine-tune the timer + // configuration, and to enable + // other features such as timer + // stall. +#define GPTIMER_O_SYNC 0x00000010 // GPTM synchronize Note: This + // register is implemented on GPTM + // 0 base address only. This + // register does however, allow + // software to synchronize a number + // of timers. +#define GPTIMER_O_IMR 0x00000018 // GPTM interrupt mask This + // register allows software to + // enable and disable GPTM + // controller-level interrupts. + // Setting a bit enables the + // corresponding interrupt, while + // clearing a bit disables it. +#define GPTIMER_O_RIS 0x0000001C // GPTM raw interrupt status This + // register shows the state of the + // GPTM internal interrupt signal. + // These bits are set whether or + // not the interrupt is masked in + // the IMR register. Each bit can + // be cleared by writing 1 to its + // corresponding bit in ICR. +#define GPTIMER_O_MIS 0x00000020 // GPTM masked interrupt status + // This register shows the state of + // the GPTM controller-level + // interrupt. If an interrupt is + // unmasked in IMR, and there is an + // event that causes the interrupt + // to be asserted, the + // corresponding bit is set in this + // register. All bits are cleared + // by writing 1 to the + // corresponding bit in ICR. +#define GPTIMER_O_ICR 0x00000024 // GPTM interrupt clear This + // register is used to clear the + // status bits in the RIS and MIS + // registers. Writing 1 to a bit + // clears the corresponding bit in + // the RIS and MIS registers. +#define GPTIMER_O_TAILR 0x00000028 // GPTM Timer A interval load When + // the Timer is counting down, this + // register is used to load the + // starting count value into the + // Timer. When the Timer is + // counting up, this register sets + // the upper bound for the timeout + // event. When a GPTM is configured + // to one of the 32-bit modes, + // TAILR appears as a 32-bit + // register (the upper 16-bits + // correspond to the contents of + // the GPTM Timer B Interval Load + // (TBILR) register). In a 16-bit + // mode, the upper 16 bits of this + // register read as 0s and have no + // effect on the state of TBILR. +#define GPTIMER_O_TBILR 0x0000002C // GPTM Timer B interval load When + // the Timer is counting down, this + // register is used to load the + // starting count value into the + // Timer. When the Timer is + // counting up, this register sets + // the upper bound for the time-out + // event. When a GPTM is configured + // to one of the 32-bit modes, the + // contents of bits [15:0] in this + // register are loaded into the + // upper 16 bits of the TAILR + // register. Reads from this + // register return the current + // value of Timer B and writes are + // ignored. In a 16-bit mode, bits + // [15:0] are used for the load + // value. Bits [31:16] are reserved + // in both cases. +#define GPTIMER_O_TAMATCHR 0x00000030 // GPTM Timer A match This + // register is loaded with a match + // value. Interrupts can be + // generated when the Timer value + // is equal to the value in this + // register in one-shot or periodic + // mode. When a GPTM is configured + // to one of the 32-bit modes, + // TAMATCHR appears as a 32-bit + // register (the upper 16-bits + // correspond to the contents of + // the GPTM Timer B match + // (GPTMTBMATCHR) register). In a + // 16-bit mode, the upper 16 bits + // of this register read as 0s and + // have no effect on the state of + // TBMATCHR. +#define GPTIMER_O_TBMATCHR 0x00000034 // PTM Timer B match This register + // is loaded with a match value. + // Interrupts can be generated when + // the Timer value is equal to the + // value in this register in + // one-shot or periodic mode. When + // a GPTM is configured to one of + // the 32-bit modes, the contents + // of bits [15:0] in this register + // are loaded into the upper 16 + // bits of the TAMATCHR register. + // Reads from this register return + // the current match value of Timer + // B and writes are ignored. In a + // 16-bit mode, bits [15:0] are + // used for the match value. Bits + // [31:16] are reserved in both + // cases. +#define GPTIMER_O_TAPR 0x00000038 // GPTM Timer A prescale This + // register allows software to + // extend the range of the 16-bit + // Timers in periodic and one-shot + // modes. +#define GPTIMER_O_TBPR 0x0000003C // GPTM Timer B prescale This + // register allows software to + // extend the range of the 16-bit + // Timers in periodic and one-shot + // modes. +#define GPTIMER_O_TAPMR 0x00000040 // GPTM Timer A prescale match + // This register effectively + // extends the range of TAMATCHR to + // 24 bits when operating in + // 16-bit, one-shot or periodic + // mode. +#define GPTIMER_O_TBPMR 0x00000044 // GPTM Timer B prescale match + // This register effectively + // extends the range ofMTBMATCHR to + // 24 bits when operating in + // 16-bit, one-shot or periodic + // mode. +#define GPTIMER_O_TAR 0x00000048 // GPTM Timer A This register + // shows the current value of the + // Timer A counter. When a GPTM is + // configured to one of the 32-bit + // modes, TAR appears as a 32-bit + // register (the upper 16-bits + // correspond to the contents of + // the GPTM Timer B (TBR) + // register). In the16-bit Input + // edge count, input edge time, and + // PWM modes, bits [15:0] contain + // the value of the counter and + // bits 23:16 contain the value of + // the prescaler, which is the + // upper 8 bits of the count. Bits + // [31:24] always read as 0. To + // read the value of the prescaler + // in 16-bit, one-shot and periodic + // modes, read bits [23:16] in the + // TAV register. +#define GPTIMER_O_TBR 0x0000004C // GPTM Timer B This register + // shows the current value of the + // Timer B counter. When a GPTM is + // configured to one of the 32-bit + // modes, the contents of bits + // [15:0] in this register are + // loaded into the upper 16 bits of + // the TAR register. Reads from + // this register return the current + // value of Timer B. In a 16-bit + // mode, bits 15:0 contain the + // value of the counter and bits + // [23:16] contain the value of the + // prescaler in Input edge count, + // input edge time, and PWM modes, + // which is the upper 8 bits of the + // count. Bits [31:24] always read + // as 0. To read the value of the + // prescaler in 16-bit, one-shot + // and periodic modes, read bits + // [23:16] in the TBV register. +#define GPTIMER_O_TAV 0x00000050 // GPTM Timer A value When read, + // this register shows the current, + // free-running value of Timer A in + // all modes. Software can use this + // value to determine the time + // elapsed between an interrupt and + // the ISR entry when using the + // snapshot feature with the + // periodic operating mode. When + // written, the value written into + // this register is loaded into the + // TAR register on the next clock + // cycle. When a GPTM is configured + // to one of the 32-bit modes, TAV + // appears as a 32-bit register + // (the upper 16-bits correspond to + // the contents of the GPTM Timer B + // Value (TBV) register). In a + // 16-bit mode, bits [15:0] contain + // the value of the counter and + // bits [23:16] contain the + // current, free-running value of + // the prescaler, which is the + // upper 8 bits of the count in + // input edge count, input edge + // time, PWM and one-shot or + // periodic up count modes. In + // one-shot or periodic down count + // modes, the prescaler stored in + // [23:16] is a true prescaler, + // meaning bits [23:16] count down + // before decrementing the value in + // bits [15:0]. The prescaler its + // [31:24] always read as 0. +#define GPTIMER_O_TBV 0x00000054 // GPTM Timer B value When read, + // this register shows the current, + // free-running value of Timer B in + // all modes. Software can use this + // value to determine the time + // elapsed between an interrupt and + // the ISR entry. When written, the + // value written into this register + // is loaded into the TBR register + // on the next clock cycle. When a + // GPTM is configured to one of the + // 32-bit modes, the contents of + // bits 15:0 in this register are + // loaded into the upper 16 bits of + // the TAV register. Reads from + // this register return the current + // free-running value of Timer B. + // In a 16-bit mode, bits [15:0] + // contain the value of the counter + // and bits [23:16] contain the + // current, free-running value of + // the prescaler, which is the + // upper 8 bits of the count in + // input edge count, input edge + // time, PWM and one-shot or + // periodic up count modes. In + // one-shot or periodic down count + // modes, the prescaler stored in + // [23:16] is a true prescaler, + // meaning bits [23:16] count down + // before decrementing the value in + // bits [15:0]. The prescaler its + // [31:24] always read as 0. +#define GPTIMER_O_TAPS 0x0000005C // GPTM Timer A prescale snapshot + // For the 32-bit wide GPTM, this + // register shows the current value + // of the Timer A prescaler in the + // 32-bit modes. This register is + // ununsed in 16-bit GPTM mode. +#define GPTIMER_O_TBPS 0x00000060 // GPTM Timer B prescale snapshot + // For the 32-bit wide GPTM, this + // register shows the current value + // of the Timer B prescaler in the + // 32-bit modes. This register is + // ununsed in 16-bit GPTM mode. +#define GPTIMER_O_TAPV 0x00000064 // GPTM Timer A prescale value For + // the 32-bit wide GPTM, this + // register shows the current + // free-running value of the Timer + // A prescaler in the 32-bit modes. + // Software can use this value in + // conjunction with the TAV + // register to determine the time + // elapsed between an interrupt and + // the ISR entry. This register is + // ununsed in 16- or 32-bit GPTM + // mode. +#define GPTIMER_O_TBPV 0x00000068 // GPTM Timer B prescale value For + // the 32-bit wide GPTM, this + // register shows the current + // free-running value of the Timer + // B prescaler in the 32-bit modes. + // Software can use this value in + // conjunction with the TBV + // register to determine the time + // elapsed between an interrupt and + // the ISR entry. This register is + // ununsed in 16- or 32-bit GPTM + // mode. +#define GPTIMER_O_PP 0x00000FC0 // GPTM peripheral properties The + // PP register provides information + // regarding the properties of the + // general-purpose Timer module. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_CFG register. +// +//***************************************************************************** +#define GPTIMER_CFG_GPTMCFG_M 0x00000007 // GPTM configuration The GPTMCFG + // values are defined as follows: + // 0x0: 32-bit timer configuration. + // 0x1: 32-bit real-time clock 0x2: + // Reserved 0x3: Reserved 0x4: + // 16-bit timer configuration. The + // function is controlled by bits + // [1:0] of GPTMTAMR and GPTMTBMR. + // 0x5-0x7: Reserved +#define GPTIMER_CFG_GPTMCFG_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TAMR register. +// +//***************************************************************************** +#define GPTIMER_TAMR_TAPLO 0x00000800 // Legacy PWM operation 0: Legacy + // operation 1: CCP is set to 1 on + // time-out. +#define GPTIMER_TAMR_TAPLO_M 0x00000800 +#define GPTIMER_TAMR_TAPLO_S 11 +#define GPTIMER_TAMR_TAMRSU 0x00000400 // Timer A match register update + // mode 0: Update GPTMAMATCHR and + // GPTMAPR if used on the next + // cycle. 1: Update GPTMAMATCHR and + // GPTMAPR if used on the next + // time-out. If the timer is + // disabled (TAEN is clear) when + // this bit is set, GPTMTAMATCHR + // and GPTMTAPR are updated when + // the timer is enabled. If the + // timer is stalled (TASTALL is + // set), GPTMTAMATCHR and GPTMTAPR + // are updated according to the + // configuration of this bit. +#define GPTIMER_TAMR_TAMRSU_M 0x00000400 +#define GPTIMER_TAMR_TAMRSU_S 10 +#define GPTIMER_TAMR_TAPWMIE 0x00000200 // GPTM Timer A PWM interrupt + // enable This bit enables + // interrupts in PWM mode on + // rising, falling, or both edges + // of the CCP output. 0: Interrupt + // is disabled. 1: Interrupt is + // enabled. This bit is valid only + // in PWM mode. +#define GPTIMER_TAMR_TAPWMIE_M 0x00000200 +#define GPTIMER_TAMR_TAPWMIE_S 9 +#define GPTIMER_TAMR_TAILD 0x00000100 // GPTM Timer A PWM interval load + // write 0: Update the GPTMTAR + // register with the value in the + // GPTMTAILR register on the next + // cycle. If the prescaler is used, + // update the GPTMTAPS register + // with the value in the GPTMTAPR + // register on the next cycle. 1: + // Update the GPTMTAR register with + // the value in the GPTMTAILR + // register on the next cycle. If + // the prescaler is used, update + // the GPTMTAPS register with the + // value in the GPTMTAPR register + // on the next time-out. +#define GPTIMER_TAMR_TAILD_M 0x00000100 +#define GPTIMER_TAMR_TAILD_S 8 +#define GPTIMER_TAMR_TASNAPS 0x00000080 // GPTM Timer A snap-shot mode 0: + // Snap-shot mode is disabled. 1: + // If Timer A is configured in + // periodic mode, the actual + // free-running value of Timer A is + // loaded at the time-out event + // into the GPTM Timer A (GPTMTAR) + // register. +#define GPTIMER_TAMR_TASNAPS_M 0x00000080 +#define GPTIMER_TAMR_TASNAPS_S 7 +#define GPTIMER_TAMR_TAWOT 0x00000040 // GPTM Timer A wait-on-trigger 0: + // Timer A begins counting as soon + // as it is enabled. 1: If Timer A + // is enabled (TAEN is set in the + // GPTMCTL register), Timer A does + // not begin counting until it + // receives a trigger from the + // Timer in the previous position + // in the daisy-chain. This bit + // must be clear for GP Timer + // module 0, Timer A. +#define GPTIMER_TAMR_TAWOT_M 0x00000040 +#define GPTIMER_TAMR_TAWOT_S 6 +#define GPTIMER_TAMR_TAMIE 0x00000020 // GPTM Timer A match interrupt + // enable 0: The match interrupt is + // disabled. 1: An interrupt is + // generated when the match value + // in the GPTMTAMATCHR register is + // reached in the one-shot and + // periodic modes. +#define GPTIMER_TAMR_TAMIE_M 0x00000020 +#define GPTIMER_TAMR_TAMIE_S 5 +#define GPTIMER_TAMR_TACDIR 0x00000010 // GPTM Timer A count direction 0: + // The timer counts down. 1: The + // timer counts up. When counting + // up, the timer starts from a + // value of 0x0. +#define GPTIMER_TAMR_TACDIR_M 0x00000010 +#define GPTIMER_TAMR_TACDIR_S 4 +#define GPTIMER_TAMR_TAAMS 0x00000008 // GPTM Timer A alternate mode 0: + // Capture mode is enabled. 1: PWM + // mode is enabled. Note: To enable + // PWM mode, the TACM bit must be + // cleared and the TAMR field must + // be configured to 0x2. +#define GPTIMER_TAMR_TAAMS_M 0x00000008 +#define GPTIMER_TAMR_TAAMS_S 3 +#define GPTIMER_TAMR_TACMR 0x00000004 // GPTM Timer A capture mode 0: + // Edge-count mode 1: Edge-time + // mode +#define GPTIMER_TAMR_TACMR_M 0x00000004 +#define GPTIMER_TAMR_TACMR_S 2 +#define GPTIMER_TAMR_TAMR_M 0x00000003 // GPTM Timer A mode 0x0: Reserved + // 0x1: One-shot mode 0x2: Periodic + // mode 0x3: Capture mode The timer + // mode is based on the timer + // configuration defined by bits + // [2:0] in the GPTMCFG register. +#define GPTIMER_TAMR_TAMR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TBMR register. +// +//***************************************************************************** +#define GPTIMER_TBMR_TBPLO 0x00000800 // Legacy PWM operation 0: Legacy + // operation 1: CCP is set to 1 on + // time-out. +#define GPTIMER_TBMR_TBPLO_M 0x00000800 +#define GPTIMER_TBMR_TBPLO_S 11 +#define GPTIMER_TBMR_TBMRSU 0x00000400 // Timer B match register update + // mode 0: Update the GPTMBMATCHR + // and the GPTMBPR, if used on the + // next cycle. 1: Update the + // GPTMBMATCHR and the GPTMBPR, if + // used on the next time-out. If + // the timer is disabled (TAEN is + // clear) when this bit is set, + // GPTMTBMATCHR and GPTMTBPR are + // updated when the timer is + // enabled. If the timer is stalled + // (TBSTALL is set), GPTMTBMATCHR + // and GPTMTBPR are updated + // according to the configuration + // of this bit. +#define GPTIMER_TBMR_TBMRSU_M 0x00000400 +#define GPTIMER_TBMR_TBMRSU_S 10 +#define GPTIMER_TBMR_TBPWMIE 0x00000200 // GPTM Timer B PWM interrupt + // enable This bit enables + // interrupts in PWM mode on + // rising, falling, or both edges + // of the CCP output. 0: Interrupt + // is disabled. 1: Interrupt is + // enabled. This bit is valid only + // in PWM mode. +#define GPTIMER_TBMR_TBPWMIE_M 0x00000200 +#define GPTIMER_TBMR_TBPWMIE_S 9 +#define GPTIMER_TBMR_TBILD 0x00000100 // GPTM Timer B PWM interval load + // write 0: Update the GPTMTBR + // register with the value in the + // GPTMTBILR register on the next + // cycle. If the prescaler is used, + // update the GPTMTBPS register + // with the value in the GPTMTBPR + // register on the next cycle. 1: + // Update the GPTMTBR register with + // the value in the GPTMTBILR + // register on the next cycle. If + // the prescaler is used, update + // the GPTMTBPS register with the + // value in the GPTMTBPR register + // on the next time-out. +#define GPTIMER_TBMR_TBILD_M 0x00000100 +#define GPTIMER_TBMR_TBILD_S 8 +#define GPTIMER_TBMR_TBSNAPS 0x00000080 // GPTM Timer B snap-shot mode 0: + // Snap-shot mode is disabled. 1: + // If Timer B is configured in the + // periodic mode, the actual + // free-running value of Timer A is + // loaded into the GPTM Timer B + // (GPTMTBR) register at the + // time-out event. +#define GPTIMER_TBMR_TBSNAPS_M 0x00000080 +#define GPTIMER_TBMR_TBSNAPS_S 7 +#define GPTIMER_TBMR_TBWOT 0x00000040 // GPTM Timer B wait-on-trigger 0: + // Timer B begins counting as soon + // as it is enabled. 1: If Timer B + // is enabled (TBEN is set in the + // GPTMCTL register), Timer B does + // not begin counting until it + // receives a trigger from the + // timer in the previous position + // in the daisy-chain. +#define GPTIMER_TBMR_TBWOT_M 0x00000040 +#define GPTIMER_TBMR_TBWOT_S 6 +#define GPTIMER_TBMR_TBMIE 0x00000020 // GPTM Timer B match interrupt + // enable 0: The match interrupt is + // disabled. 1: An interrupt is + // generated when the match value + // in the GPTMTBMATCHR register is + // reached in the one-shot and + // periodic modes. +#define GPTIMER_TBMR_TBMIE_M 0x00000020 +#define GPTIMER_TBMR_TBMIE_S 5 +#define GPTIMER_TBMR_TBCDIR 0x00000010 // GPTM Timer B count direction 0: + // The timer counts down. 1: The + // timer counts up. When counting + // up, the timer starts from a + // value of 0x0. +#define GPTIMER_TBMR_TBCDIR_M 0x00000010 +#define GPTIMER_TBMR_TBCDIR_S 4 +#define GPTIMER_TBMR_TBAMS 0x00000008 // GPTM Timer B alternate mode 0: + // Capture mode is enabled. 1: PWM + // mode is enabled. Note: To enable + // PWM mode, the TBCM bit must be + // cleared and the TBMR field must + // be configured to 0x2. +#define GPTIMER_TBMR_TBAMS_M 0x00000008 +#define GPTIMER_TBMR_TBAMS_S 3 +#define GPTIMER_TBMR_TBCMR 0x00000004 // GPTM Timer B capture mode 0: + // Edge-count mode 1: Edge-time + // mode +#define GPTIMER_TBMR_TBCMR_M 0x00000004 +#define GPTIMER_TBMR_TBCMR_S 2 +#define GPTIMER_TBMR_TBMR_M 0x00000003 // GPTM Timer B mode 0x0: Reserved + // 0x1: One-shot timer mode 0x2: + // Periodic timer mode 0x3: Capture + // mode The timer mode is based on + // the timer configuration defined + // by bits [2:0] in the GPTMCFG + // register. +#define GPTIMER_TBMR_TBMR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_CTL register. +// +//***************************************************************************** +#define GPTIMER_CTL_TBPWML 0x00004000 // GPTM Timer B PWM output level + // 0: Output is unaffected. 1: + // Output is inverted. +#define GPTIMER_CTL_TBPWML_M 0x00004000 +#define GPTIMER_CTL_TBPWML_S 14 +#define GPTIMER_CTL_TBOTE 0x00002000 // GPTM Timer B output trigger + // enable 0: The ADC trigger of + // output Timer B is disabled. 1: + // The ADC trigger of output Timer + // B is enabled. +#define GPTIMER_CTL_TBOTE_M 0x00002000 +#define GPTIMER_CTL_TBOTE_S 13 +#define GPTIMER_CTL_TBEVENT_M 0x00000C00 // GPTM Timer B event mode 0x0: + // Positive edge 0x1: Negative edge + // 0x2: Reserved 0x3: Both edges +#define GPTIMER_CTL_TBEVENT_S 10 +#define GPTIMER_CTL_TBSTALL 0x00000200 // GPTM Timer B stall enable 0: + // Timer B continues counting while + // the processor is halted by the + // debugger. 1: Timer B freezes + // counting while the processor is + // halted by the debugger. +#define GPTIMER_CTL_TBSTALL_M 0x00000200 +#define GPTIMER_CTL_TBSTALL_S 9 +#define GPTIMER_CTL_TBEN 0x00000100 // GPTM Timer B enable 0: Timer B + // is disabled. 1: Timer B is + // enabled and begins counting or + // the capture logic is enabled + // based on the GPTMCFG register. +#define GPTIMER_CTL_TBEN_M 0x00000100 +#define GPTIMER_CTL_TBEN_S 8 +#define GPTIMER_CTL_TAPWML 0x00000040 // GPTM Timer A PWM output level + // 0: Output is unaffected. 1: + // Output is inverted. +#define GPTIMER_CTL_TAPWML_M 0x00000040 +#define GPTIMER_CTL_TAPWML_S 6 +#define GPTIMER_CTL_TAOTE 0x00000020 // GPTM Timer A output trigger + // enable 0: The ADC trigger of + // output Timer A is disabled. 1: + // The ADC trigger of output Timer + // A is enabled. +#define GPTIMER_CTL_TAOTE_M 0x00000020 +#define GPTIMER_CTL_TAOTE_S 5 +#define GPTIMER_CTL_TAEVENT_M 0x0000000C // GPTM Timer A event mode 0x0: + // Positive edge 0x1: Negative edge + // 0x2: Reserved 0x3: Both edges +#define GPTIMER_CTL_TAEVENT_S 2 +#define GPTIMER_CTL_TASTALL 0x00000002 // GPTM Timer A stall enable 0: + // Timer A continues counting while + // the processor is halted by the + // debugger. 1: Timer A freezes + // counting while the processor is + // halted by the debugger. +#define GPTIMER_CTL_TASTALL_M 0x00000002 +#define GPTIMER_CTL_TASTALL_S 1 +#define GPTIMER_CTL_TAEN 0x00000001 // GPTM Timer A enable 0: Timer A + // is disabled. 1: Timer A is + // enabled and begins counting or + // the capture logic is enabled + // based on the GPTMCFG register. +#define GPTIMER_CTL_TAEN_M 0x00000001 +#define GPTIMER_CTL_TAEN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_SYNC register. +// +//***************************************************************************** +#define GPTIMER_SYNC_SYNC3_M 0x000000C0 // Synchronize GPTM3 0x0: GPTM3 is + // not affected. 0x1: A time-out + // event for Timer A of GPTM3 is + // triggered. 0x2: A time-out event + // for Timer B of GPTM3 is + // triggered. 0x3: A time-out event + // for Timer A and Timer B of GPTM3 + // is triggered. +#define GPTIMER_SYNC_SYNC3_S 6 +#define GPTIMER_SYNC_SYNC2_M 0x00000030 // Synchronize GPTM2 0x0: GPTM2 is + // not affected. 0x1: A time-out + // event for Timer A of GPTM2 is + // triggered. 0x2: A time-out event + // for Timer B of GPTM2 is + // triggered. 0x3: A time-out event + // for Timer A and Timer B of GPTM2 + // is triggered. +#define GPTIMER_SYNC_SYNC2_S 4 +#define GPTIMER_SYNC_SYNC1_M 0x0000000C // Synchronize GPTM1 0x0: GPTM1 is + // not affected. 0x1: A time-out + // event for Timer A of GPTM1 is + // triggered. 0x2: A time-out event + // for Timer B of GPTM1 is + // triggered. 0x3: A time-out event + // for Timer A and Timer B of GPTM1 + // is triggered. +#define GPTIMER_SYNC_SYNC1_S 2 +#define GPTIMER_SYNC_SYNC0_M 0x00000003 // Synchronize GPTM0 0x0: GPTM0 is + // not affected. 0x1: A time-out + // event for Timer A of GPTM0 is + // triggered. 0x2: A time-out event + // for Timer B of GPTM0 is + // triggered. 0x3: A time-out event + // for Timer A and Timer B of GPTM0 + // is triggered. +#define GPTIMER_SYNC_SYNC0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_IMR register. +// +//***************************************************************************** +#define GPTIMER_IMR_TBMIM 0x00000800 // GPTM Timer B match interrupt + // mask 0: Interrupt is disabled. + // 1: Interrupt is enabled. +#define GPTIMER_IMR_TBMIM_M 0x00000800 +#define GPTIMER_IMR_TBMIM_S 11 +#define GPTIMER_IMR_CBEIM 0x00000400 // GPTM Timer B capture event + // interrupt mask 0: Interrupt is + // disabled. 1: Interrupt is + // enabled. +#define GPTIMER_IMR_CBEIM_M 0x00000400 +#define GPTIMER_IMR_CBEIM_S 10 +#define GPTIMER_IMR_CBMIM 0x00000200 // GPTM Timer B capture match + // interrupt mask 0: Interrupt is + // disabled. 1: Interrupt is + // enabled. +#define GPTIMER_IMR_CBMIM_M 0x00000200 +#define GPTIMER_IMR_CBMIM_S 9 +#define GPTIMER_IMR_TBTOIM 0x00000100 // GPTM Timer B time-out interrupt + // mask 0: Interrupt is disabled. + // 1: Interrupt is enabled. +#define GPTIMER_IMR_TBTOIM_M 0x00000100 +#define GPTIMER_IMR_TBTOIM_S 8 +#define GPTIMER_IMR_TAMIM 0x00000010 // GPTM Timer A match interrupt + // mask 0: Interrupt is disabled. + // 1: Interrupt is enabled. +#define GPTIMER_IMR_TAMIM_M 0x00000010 +#define GPTIMER_IMR_TAMIM_S 4 +#define GPTIMER_IMR_CAEIM 0x00000004 // GPTM Timer A capture event + // interrupt mask 0: Interrupt is + // disabled. 1: Interrupt is + // enabled. +#define GPTIMER_IMR_CAEIM_M 0x00000004 +#define GPTIMER_IMR_CAEIM_S 2 +#define GPTIMER_IMR_CAMIM 0x00000002 // GPTM Timer A capture match + // interrupt mask 0: Interrupt is + // disabled. 1: Interrupt is + // enabled. +#define GPTIMER_IMR_CAMIM_M 0x00000002 +#define GPTIMER_IMR_CAMIM_S 1 +#define GPTIMER_IMR_TATOIM 0x00000001 // GPTM Timer A time-out interrupt + // mask 0: Interrupt is disabled. + // 1: Interrupt is enabled. +#define GPTIMER_IMR_TATOIM_M 0x00000001 +#define GPTIMER_IMR_TATOIM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_RIS register. +// +//***************************************************************************** +#define GPTIMER_RIS_TBMRIS 0x00000800 // GPTM Timer B match raw + // interrupt +#define GPTIMER_RIS_TBMRIS_M 0x00000800 +#define GPTIMER_RIS_TBMRIS_S 11 +#define GPTIMER_RIS_CBERIS 0x00000400 // GPTM Timer B capture event raw + // interrupt +#define GPTIMER_RIS_CBERIS_M 0x00000400 +#define GPTIMER_RIS_CBERIS_S 10 +#define GPTIMER_RIS_CBMRIS 0x00000200 // GPTM Timer B capture match raw + // interrupt +#define GPTIMER_RIS_CBMRIS_M 0x00000200 +#define GPTIMER_RIS_CBMRIS_S 9 +#define GPTIMER_RIS_TBTORIS 0x00000100 // GPTM Timer B time-out raw + // interrupt +#define GPTIMER_RIS_TBTORIS_M 0x00000100 +#define GPTIMER_RIS_TBTORIS_S 8 +#define GPTIMER_RIS_TAMRIS 0x00000010 // GPTM Timer A match raw + // interrupt +#define GPTIMER_RIS_TAMRIS_M 0x00000010 +#define GPTIMER_RIS_TAMRIS_S 4 +#define GPTIMER_RIS_CAERIS 0x00000004 // GPTM Timer A capture event raw + // interrupt +#define GPTIMER_RIS_CAERIS_M 0x00000004 +#define GPTIMER_RIS_CAERIS_S 2 +#define GPTIMER_RIS_CAMRIS 0x00000002 // GPTM Timer A capture match raw + // interrupt +#define GPTIMER_RIS_CAMRIS_M 0x00000002 +#define GPTIMER_RIS_CAMRIS_S 1 +#define GPTIMER_RIS_TATORIS 0x00000001 // GPTM Timer A time-out raw + // interrupt +#define GPTIMER_RIS_TATORIS_M 0x00000001 +#define GPTIMER_RIS_TATORIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_MIS register. +// +//***************************************************************************** +#define GPTIMER_MIS_TBMMIS 0x00000800 // GPTM Timer B match masked + // interrupt +#define GPTIMER_MIS_TBMMIS_M 0x00000800 +#define GPTIMER_MIS_TBMMIS_S 11 +#define GPTIMER_MIS_CBEMIS 0x00000400 // GPTM Timer B capture event + // masked interrupt +#define GPTIMER_MIS_CBEMIS_M 0x00000400 +#define GPTIMER_MIS_CBEMIS_S 10 +#define GPTIMER_MIS_CBMMIS 0x00000200 // GPTM Timer B capture match + // masked interrupt +#define GPTIMER_MIS_CBMMIS_M 0x00000200 +#define GPTIMER_MIS_CBMMIS_S 9 +#define GPTIMER_MIS_TBTOMIS 0x00000100 // GPTM Timer B time-out masked + // interrupt +#define GPTIMER_MIS_TBTOMIS_M 0x00000100 +#define GPTIMER_MIS_TBTOMIS_S 8 +#define GPTIMER_MIS_TAMRIS 0x00000010 // GPTM Timer A match raw + // interrupt +#define GPTIMER_MIS_TAMRIS_M 0x00000010 +#define GPTIMER_MIS_TAMRIS_S 4 +#define GPTIMER_MIS_CAEMIS 0x00000004 // GPTM Timer A capture event raw + // interrupt +#define GPTIMER_MIS_CAEMIS_M 0x00000004 +#define GPTIMER_MIS_CAEMIS_S 2 +#define GPTIMER_MIS_CAMMIS 0x00000002 // GPTM Timer A capture match raw + // interrupt +#define GPTIMER_MIS_CAMMIS_M 0x00000002 +#define GPTIMER_MIS_CAMMIS_S 1 +#define GPTIMER_MIS_TATOMIS 0x00000001 // GPTM Timer A time-out raw + // interrupt +#define GPTIMER_MIS_TATOMIS_M 0x00000001 +#define GPTIMER_MIS_TATOMIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_ICR register. +// +//***************************************************************************** +#define GPTIMER_ICR_WUECINT 0x00010000 // GPTM write update error + // interrupt clear +#define GPTIMER_ICR_WUECINT_M 0x00010000 +#define GPTIMER_ICR_WUECINT_S 16 +#define GPTIMER_ICR_TBMCINT 0x00000800 // GPTM Timer B match interrupt + // clear +#define GPTIMER_ICR_TBMCINT_M 0x00000800 +#define GPTIMER_ICR_TBMCINT_S 11 +#define GPTIMER_ICR_CBECINT 0x00000400 // GPTM Timer B capture event + // Interrupt clear +#define GPTIMER_ICR_CBECINT_M 0x00000400 +#define GPTIMER_ICR_CBECINT_S 10 +#define GPTIMER_ICR_CBMCINT 0x00000200 // GPTM Timer B capture match + // interrupt clear +#define GPTIMER_ICR_CBMCINT_M 0x00000200 +#define GPTIMER_ICR_CBMCINT_S 9 +#define GPTIMER_ICR_TBTOCINT 0x00000100 // GPTM Timer B time-out interrupt + // clear +#define GPTIMER_ICR_TBTOCINT_M 0x00000100 +#define GPTIMER_ICR_TBTOCINT_S 8 +#define GPTIMER_ICR_TAMCINT 0x00000010 // GPTM Timer A match interrupt + // clear +#define GPTIMER_ICR_TAMCINT_M 0x00000010 +#define GPTIMER_ICR_TAMCINT_S 4 +#define GPTIMER_ICR_CAECINT 0x00000004 // GPTM Timer A capture event + // Interrupt clear +#define GPTIMER_ICR_CAECINT_M 0x00000004 +#define GPTIMER_ICR_CAECINT_S 2 +#define GPTIMER_ICR_CAMCINT 0x00000002 // GPTM Timer A capture match + // interrupt clear +#define GPTIMER_ICR_CAMCINT_M 0x00000002 +#define GPTIMER_ICR_CAMCINT_S 1 +#define GPTIMER_ICR_TATOCINT 0x00000001 // GPTM Timer A time-out interrupt + // clear +#define GPTIMER_ICR_TATOCINT_M 0x00000001 +#define GPTIMER_ICR_TATOCINT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPTIMER_O_TAILR register. +// +//***************************************************************************** +#define GPTIMER_TAILR_TAILR_M 0xFFFFFFFF // GPTM A interval load register +#define GPTIMER_TAILR_TAILR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPTIMER_O_TBILR register. +// +//***************************************************************************** +#define GPTIMER_TBILR_TBILR_M 0x0000FFFF // GPTM B interval load register +#define GPTIMER_TBILR_TBILR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPTIMER_O_TAMATCHR register. +// +//***************************************************************************** +#define GPTIMER_TAMATCHR_TAMR_M 0xFFFFFFFF // GPTM Timer A match register +#define GPTIMER_TAMATCHR_TAMR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPTIMER_O_TBMATCHR register. +// +//***************************************************************************** +#define GPTIMER_TBMATCHR_TBMR_M 0x0000FFFF // GPTM Timer B match register +#define GPTIMER_TBMATCHR_TBMR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TAPR register. +// +//***************************************************************************** +#define GPTIMER_TAPR_TAPSR_M 0x000000FF // GPTM Timer A prescale +#define GPTIMER_TAPR_TAPSR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TBPR register. +// +//***************************************************************************** +#define GPTIMER_TBPR_TBPSR_M 0x000000FF // GPTM Timer B prescale +#define GPTIMER_TBPR_TBPSR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPTIMER_O_TAPMR register. +// +//***************************************************************************** +#define GPTIMER_TAPMR_TAPSR_M 0x000000FF // GPTM Timer A prescale match +#define GPTIMER_TAPMR_TAPSR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// GPTIMER_O_TBPMR register. +// +//***************************************************************************** +#define GPTIMER_TBPMR_TBPSR_M 0x000000FF // GPTM Timer B prescale match +#define GPTIMER_TBPMR_TBPSR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TAR register. +// +//***************************************************************************** +#define GPTIMER_TAR_TAR_M 0xFFFFFFFF // GPTM Timer A register +#define GPTIMER_TAR_TAR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TBR register. +// +//***************************************************************************** +#define GPTIMER_TBR_TBR_M 0x0000FFFF // GPTM Timer B register +#define GPTIMER_TBR_TBR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TAV register. +// +//***************************************************************************** +#define GPTIMER_TAV_TAV_M 0xFFFFFFFF // GPTM Timer A register +#define GPTIMER_TAV_TAV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TBV register. +// +//***************************************************************************** +#define GPTIMER_TBV_PRE_M 0x00FF0000 // GPTM Timer B prescale register + // (16-bit mode) +#define GPTIMER_TBV_PRE_S 16 +#define GPTIMER_TBV_TBV_M 0x0000FFFF // GPTM Timer B register +#define GPTIMER_TBV_TBV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TAPS register. +// +//***************************************************************************** +#define GPTIMER_TAPS_PSS_M 0x0000FFFF // GPTM Timer A prescaler +#define GPTIMER_TAPS_PSS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TBPS register. +// +//***************************************************************************** +#define GPTIMER_TBPS_PSS_M 0x0000FFFF // GPTM Timer B prescaler +#define GPTIMER_TBPS_PSS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TAPV register. +// +//***************************************************************************** +#define GPTIMER_TAPV_PSV_M 0x0000FFFF // GPTM Timer A prescaler value +#define GPTIMER_TAPV_PSV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_TBPV register. +// +//***************************************************************************** +#define GPTIMER_TBPV_PSV_M 0x0000FFFF // GPTM Timer B prescaler value +#define GPTIMER_TBPV_PSV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the GPTIMER_O_PP register. +// +//***************************************************************************** +#define GPTIMER_PP_ALTCLK 0x00000040 // Alternate clock source 0: Timer + // is not capable of using an + // alternate clock. 1: Timer is + // capable of using an alternate + // clock. +#define GPTIMER_PP_ALTCLK_M 0x00000040 +#define GPTIMER_PP_ALTCLK_S 6 +#define GPTIMER_PP_SYNCNT 0x00000020 // Synchronized start 0: Timer is + // not capable of synchronizing the + // count value with other timers. + // 1: Timer is capable of + // synchronizing the count value + // with other timers. +#define GPTIMER_PP_SYNCNT_M 0x00000020 +#define GPTIMER_PP_SYNCNT_S 5 +#define GPTIMER_PP_CHAIN 0x00000010 // Chain with other timers 0: + // Timer is not capable of chaining + // with previously numbered Timers. + // 1: Timer is capable of chaining + // with previously numbered timers. +#define GPTIMER_PP_CHAIN_M 0x00000010 +#define GPTIMER_PP_CHAIN_S 4 +#define GPTIMER_PP_SIZE_M 0x0000000F // Timer size 0: Timer A and Timer + // B are 16 bits wide with 8-bit + // prescale. 1: Timer A and Timer B + // are 32 bits wide with 16-bit + // prescale. +#define GPTIMER_PP_SIZE_S 0 + + +#endif // __HW_GPTIMER_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_i2cm.h b/bsp/boards/mimsy2-cc2538/headers/hw_i2cm.h new file mode 100644 index 0000000000..2e6ac74a52 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_i2cm.h @@ -0,0 +1,357 @@ +/****************************************************************************** +* Filename: hw_i2cm.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_I2CM_H__ +#define __HW_I2CM_H__ + +//***************************************************************************** +// +// The following are defines for the I2CM register offsets. +// +//***************************************************************************** +#define I2CM_SA 0x40020000 // I2C master slave address This + // register consists of eight bits, + // seven address bits (A6-A0), and + // a receive and send bit, which + // determines if the next operation + // is a receive (high) or transmit + // (low). +#define I2CM_CTRL 0x40020004 // I2C master control and status + // This register accesses status + // bits when read and control bits + // when written. When read, the + // status register indicates the + // state of the I2C bus controller. + // When written, the control + // register configures the I2C + // controller operation. The START + // bit generates the START or + // REPEATED START condition. The + // STOP bit determines if the cycle + // stops at the end of the data + // cycle or continues on to a + // repeated START condition. To + // generate a single transmit + // cycle, the I2C master slave + // address (I2CMSA) register is + // written with the desired + // address, the R/S bit is cleared, + // and this register is written + // with ACK = X (0 or 1), STOP = 1, + // START = 1, and RUN = 1 to + // perform the operation and stop. + // When the operation is completed + // (or aborted due an error), an + // interrupt becomes active and the + // data may be read from the I2CMDR + // register. When the I2C module + // operates in master receiver + // mode, the ACK bit is normally + // set, causing the I2C bus + // controller to automatically + // transmit an acknowledge after + // each byte. This bit must be + // cleared when the I2C bus + // controller requires no further + // data to be transmitted from the + // slave transmitter. +#define I2CM_STAT 0x40020004 // I2C master control and status + // This register accesses status + // bits when read and control bits + // when written. When read, the + // status register indicates the + // state of the I2C bus controller. + // When written, the control + // register configures the I2C + // controller operation. The START + // bit generates the START or + // REPEATED START condition. The + // STOP bit determines if the cycle + // stops at the end of the data + // cycle or continues on to a + // repeated START condition. To + // generate a single transmit + // cycle, the I2C master slave + // address (I2CMSA) register is + // written with the desired + // address, the R/S bit is cleared, + // and this register is written + // with ACK = X (0 or 1), STOP = 1, + // START = 1, and RUN = 1 to + // perform the operation and stop. + // When the operation is completed + // (or aborted due an error), an + // interrupt becomes active and the + // data may be read from the I2CMDR + // register. When the I2C module + // operates in master receiver + // mode, the ACK bit is normally + // set, causing the I2C bus + // controller to automatically + // transmit an acknowledge after + // each byte. This bit must be + // cleared when the I2C bus + // controller requires no further + // data to be transmitted from the + // slave transmitter. +#define I2CM_DR 0x40020008 // I2C master data This register + // contains the data to be + // transmitted when in the master + // transmit state and the data + // received when in the master + // receive state. +#define I2CM_TPR 0x4002000C // I2C master timer period This + // register specifies the period of + // the SCL clock. +#define I2CM_IMR 0x40020010 // I2C master interrupt mask This + // register controls whether a raw + // interrupt is promoted to a + // controller interrupt. +#define I2CM_RIS 0x40020014 // I2C master raw interrupt status + // This register specifies whether + // an interrupt is pending. +#define I2CM_MIS 0x40020018 // I2C master masked interrupt + // status This register specifies + // whether an interrupt was + // signaled. +#define I2CM_ICR 0x4002001C // I2C master interrupt clear This + // register clears the raw and + // masked interrupts. +#define I2CM_CR 0x40020020 // I2C master configuration This + // register configures the mode + // (master or slave) and sets the + // interface for test mode + // loopback. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_SA register. +// +//***************************************************************************** +#define I2CM_SA_SA_M 0x000000FE // I2C slave address +#define I2CM_SA_SA_S 1 +#define I2CM_SA_RS 0x00000001 // Receive and send The R/S bit + // specifies if the next operation + // is a receive (high) or transmit + // (low). 0: Transmit 1: Receive +#define I2CM_SA_RS_M 0x00000001 +#define I2CM_SA_RS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_CTRL register. +// +//***************************************************************************** +#define I2CM_CTRL_ACK 0x00000008 // Data acknowledge enable 0: The + // received data byte is not + // acknowledged automatically by + // the master. 1: The received data + // byte is acknowledged + // automatically by the master. +#define I2CM_CTRL_ACK_M 0x00000008 +#define I2CM_CTRL_ACK_S 3 +#define I2CM_CTRL_STOP 0x00000004 // Generate STOP 0: The controller + // does not generate the STOP + // condition. 1: The controller + // generates the STOP condition. +#define I2CM_CTRL_STOP_M 0x00000004 +#define I2CM_CTRL_STOP_S 2 +#define I2CM_CTRL_START 0x00000002 // Generate START 0: The + // controller does not generate the + // START condition. 1: The + // controller generates the START + // condition. +#define I2CM_CTRL_START_M 0x00000002 +#define I2CM_CTRL_START_S 1 +#define I2CM_CTRL_RUN 0x00000001 // I2C master enable 0: The master + // is disabled. 1: The master is + // enabled to transmit or receive + // data. When the BUSY bit is set, + // the other status bits are not + // valid. +#define I2CM_CTRL_RUN_M 0x00000001 +#define I2CM_CTRL_RUN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_STAT register. +// +//***************************************************************************** +#define I2CM_STAT_BUSBSY 0x00000040 // Bus busy 0: The I2C bus is + // idle. 1: The I2C bus is busy. + // The bit changes based on the + // START and STOP conditions. +#define I2CM_STAT_BUSBSY_M 0x00000040 +#define I2CM_STAT_BUSBSY_S 6 +#define I2CM_STAT_IDLE 0x00000020 // I2C idle 0: The I2C controller + // is not idle. 1: The I2C + // controller is idle. +#define I2CM_STAT_IDLE_M 0x00000020 +#define I2CM_STAT_IDLE_S 5 +#define I2CM_STAT_ARBLST 0x00000010 // Arbitration lost 0: The I2C + // controller won arbitration. 1: + // The I2C controller lost + // arbitration. +#define I2CM_STAT_ARBLST_M 0x00000010 +#define I2CM_STAT_ARBLST_S 4 +#define I2CM_STAT_DATACK 0x00000008 // Acknowledge data 0: The + // transmited data was + // acknowledged. 1: The transmited + // data was not acknowledged. +#define I2CM_STAT_DATACK_M 0x00000008 +#define I2CM_STAT_DATACK_S 3 +#define I2CM_STAT_ADRACK 0x00000004 // Acknowledge address 0: The + // transmited address was + // acknowledged. 1: The transmited + // address was not acknowledged. +#define I2CM_STAT_ADRACK_M 0x00000004 +#define I2CM_STAT_ADRACK_S 2 +#define I2CM_STAT_ERROR 0x00000002 // Error 0: No error was detected + // on the last operation. 1: An + // error occurred on the last + // operation. +#define I2CM_STAT_ERROR_M 0x00000002 +#define I2CM_STAT_ERROR_S 1 +#define I2CM_STAT_BUSY 0x00000001 // I2C busy 0: The controller is + // idle. 1: The controller is busy. + // When the BUSY bit is set, the + // other status bits are not valid. +#define I2CM_STAT_BUSY_M 0x00000001 +#define I2CM_STAT_BUSY_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_DR register. +// +//***************************************************************************** +#define I2CM_DR_DATA_M 0x000000FF // Data transferred Data + // transferred during transaction +#define I2CM_DR_DATA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_TPR register. +// +//***************************************************************************** +#define I2CM_TPR_TPR_M 0x0000007F // SCL clock period This field + // specifies the period of the SCL + // clock. SCL_PRD = 2 * + // (1+TPR)*(SCL_LP + + // SCL_HP)*CLK_PRD where: SCL_PRD + // is the SCL line period (I2C + // clock). TPR is the timer period + // register value (range of 1 to + // 127) SCL_LP is the SCL low + // period (fixed at 6). SCL_HP is + // the SCL high period (fixed at + // 4). CLK_PRD is the system clock + // period in ns. +#define I2CM_TPR_TPR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_IMR register. +// +//***************************************************************************** +#define I2CM_IMR_IM 0x00000001 // Interrupt mask 1: The master + // interrupt is sent to the + // interrupt controller when the + // RIS bit in the I2CMRIS register + // is set. 0: The RIS interrupt is + // suppressed and not sent to the + // interrupt controller. +#define I2CM_IMR_IM_M 0x00000001 +#define I2CM_IMR_IM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_RIS register. +// +//***************************************************************************** +#define I2CM_RIS_RIS 0x00000001 // Raw interrupt status 1: A + // master interrupt is pending. 0: + // No interrupt This bit is cleared + // by writing 1 to the IC bit in + // the I2CMICR register. +#define I2CM_RIS_RIS_M 0x00000001 +#define I2CM_RIS_RIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_MIS register. +// +//***************************************************************************** +#define I2CM_MIS_MIS 0x00000001 // Masked interrupt status 1: An + // unmasked master interrupt is + // pending. 0: An interrupt has not + // occurred or is masked. This bit + // is cleared by writing 1 to the + // IC bit in the I2CMICR register. +#define I2CM_MIS_MIS_M 0x00000001 +#define I2CM_MIS_MIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_ICR register. +// +//***************************************************************************** +#define I2CM_ICR_IC 0x00000001 // Interrupt clear Writing 1 to + // this bit clears the RIS bit in + // the I2CMRIS register and the MIS + // bit in the I2CMMIS register. + // Reading this register returns no + // meaningful data. +#define I2CM_ICR_IC_M 0x00000001 +#define I2CM_ICR_IC_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CM_CR register. +// +//***************************************************************************** +#define I2CM_CR_SFE 0x00000020 // I2C slave function enable 1: + // Slave mode is enabled. 0: Slave + // mode is disabled. +#define I2CM_CR_SFE_M 0x00000020 +#define I2CM_CR_SFE_S 5 +#define I2CM_CR_MFE 0x00000010 // I2C master function enable 1: + // Master mode is enabled. 0: + // Master mode is disabled. +#define I2CM_CR_MFE_M 0x00000010 +#define I2CM_CR_MFE_S 4 +#define I2CM_CR_LPBK 0x00000001 // I2C loopback 1: The controller + // in a test mode loopback + // configuration. 0: Normal + // operation +#define I2CM_CR_LPBK_M 0x00000001 +#define I2CM_CR_LPBK_S 0 + + +#endif // __HW_I2CM_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_i2cs.h b/bsp/boards/mimsy2-cc2538/headers/hw_i2cs.h new file mode 100644 index 0000000000..51ef377e87 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_i2cs.h @@ -0,0 +1,285 @@ +/****************************************************************************** +* Filename: hw_i2cs.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_I2CS_H__ +#define __HW_I2CS_H__ + +//***************************************************************************** +// +// The following are defines for the I2CS register offsets. +// +//***************************************************************************** +#define I2CS_OAR 0x40020800 // I2C slave own address This + // register consists of seven + // address bits that identify the + // CC2538 I2C device on the I2C + // bus. +#define I2CS_STAT 0x40020804 // I2C slave control and status + // This register functions as a + // control register when written, + // and a status register when read. +#define I2CS_CTRL 0x40020804 // I2C slave control and status + // This register functions as a + // control register when written, + // and a status register when read. +#define I2CS_DR 0x40020808 // I2C slave data This register + // contains the data to be + // transmitted when in the slave + // transmit state, and the data + // received when in the slave + // receive state. +#define I2CS_IMR 0x4002080C // I2C slave interrupt mask This + // register controls whether a raw + // interrupt is promoted to a + // controller interrupt. +#define I2CS_RIS 0x40020810 // I2C slave raw interrupt status + // This register specifies whether + // an interrupt is pending. +#define I2CS_MIS 0x40020814 // I2C slave masked interrupt + // status This register specifies + // whether an interrupt was + // signaled. +#define I2CS_ICR 0x40020818 // I2C slave interrupt clear This + // register clears the raw + // interrupt. A read of this + // register returns no meaningful + // data. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CS_OAR register. +// +//***************************************************************************** +#define I2CS_OAR_OAR_M 0x0000007F // I2C slave own address This + // field specifies bits A6 through + // A0 of the slave address. +#define I2CS_OAR_OAR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CS_STAT register. +// +//***************************************************************************** +#define I2CS_STAT_FBR 0x00000004 // First byte received 1: The + // first byte following the slave's + // own address has been received. + // 0: The first byte has not been + // received. This bit is only valid + // when the RREQ bit is set and is + // automatically cleared when data + // has been read from the I2CSDR + // register. Note: This bit is not + // used for slave transmit + // operations. +#define I2CS_STAT_FBR_M 0x00000004 +#define I2CS_STAT_FBR_S 2 +#define I2CS_STAT_TREQ 0x00000002 // Transmit request 1: The I2C + // controller has been addressed as + // a slave transmitter and is using + // clock stretching to delay the + // master until data has been + // written to the I2CSDR register. + // 0: No outstanding transmit + // request. +#define I2CS_STAT_TREQ_M 0x00000002 +#define I2CS_STAT_TREQ_S 1 +#define I2CS_STAT_RREQ 0x00000001 // Receive request 1: The I2C + // controller has outstanding + // receive data from the I2C master + // and is using clock stretching to + // delay the master until data has + // been read from the I2CSDR + // register. 0: No outstanding + // receive data +#define I2CS_STAT_RREQ_M 0x00000001 +#define I2CS_STAT_RREQ_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CS_CTRL register. +// +//***************************************************************************** +#define I2CS_CTRL_DA 0x00000001 // Device active 0: Disables the + // I2C slave operation 1: Enables + // the I2C slave operation +#define I2CS_CTRL_DA_M 0x00000001 +#define I2CS_CTRL_DA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CS_DR register. +// +//***************************************************************************** +#define I2CS_DR_DATA_M 0x000000FF // Data for transfer This field + // contains the data for transfer + // during a slave receive or + // transmit operation. +#define I2CS_DR_DATA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CS_IMR register. +// +//***************************************************************************** +#define I2CS_IMR_STOPIM 0x00000004 // Stop condition interrupt mask + // 1: The STOP condition interrupt + // is sent to the interrupt + // controller when the STOPRIS bit + // in the I2CSRIS register is set. + // 0: The STOPRIS interrupt is + // supressed and not sent to the + // interrupt controller. +#define I2CS_IMR_STOPIM_M 0x00000004 +#define I2CS_IMR_STOPIM_S 2 +#define I2CS_IMR_STARTIM 0x00000002 // Start condition interrupt mask + // 1: The START condition interrupt + // is sent to the interrupt + // controller when the STARTRIS bit + // in the I2CSRIS register is set. + // 0: The STARTRIS interrupt is + // supressed and not sent to the + // interrupt controller. +#define I2CS_IMR_STARTIM_M 0x00000002 +#define I2CS_IMR_STARTIM_S 1 +#define I2CS_IMR_DATAIM 0x00000001 // Data interrupt mask 1: The data + // received or data requested + // interrupt is sent to the + // interrupt controller when the + // DATARIS bit in the I2CSRIS + // register is set. 0: The DATARIS + // interrupt is surpressed and not + // sent to the interrupt + // controller. +#define I2CS_IMR_DATAIM_M 0x00000001 +#define I2CS_IMR_DATAIM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CS_RIS register. +// +//***************************************************************************** +#define I2CS_RIS_STOPRIS 0x00000004 // Stop condition raw interrupt + // status 1: A STOP condition + // interrupt is pending. 0: No + // interrupt This bit is cleared by + // writing 1 to the STOPIC bit in + // the I2CSICR register. +#define I2CS_RIS_STOPRIS_M 0x00000004 +#define I2CS_RIS_STOPRIS_S 2 +#define I2CS_RIS_STARTRIS 0x00000002 // Start condition raw interrupt + // status 1: A START condition + // interrupt is pending. 0: No + // interrupt This bit is cleared by + // writing 1 to the STARTIC bit in + // the I2CSICR register. +#define I2CS_RIS_STARTRIS_M 0x00000002 +#define I2CS_RIS_STARTRIS_S 1 +#define I2CS_RIS_DATARIS 0x00000001 // Data raw interrupt status 1: A + // data received or data requested + // interrupt is pending. 0: No + // interrupt This bit is cleared by + // writing 1 to the DATAIC bit in + // the I2CSICR register. +#define I2CS_RIS_DATARIS_M 0x00000001 +#define I2CS_RIS_DATARIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CS_MIS register. +// +//***************************************************************************** +#define I2CS_MIS_STOPMIS 0x00000004 // Stop condition masked interrupt + // status 1: An unmasked STOP + // condition interrupt is pending. + // 0: An interrupt has not occurred + // or is masked. This bit is + // cleared by writing 1 to the + // STOPIC bit in the I2CSICR + // register. +#define I2CS_MIS_STOPMIS_M 0x00000004 +#define I2CS_MIS_STOPMIS_S 2 +#define I2CS_MIS_STARTMIS 0x00000002 // Start condition masked + // interrupt status 1: An unmasked + // START condition interrupt is + // pending. 0: An interrupt has not + // occurred or is masked. This bit + // is cleared by writing 1 to the + // STARTIC bit in the I2CSICR + // register. +#define I2CS_MIS_STARTMIS_M 0x00000002 +#define I2CS_MIS_STARTMIS_S 1 +#define I2CS_MIS_DATAMIS 0x00000001 // Data masked interrupt status 1: + // An unmasked data received or + // data requested interrupt is + // pending. 0: An interrupt has not + // occurred or is masked. This bit + // is cleared by writing 1 to the + // DATAIC bit in the I2CSICR + // register. +#define I2CS_MIS_DATAMIS_M 0x00000001 +#define I2CS_MIS_DATAMIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the I2CS_ICR register. +// +//***************************************************************************** +#define I2CS_ICR_STOPIC 0x00000004 // Stop condition interrupt clear + // Writing 1 to this bit clears the + // STOPRIS bit in the I2CSRIS + // register and the STOPMIS bit in + // the I2CSMIS register. A read of + // this register returns no + // meaningful data. +#define I2CS_ICR_STOPIC_M 0x00000004 +#define I2CS_ICR_STOPIC_S 2 +#define I2CS_ICR_STARTIC 0x00000002 // Start condition interrupt vlear + // Writing 1 to this bit clears the + // STARTRIS bit in the I2CSRIS + // register and the STARTMIS bit in + // the I2CSMIS register. A read of + // this register returns no + // meaningful data. +#define I2CS_ICR_STARTIC_M 0x00000002 +#define I2CS_ICR_STARTIC_S 1 +#define I2CS_ICR_DATAIC 0x00000001 // Data interrupt clear Writing 1 + // to this bit clears the DATARIS + // bit in the I2CSRIS register and + // the DATAMIS bit in the I2CSMIS + // register. A read of this + // register returns no meaningful + // data. +#define I2CS_ICR_DATAIC_M 0x00000001 +#define I2CS_ICR_DATAIC_S 0 + + +#endif // __HW_I2CS_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_ints.h b/bsp/boards/mimsy2-cc2538/headers/hw_ints.h new file mode 100644 index 0000000000..a31d3799fe --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_ints.h @@ -0,0 +1,153 @@ +/****************************************************************************** +* Filename: hw_ints.h +* Revised: $Date: 2013-04-29 09:49:55 +0200 (Mon, 29 Apr 2013) $ +* Revision: $Revision: 9923 $ +* +* Description: Macros that define the interrupt assignment on Stellaris. +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + + +#ifndef __HW_INTS_H__ +#define __HW_INTS_H__ + +// Note: Use the following define if alternate interrupt map is to be used. +// This map is smaller. The function IntAltMapEnable() must be called +// to enable The alternate map. +// #define CC2538_USE_ALTERNATE_INTERRUPT_MAP 1 + +//***************************************************************************** +// +// The following are defines for the fault assignments. +// +//***************************************************************************** +#define FAULT_NMI 2 // NMI fault +#define FAULT_HARD 3 // Hard fault +#define FAULT_MPU 4 // MPU fault +#define FAULT_BUS 5 // Bus fault +#define FAULT_USAGE 6 // Usage fault +#define FAULT_SVCALL 11 // SVCall +#define FAULT_DEBUG 12 // Debug monitor +#define FAULT_PENDSV 14 // PendSV +#define FAULT_SYSTICK 15 // System Tick + +//***************************************************************************** +// +// The following are defines for the interrupt assignments. +// +//***************************************************************************** +#define INT_GPIOA 16 // GPIO Port A +#define INT_GPIOB 17 // GPIO Port B +#define INT_GPIOC 18 // GPIO Port C +#define INT_GPIOD 19 // GPIO Port D +// 20 not in use +#define INT_UART0 21 // UART0 Rx and Tx +#define INT_UART1 22 // UART1 Rx and Tx +#define INT_SSI0 23 // SSI0 Rx and Tx +#define INT_I2C0 24 // I2C0 Master and Slave +// 25 - 29 not in use +#define INT_ADC0 30 // ADC0 Sequence 0 +// 31 - 33 not in use +#define INT_WATCHDOG 34 // Watchdog timer +#define INT_WATCHDOG0 34 // Watchdog Timer0 +#define INT_TIMER0A 35 // Timer 0 subtimer A +#define INT_TIMER0B 36 // Timer 0 subtimer B +#define INT_TIMER1A 37 // Timer 1 subtimer A +#define INT_TIMER1B 38 // Timer 1 subtimer B +#define INT_TIMER2A 39 // Timer 2 subtimer A +#define INT_TIMER2B 40 // Timer 2 subtimer B +#define INT_COMP0 41 // Analog Comparator 0 + +// 42 - 44 only in use for alternate map +#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP +#define INT_RFCORERTX 42 // RFCORE RX/TX +#define INT_RFCOREERR 43 // RFCORE Error +#define INT_ICEPICK 44 // Icepick +#endif // CC2538_USE_ALTERNATE_INTERRUPT_MAP + +#define INT_FLASH 45 // FLASH Control + +// 46 - 49 only in use for alternate map +#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP +#define INT_AES 46 // AES +#define INT_PKA 47 // PKA +#define INT_SMTIM 48 // SMTimer +#define INT_MACTIMR 49 // MACTimer +#endif // CC2538_USE_ALTERNATE_INTERRUPT_MAP + +#define INT_SSI1 50 // SSI1 Rx and Tx +#define INT_TIMER3A 51 // Timer 3 subtimer A +#define INT_TIMER3B 52 // Timer 3 subtimer B +// 53 - 59 not in use +// 60 only in use for alternate map +#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP +#define INT_USB2538 60 // USB new for 2538 +#endif // CC2538_USE_ALTERNATE_INTERRUPT_MAP + +// 61 not in use +#define INT_UDMA 62 // uDMA controller +#define INT_UDMAERR 63 // uDMA Error + +// 64 - 155 not in use +// 156-162 only in use in basic map +#ifndef CC2538_USE_ALTERNATE_INTERRUPT_MAP +#define INT_USB2538 156 // USB new for 2538 +#define INT_RFCORERTX 157 // RFCORE RX/TX +#define INT_RFCOREERR 158 // RFCORE Error +#define INT_AES 159 // AES +#define INT_PKA 160 // PKA +#define INT_SMTIM 161 // SMTimer +#define INT_MACTIMR 162 // MACTimer +#endif // not CC2538_USE_ALTERNATE_INTERRUPT_MAP + +//***************************************************************************** +// +// The following are defines for the total number of interrupts. +// +//***************************************************************************** + +#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP +#define NUM_INTERRUPTS 64 +#else +#define NUM_INTERRUPTS 163 +#endif // CC2538_USE_ALTERNATE_INTERRUPT_MAP + +//***************************************************************************** +// +// The following are defines for the total number of priority levels. +// +//***************************************************************************** +#define NUM_PRIORITY 8 +#define NUM_PRIORITY_BITS 3 + +#endif // __HW_INTS_H__ diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_ioc.h b/bsp/boards/mimsy2-cc2538/headers/hw_ioc.h new file mode 100644 index 0000000000..0fbb178b21 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_ioc.h @@ -0,0 +1,1117 @@ +/****************************************************************************** +* Filename: hw_ioc.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_IOC_H__ +#define __HW_IOC_H__ + +//***************************************************************************** +// +// The following are defines for the IOC register offsets. +// +//***************************************************************************** +#define IOC_PA0_SEL 0x400D4000 // Peripheral select control for + // PA0 +#define IOC_PA1_SEL 0x400D4004 // Peripheral select control for + // PA1 +#define IOC_PA2_SEL 0x400D4008 // Peripheral select control for + // PA2 +#define IOC_PA3_SEL 0x400D400C // Peripheral select control for + // PA3 +#define IOC_PA4_SEL 0x400D4010 // Peripheral select control for + // PA4 +#define IOC_PA5_SEL 0x400D4014 // Peripheral select control for + // PA5 +#define IOC_PA6_SEL 0x400D4018 // Peripheral select control for + // PA6 +#define IOC_PA7_SEL 0x400D401C // Peripheral select control for + // PA7 +#define IOC_PB0_SEL 0x400D4020 // Peripheral select control for + // PB0 +#define IOC_PB1_SEL 0x400D4024 // Peripheral select control for + // PB1 +#define IOC_PB2_SEL 0x400D4028 // Peripheral select control for + // PB2 +#define IOC_PB3_SEL 0x400D402C // Peripheral select control for + // PB3 +#define IOC_PB4_SEL 0x400D4030 // Peripheral select control for + // PB4 +#define IOC_PB5_SEL 0x400D4034 // Peripheral select control for + // PB5 +#define IOC_PB6_SEL 0x400D4038 // Peripheral select control for + // PB6 +#define IOC_PB7_SEL 0x400D403C // Peripheral select control for + // PB7 +#define IOC_PC0_SEL 0x400D4040 // Peripheral select control for + // PC0 +#define IOC_PC1_SEL 0x400D4044 // Peripheral select control for + // PC1 +#define IOC_PC2_SEL 0x400D4048 // Peripheral select control for + // PC2 +#define IOC_PC3_SEL 0x400D404C // Peripheral select control for + // PC3 +#define IOC_PC4_SEL 0x400D4050 // Peripheral select control for + // PC4 +#define IOC_PC5_SEL 0x400D4054 // Peripheral select control for + // PC5 +#define IOC_PC6_SEL 0x400D4058 // Peripheral select control for + // PC6 +#define IOC_PC7_SEL 0x400D405C // Peripheral select control for + // PC7 +#define IOC_PD0_SEL 0x400D4060 // Peripheral select control for + // PD0 +#define IOC_PD1_SEL 0x400D4064 // Peripheral select control for + // PD1 +#define IOC_PD2_SEL 0x400D4068 // Peripheral select control for + // PD2 +#define IOC_PD3_SEL 0x400D406C // Peripheral select control for + // PD3 +#define IOC_PD4_SEL 0x400D4070 // Peripheral select control for + // PD4 +#define IOC_PD5_SEL 0x400D4074 // Peripheral select control for + // PD5 +#define IOC_PD6_SEL 0x400D4078 // Peripheral select control for + // PD6 +#define IOC_PD7_SEL 0x400D407C // Peripheral select control for + // PD7 +#define IOC_PA0_OVER 0x400D4080 // This is the overide + // configuration register for each + // pad. +#define IOC_PA1_OVER 0x400D4084 // This is the overide + // configuration register for each + // pad. +#define IOC_PA2_OVER 0x400D4088 // This is the overide + // configuration register for each + // pad. +#define IOC_PA3_OVER 0x400D408C // This is the overide + // configuration register for each + // pad. +#define IOC_PA4_OVER 0x400D4090 // This is the overide + // configuration register for each + // pad. +#define IOC_PA5_OVER 0x400D4094 // This is the overide + // configuration register for each + // pad. +#define IOC_PA6_OVER 0x400D4098 // This is the overide + // configuration register for each + // pad. +#define IOC_PA7_OVER 0x400D409C // This is the overide + // configuration register for each + // pad. +#define IOC_PB0_OVER 0x400D40A0 // This is the overide + // configuration register for each + // pad. +#define IOC_PB1_OVER 0x400D40A4 // This is the overide + // configuration register for each + // pad. +#define IOC_PB2_OVER 0x400D40A8 // This is the overide + // configuration register for each + // pad. +#define IOC_PB3_OVER 0x400D40AC // This is the overide + // configuration register for each + // pad. +#define IOC_PB4_OVER 0x400D40B0 // This is the overide + // configuration register for each + // pad. +#define IOC_PB5_OVER 0x400D40B4 // This is the overide + // configuration register for each + // pad. +#define IOC_PB6_OVER 0x400D40B8 // This is the overide + // configuration register for each + // pad. +#define IOC_PB7_OVER 0x400D40BC // This is the overide + // configuration register for each + // pad. +#define IOC_PC0_OVER 0x400D40C0 // This is the overide + // configuration register for each + // pad. PC0 has high drive + // capability. +#define IOC_PC1_OVER 0x400D40C4 // This is the overide + // configuration register for each + // pad. PC1 has high drive + // capability. +#define IOC_PC2_OVER 0x400D40C8 // This is the overide + // configuration register for each + // pad. PC2 has high drive + // capability. +#define IOC_PC3_OVER 0x400D40CC // This is the overide + // configuration register for each + // pad. PC3 has high drive + // capability. +#define IOC_PC4_OVER 0x400D40D0 // This is the overide + // configuration register for each + // pad. +#define IOC_PC5_OVER 0x400D40D4 // This is the overide + // configuration register for each + // pad. +#define IOC_PC6_OVER 0x400D40D8 // This is the overide + // configuration register for each + // pad. +#define IOC_PC7_OVER 0x400D40DC // This is the overide + // configuration register for each + // pad. +#define IOC_PD0_OVER 0x400D40E0 // This is the overide + // configuration register for each + // pad. +#define IOC_PD1_OVER 0x400D40E4 // This is the overide + // configuration register for each + // pad. +#define IOC_PD2_OVER 0x400D40E8 // This is the overide + // configuration register for each + // pad. +#define IOC_PD3_OVER 0x400D40EC // This is the overide + // configuration register for each + // pad. +#define IOC_PD4_OVER 0x400D40F0 // This is the overide + // configuration register for each + // pad. +#define IOC_PD5_OVER 0x400D40F4 // This is the overide + // configuration register for each + // pad. +#define IOC_PD6_OVER 0x400D40F8 // This is the overide + // configuration register for each + // pad. +#define IOC_PD7_OVER 0x400D40FC // This is the overide + // configuration register for each + // pad. +#define IOC_UARTRXD_UART0 0x400D4100 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the UART0 RX. +#define IOC_UARTCTS_UART1 0x400D4104 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the UART1 CTS. +#define IOC_UARTRXD_UART1 0x400D4108 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the UART1 RX. +#define IOC_CLK_SSI_SSI0 0x400D410C // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the SSI0 CLK. +#define IOC_SSIRXD_SSI0 0x400D4110 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the SSI0 RX. +#define IOC_SSIFSSIN_SSI0 0x400D4114 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the SSI0 FSSIN. +#define IOC_CLK_SSIIN_SSI0 0x400D4118 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the SSI0 CLK_SSIN. +#define IOC_CLK_SSI_SSI1 0x400D411C // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the SSI1 CLK. +#define IOC_SSIRXD_SSI1 0x400D4120 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the SSI1 RX. +#define IOC_SSIFSSIN_SSI1 0x400D4124 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the SSI1 FSSIN. +#define IOC_CLK_SSIIN_SSI1 0x400D4128 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the SSI1 CLK_SSIN. +#define IOC_I2CMSSDA 0x400D412C // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the I2C SDA. +#define IOC_I2CMSSCL 0x400D4130 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the I2C SCL. +#define IOC_GPT0OCP1 0x400D4134 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the GPT0OCP1. +#define IOC_GPT0OCP2 0x400D4138 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the GPT0OCP2. +#define IOC_GPT1OCP1 0x400D413C // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the GPT1OCP1. +#define IOC_GPT1OCP2 0x400D4140 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the GPT1OCP2. +#define IOC_GPT2OCP1 0x400D4144 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the GPT2OCP1. +#define IOC_GPT2OCP2 0x400D4148 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the GPT2OCP2. +#define IOC_GPT3OCP1 0x400D414C // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the GPT3OCP1. +#define IOC_GPT3OCP2 0x400D4150 // Selects one of the 32 pins on + // the four 8-pin I/O-ports (port + // A, port B, port C, and port D) + // to be the GPT3OCP2. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA0_SEL register. +// +//***************************************************************************** +#define IOC_PA0_SEL_PA0_sel_M 0x0000001F // Select one peripheral signal + // output for PA0. +#define IOC_PA0_SEL_PA0_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA1_SEL register. +// +//***************************************************************************** +#define IOC_PA1_SEL_PA1_sel_M 0x0000001F // Select one peripheral signal + // output for PA1. +#define IOC_PA1_SEL_PA1_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA2_SEL register. +// +//***************************************************************************** +#define IOC_PA2_SEL_PA2_sel_M 0x0000001F // Select one peripheral signal + // output for PA2. +#define IOC_PA2_SEL_PA2_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA3_SEL register. +// +//***************************************************************************** +#define IOC_PA3_SEL_PA3_sel_M 0x0000001F // Select one peripheral signal + // output for PA3. +#define IOC_PA3_SEL_PA3_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA4_SEL register. +// +//***************************************************************************** +#define IOC_PA4_SEL_PA4_sel_M 0x0000001F // Select one peripheral signal + // output for PA4. +#define IOC_PA4_SEL_PA4_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA5_SEL register. +// +//***************************************************************************** +#define IOC_PA5_SEL_PA5_sel_M 0x0000001F // Select one peripheral signal + // output for PA5. +#define IOC_PA5_SEL_PA5_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA6_SEL register. +// +//***************************************************************************** +#define IOC_PA6_SEL_PA6_sel_M 0x0000001F // Select one peripheral signal + // output for PA6. +#define IOC_PA6_SEL_PA6_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA7_SEL register. +// +//***************************************************************************** +#define IOC_PA7_SEL_PA7_sel_M 0x0000001F // Select one peripheral signal + // output for PA7. +#define IOC_PA7_SEL_PA7_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB0_SEL register. +// +//***************************************************************************** +#define IOC_PB0_SEL_PB0_sel_M 0x0000001F // Select one peripheral signal + // output for PB0. +#define IOC_PB0_SEL_PB0_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB1_SEL register. +// +//***************************************************************************** +#define IOC_PB1_SEL_PB1_sel_M 0x0000001F // Select one peripheral signal + // output for PB1. +#define IOC_PB1_SEL_PB1_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB2_SEL register. +// +//***************************************************************************** +#define IOC_PB2_SEL_PB2_sel_M 0x0000001F // Select one peripheral signal + // output for PB2. +#define IOC_PB2_SEL_PB2_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB3_SEL register. +// +//***************************************************************************** +#define IOC_PB3_SEL_PB3_sel_M 0x0000001F // Select one peripheral signal + // output for PB3. +#define IOC_PB3_SEL_PB3_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB4_SEL register. +// +//***************************************************************************** +#define IOC_PB4_SEL_PB4_sel_M 0x0000001F // Select one peripheral signal + // output for PB4. +#define IOC_PB4_SEL_PB4_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB5_SEL register. +// +//***************************************************************************** +#define IOC_PB5_SEL_PB5_sel_M 0x0000001F // Select one peripheral signal + // output for PB5. +#define IOC_PB5_SEL_PB5_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB6_SEL register. +// +//***************************************************************************** +#define IOC_PB6_SEL_PB6_sel_M 0x0000001F // Select one peripheral signal + // output for PB6. +#define IOC_PB6_SEL_PB6_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB7_SEL register. +// +//***************************************************************************** +#define IOC_PB7_SEL_PB7_sel_M 0x0000001F // Select one peripheral signal + // output for PB7. +#define IOC_PB7_SEL_PB7_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC0_SEL register. +// +//***************************************************************************** +#define IOC_PC0_SEL_PC0_sel_M 0x0000001F // Select one peripheral signal + // output for PC0. +#define IOC_PC0_SEL_PC0_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC1_SEL register. +// +//***************************************************************************** +#define IOC_PC1_SEL_PC1_sel_M 0x0000001F // Select one peripheral signal + // output for PC1. +#define IOC_PC1_SEL_PC1_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC2_SEL register. +// +//***************************************************************************** +#define IOC_PC2_SEL_PC2_sel_M 0x0000001F // Select one peripheral signal + // output for PC2. +#define IOC_PC2_SEL_PC2_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC3_SEL register. +// +//***************************************************************************** +#define IOC_PC3_SEL_PC3_sel_M 0x0000001F // Select one peripheral signal + // output for PC3. +#define IOC_PC3_SEL_PC3_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC4_SEL register. +// +//***************************************************************************** +#define IOC_PC4_SEL_PC4_sel_M 0x0000001F // Select one peripheral signal + // output for PC4. +#define IOC_PC4_SEL_PC4_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC5_SEL register. +// +//***************************************************************************** +#define IOC_PC5_SEL_PC5_sel_M 0x0000001F // Select one peripheral signal + // output for PC5. +#define IOC_PC5_SEL_PC5_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC6_SEL register. +// +//***************************************************************************** +#define IOC_PC6_SEL_PC6_sel_M 0x0000001F // Select one peripheral signal + // output for PC6. +#define IOC_PC6_SEL_PC6_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC7_SEL register. +// +//***************************************************************************** +#define IOC_PC7_SEL_PC7_sel_M 0x0000001F // Select one peripheral signal + // output for PC7. +#define IOC_PC7_SEL_PC7_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD0_SEL register. +// +//***************************************************************************** +#define IOC_PD0_SEL_PD0_sel_M 0x0000001F // Select one peripheral signal + // output for PD0. +#define IOC_PD0_SEL_PD0_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD1_SEL register. +// +//***************************************************************************** +#define IOC_PD1_SEL_PD1_sel_M 0x0000001F // Select one peripheral signal + // output for PD1. +#define IOC_PD1_SEL_PD1_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD2_SEL register. +// +//***************************************************************************** +#define IOC_PD2_SEL_PD2_sel_M 0x0000001F // Select one peripheral signal + // output for PD2. +#define IOC_PD2_SEL_PD2_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD3_SEL register. +// +//***************************************************************************** +#define IOC_PD3_SEL_PD3_sel_M 0x0000001F // Select one peripheral signal + // output for PD3. +#define IOC_PD3_SEL_PD3_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD4_SEL register. +// +//***************************************************************************** +#define IOC_PD4_SEL_PD4_sel_M 0x0000001F // Select one peripheral signal + // output for PD4. +#define IOC_PD4_SEL_PD4_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD5_SEL register. +// +//***************************************************************************** +#define IOC_PD5_SEL_PD5_sel_M 0x0000001F // Select one peripheral signal + // output for PD5. +#define IOC_PD5_SEL_PD5_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD6_SEL register. +// +//***************************************************************************** +#define IOC_PD6_SEL_PD6_sel_M 0x0000001F // Select one peripheral signal + // output for PD6. +#define IOC_PD6_SEL_PD6_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD7_SEL register. +// +//***************************************************************************** +#define IOC_PD7_SEL_PD7_sel_M 0x0000001F // Select one peripheral signal + // output for PD7. +#define IOC_PD7_SEL_PD7_sel_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA0_OVER register. +// +//***************************************************************************** +#define IOC_PA0_OVER_PA0_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PA0_OVER_PA0_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA1_OVER register. +// +//***************************************************************************** +#define IOC_PA1_OVER_PA1_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PA1_OVER_PA1_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA2_OVER register. +// +//***************************************************************************** +#define IOC_PA2_OVER_PA2_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PA2_OVER_PA2_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA3_OVER register. +// +//***************************************************************************** +#define IOC_PA3_OVER_PA3_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PA3_OVER_PA3_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA4_OVER register. +// +//***************************************************************************** +#define IOC_PA4_OVER_PA4_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PA4_OVER_PA4_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA5_OVER register. +// +//***************************************************************************** +#define IOC_PA5_OVER_PA5_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PA5_OVER_PA5_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA6_OVER register. +// +//***************************************************************************** +#define IOC_PA6_OVER_PA6_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PA6_OVER_PA6_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PA7_OVER register. +// +//***************************************************************************** +#define IOC_PA7_OVER_PA7_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PA7_OVER_PA7_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB0_OVER register. +// +//***************************************************************************** +#define IOC_PB0_OVER_PB0_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PB0_OVER_PB0_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB1_OVER register. +// +//***************************************************************************** +#define IOC_PB1_OVER_PB1_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PB1_OVER_PB1_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB2_OVER register. +// +//***************************************************************************** +#define IOC_PB2_OVER_PB2_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PB2_OVER_PB2_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB3_OVER register. +// +//***************************************************************************** +#define IOC_PB3_OVER_PB3_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PB3_OVER_PB3_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB4_OVER register. +// +//***************************************************************************** +#define IOC_PB4_OVER_PB4_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PB4_OVER_PB4_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB5_OVER register. +// +//***************************************************************************** +#define IOC_PB5_OVER_PB5_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PB5_OVER_PB5_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB6_OVER register. +// +//***************************************************************************** +#define IOC_PB6_OVER_PB6_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PB6_OVER_PB6_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PB7_OVER register. +// +//***************************************************************************** +#define IOC_PB7_OVER_PB7_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PB7_OVER_PB7_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC0_OVER register. +// +//***************************************************************************** +#define IOC_PC0_OVER_PC0_over 0x00000008 // 0: output disable 1: oe - + // output enable +#define IOC_PC0_OVER_PC0_over_M 0x00000008 +#define IOC_PC0_OVER_PC0_over_S 3 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC1_OVER register. +// +//***************************************************************************** +#define IOC_PC1_OVER_PC1_over 0x00000008 // 0: output disable 1: oe - + // output enable +#define IOC_PC1_OVER_PC1_over_M 0x00000008 +#define IOC_PC1_OVER_PC1_over_S 3 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC2_OVER register. +// +//***************************************************************************** +#define IOC_PC2_OVER_PC2_over 0x00000008 // 0: output disable 1: oe - + // output enable +#define IOC_PC2_OVER_PC2_over_M 0x00000008 +#define IOC_PC2_OVER_PC2_over_S 3 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC3_OVER register. +// +//***************************************************************************** +#define IOC_PC3_OVER_PC3_over 0x00000008 // 0: output disable 1: oe - + // output enable +#define IOC_PC3_OVER_PC3_over_M 0x00000008 +#define IOC_PC3_OVER_PC3_over_S 3 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC4_OVER register. +// +//***************************************************************************** +#define IOC_PC4_OVER_PC4_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PC4_OVER_PC4_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC5_OVER register. +// +//***************************************************************************** +#define IOC_PC5_OVER_PC5_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PC5_OVER_PC5_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC6_OVER register. +// +//***************************************************************************** +#define IOC_PC6_OVER_PC6_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PC6_OVER_PC6_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PC7_OVER register. +// +//***************************************************************************** +#define IOC_PC7_OVER_PC7_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PC7_OVER_PC7_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD0_OVER register. +// +//***************************************************************************** +#define IOC_PD0_OVER_PD0_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PD0_OVER_PD0_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD1_OVER register. +// +//***************************************************************************** +#define IOC_PD1_OVER_PD1_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PD1_OVER_PD1_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD2_OVER register. +// +//***************************************************************************** +#define IOC_PD2_OVER_PD2_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PD2_OVER_PD2_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD3_OVER register. +// +//***************************************************************************** +#define IOC_PD3_OVER_PD3_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PD3_OVER_PD3_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD4_OVER register. +// +//***************************************************************************** +#define IOC_PD4_OVER_PD4_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PD4_OVER_PD4_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD5_OVER register. +// +//***************************************************************************** +#define IOC_PD5_OVER_PD5_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PD5_OVER_PD5_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD6_OVER register. +// +//***************************************************************************** +#define IOC_PD6_OVER_PD6_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PD6_OVER_PD6_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_PD7_OVER register. +// +//***************************************************************************** +#define IOC_PD7_OVER_PD7_over_M 0x0000000F // 0x8: oe - output enable 0x4: + // pue - pullup enable 0x2: pde - + // pulldown enable 0x1: ana - + // analog enable +#define IOC_PD7_OVER_PD7_over_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_UARTRXD_UART0 register. +// +//***************************************************************************** +#define IOC_UARTRXD_UART0_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as UART0 RX 1: + // PA1 selected as UART0 RX ... 31: + // PD7 selected as UART0 RX + +#define IOC_UARTRXD_UART0_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_UARTCTS_UART1 register. +// +//***************************************************************************** +#define IOC_UARTCTS_UART1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as UART1 CTS 1: + // PA1 selected as UART1 CTS ... + // 31: PD7 selected as UART1 CTS + +#define IOC_UARTCTS_UART1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_UARTRXD_UART1 register. +// +//***************************************************************************** +#define IOC_UARTRXD_UART1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as UART1 RX 1: + // PA1 selected as UART1 RX ... 31: + // PD7 selected as UART1 RX + +#define IOC_UARTRXD_UART1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_CLK_SSI_SSI0 register. +// +//***************************************************************************** +#define IOC_CLK_SSI_SSI0_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as SSI0 CLK 1: + // PA1 selected as SSI0 CLK ... 31: + // PD7 selected as SSI0 CLK + +#define IOC_CLK_SSI_SSI0_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_SSIRXD_SSI0 register. +// +//***************************************************************************** +#define IOC_SSIRXD_SSI0_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as SSI0 RX 1: + // PA1 selected as SSI0 RX ... 31: + // PD7 selected as SSI0 RX + +#define IOC_SSIRXD_SSI0_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_SSIFSSIN_SSI0 register. +// +//***************************************************************************** +#define IOC_SSIFSSIN_SSI0_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as SSI0 FSSIN + // 1: PA1 selected as SSI0 FSSIN + // ... 31: PD7 selected as SSI0 + // FSSIN + +#define IOC_SSIFSSIN_SSI0_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_CLK_SSIIN_SSI0 register. +// +//***************************************************************************** +#define IOC_CLK_SSIIN_SSI0_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as SSI0 + // CLK_SSIN 1: PA1 selected as SSI0 + // CLK_SSIN ... 31: PD7 selected as + // SSI0 CLK_SSIN + +#define IOC_CLK_SSIIN_SSI0_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_CLK_SSI_SSI1 register. +// +//***************************************************************************** +#define IOC_CLK_SSI_SSI1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as SSI1 CLK 1: + // PA1 selected as SSI1 CLK ... 31: + // PD7 selected as SSI1 CLK + +#define IOC_CLK_SSI_SSI1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_SSIRXD_SSI1 register. +// +//***************************************************************************** +#define IOC_SSIRXD_SSI1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as SSI1 RX 1: + // PA1 selected as SSI1 RX ... 31: + // PD7 selected as SSI1 RX + +#define IOC_SSIRXD_SSI1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_SSIFSSIN_SSI1 register. +// +//***************************************************************************** +#define IOC_SSIFSSIN_SSI1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as SSI1 FSSIN + // 1: PA1 selected as SSI1 FSSIN + // ... 31: PD7 selected as SSI1 + // FSSIN + +#define IOC_SSIFSSIN_SSI1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// IOC_CLK_SSIIN_SSI1 register. +// +//***************************************************************************** +#define IOC_CLK_SSIIN_SSI1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as SSI1 + // CLK_SSIN 1: PA1 selected as SSI1 + // CLK_SSIN ... 31: PD7 selected as + // SSI1 CLK_SSIN + +#define IOC_CLK_SSIIN_SSI1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_I2CMSSDA register. +// +//***************************************************************************** +#define IOC_I2CMSSDA_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as I2C SDA 1: + // PA1 selected as I2C SDA ... 31: + // PD7 selected as I2C SDA + +#define IOC_I2CMSSDA_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_I2CMSSCL register. +// +//***************************************************************************** +#define IOC_I2CMSSCL_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as I2C SCL 1: + // PA1 selected as I2C SCL ... 31: + // PD7 selected as I2C SCL + +#define IOC_I2CMSSCL_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_GPT0OCP1 register. +// +//***************************************************************************** +#define IOC_GPT0OCP1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as GPT0OCP1 1: + // PA1 selected as GPT0OCP1 ... 31: + // PD7 selected as GPT0OCP1 + +#define IOC_GPT0OCP1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_GPT0OCP2 register. +// +//***************************************************************************** +#define IOC_GPT0OCP2_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as GPT0OCP2 1: + // PA1 selected as GPT0OCP2 ... 31: + // PD7 selected as GPT0OCP2 + +#define IOC_GPT0OCP2_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_GPT1OCP1 register. +// +//***************************************************************************** +#define IOC_GPT1OCP1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as GPT1OCP1 1: + // PA1 selected as GPT1OCP1 ... 31: + // PD7 selected as GPT1OCP1 + +#define IOC_GPT1OCP1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_GPT1OCP2 register. +// +//***************************************************************************** +#define IOC_GPT1OCP2_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as GPT1OCP2 1: + // PA1 selected as GPT1OCP2 ... 31: + // PD7 selected as GPT1OCP2 + +#define IOC_GPT1OCP2_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_GPT2OCP1 register. +// +//***************************************************************************** +#define IOC_GPT2OCP1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as GPT2OCP1 1: + // PA1 selected as GPT2OCP1 ... 31: + // PD7 selected as GPT2OCP1 + +#define IOC_GPT2OCP1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_GPT2OCP2 register. +// +//***************************************************************************** +#define IOC_GPT2OCP2_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as GPT2OCP2 1: + // PA1 selected as GPT2OCP2 ... 31: + // PD7 selected as GPT2OCP2 + +#define IOC_GPT2OCP2_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_GPT3OCP1 register. +// +//***************************************************************************** +#define IOC_GPT3OCP1_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as GPT3OCP1 1: + // PA1 selected as GPT3OCP1 ... 31: + // PD7 selected as GPT3OCP1 + +#define IOC_GPT3OCP1_INPUT_SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the IOC_GPT3OCP2 register. +// +//***************************************************************************** +#define IOC_GPT3OCP2_INPUT_SEL_M \ + 0x0000001F // 0: PA0 selected as GPT3OCP2 1: + // PA1 selected as GPT3OCP2 ... 31: + // PD7 selected as GPT3OCP2 + +#define IOC_GPT3OCP2_INPUT_SEL_S 0 + + +#endif // __HW_IOC_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_memmap.h b/bsp/boards/mimsy2-cc2538/headers/hw_memmap.h new file mode 100644 index 0000000000..2427f91124 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_memmap.h @@ -0,0 +1,85 @@ +/****************************************************************************** +* Filename: hw_memmap.h +* Revised: $Date: 2013-04-12 15:10:54 +0200 (Fri, 12 Apr 2013) $ +* Revision: $Revision: 9735 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_MEMMAP_H__ +#define __HW_MEMMAP_H__ + +//***************************************************************************** +// +// The following are defines for the base address of the memories and +// peripherals on the top_s interface. +// +//***************************************************************************** +#define ROM_BASE 0x00000000 // ROM +#define FLASH_BASE 0x00200000 // Flash +#define SRAM_BASE 0x20000000 // SRAM +#define SRAM_LL_BASE 0x20004000 // SRAM_LL +#define SSI0_BASE 0x40008000 // SSI +#define SSI1_BASE 0x40009000 // SSI +#define UART0_BASE 0x4000C000 // UART +#define UART1_BASE 0x4000D000 // UART +#define I2C_M0_BASE 0x40020000 // I2CM +#define I2C_S0_BASE 0x40020800 // I2CS +#define GPTIMER0_BASE 0x40030000 // GPTIMER +#define GPTIMER1_BASE 0x40031000 // GPTIMER +#define GPTIMER2_BASE 0x40032000 // GPTIMER +#define GPTIMER3_BASE 0x40033000 // GPTIMER +#define RFCORE_RAM_BASE 0x40088000 // SRAM_RFCORE +#define FRMF_SRCM_RAM_BASE 0x40088400 // SRAM_FRMF_SRCM +#define RFCORE_FFSM_BASE 0x40088500 // RFCORE_FFSM +#define RFCORE_XREG_BASE 0x40088600 // RFCORE_XREG +#define RFCORE_SFR_BASE 0x40088800 // RFCORE_SFR +#define USB_BASE 0x40089000 // USB +#define AES_BASE 0x4008B000 // AES +#define SYS_CTRL_BASE 0x400D2000 // SYS_CTRL +#define FLASH_CTRL_BASE 0x400D3000 // FLASH_CTRL +#define IOC_BASE 0x400D4000 // IOC +#define SMWDTHROSC_BASE 0x400D5000 // SMWDTHROSC +#define ANA_REGS_BASE 0x400D6000 // ANA_REGS +#define SOC_ADC_BASE 0x400D7000 // SOC_ADC +#define GPIO_A_BASE 0x400D9000 // GPIO +#define GPIO_B_BASE 0x400DA000 // GPIO +#define GPIO_C_BASE 0x400DB000 // GPIO +#define GPIO_D_BASE 0x400DC000 // GPIO +#define uDMA_BASE 0x400FF000 // UDMA +#define ST_TESTCTRL_BASE 0x40110000 // STTEST +#define PKA_BASE 0x44004000 // PKA +#define PKA_RAM_BASE 0x44006000 // SRAM_PKA +#define CC_TESTCTRL_BASE 0x44010000 // CCTEST + +#endif // __HW_MEMMAP_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_nvic.h b/bsp/boards/mimsy2-cc2538/headers/hw_nvic.h new file mode 100644 index 0000000000..c259a0cde6 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_nvic.h @@ -0,0 +1,1767 @@ +/****************************************************************************** +* Filename: hw_nvic.h +* Revised: $Date: 2013-04-29 09:49:55 +0200 (Mon, 29 Apr 2013) $ +* Revision: $Revision: 9923 $ +* +* Description: Macros used when accessing the NVIC hardware. +* +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_NVIC_H__ +#define __HW_NVIC_H__ + +//***************************************************************************** +// +// The following are defines for the NVIC register addresses. +// +//***************************************************************************** +#define NVIC_INT_TYPE 0xE000E004 // Interrupt Controller Type Reg +#define NVIC_ACTLR 0xE000E008 // Auxiliary Control +#define NVIC_ST_CTRL 0xE000E010 // SysTick Control and Status + // Register +#define NVIC_ST_RELOAD 0xE000E014 // SysTick Reload Value Register +#define NVIC_ST_CURRENT 0xE000E018 // SysTick Current Value Register +#define NVIC_ST_CAL 0xE000E01C // SysTick Calibration Value Reg +#define NVIC_EN0 0xE000E100 // Interrupt 0-31 Set Enable +#define NVIC_EN1 0xE000E104 // Interrupt 32-54 Set Enable +#define NVIC_EN2 0xE000E108 // Interrupt 64-95 Set Enable +#define NVIC_EN3 0xE000E10C // Interrupt 96-127 Set Enable +#define NVIC_EN4 0xE000E110 // Interrupt 128-131 Set Enable +#define NVIC_DIS0 0xE000E180 // Interrupt 0-31 Clear Enable +#define NVIC_DIS1 0xE000E184 // Interrupt 32-54 Clear Enable +#define NVIC_DIS2 0xE000E188 // Interrupt 64-95 Clear Enable +#define NVIC_DIS3 0xE000E18C // Interrupt 96-127 Clear Enable +#define NVIC_DIS4 0xE000E190 // Interrupt 128-131 Clear Enable +#define NVIC_PEND0 0xE000E200 // Interrupt 0-31 Set Pending +#define NVIC_PEND1 0xE000E204 // Interrupt 32-54 Set Pending +#define NVIC_PEND2 0xE000E208 // Interrupt 64-95 Set Pending +#define NVIC_PEND3 0xE000E20C // Interrupt 96-127 Set Pending +#define NVIC_PEND4 0xE000E210 // Interrupt 128-131 Set Pending +#define NVIC_UNPEND0 0xE000E280 // Interrupt 0-31 Clear Pending +#define NVIC_UNPEND1 0xE000E284 // Interrupt 32-54 Clear Pending +#define NVIC_UNPEND2 0xE000E288 // Interrupt 64-95 Clear Pending +#define NVIC_UNPEND3 0xE000E28C // Interrupt 96-127 Clear Pending +#define NVIC_UNPEND4 0xE000E290 // Interrupt 128-131 Clear Pending +#define NVIC_ACTIVE0 0xE000E300 // Interrupt 0-31 Active Bit +#define NVIC_ACTIVE1 0xE000E304 // Interrupt 32-54 Active Bit +#define NVIC_ACTIVE2 0xE000E308 // Interrupt 64-95 Active Bit +#define NVIC_ACTIVE3 0xE000E30C // Interrupt 96-127 Active Bit +#define NVIC_ACTIVE4 0xE000E310 // Interrupt 128-131 Active Bit +#define NVIC_PRI0 0xE000E400 // Interrupt 0-3 Priority +#define NVIC_PRI1 0xE000E404 // Interrupt 4-7 Priority +#define NVIC_PRI2 0xE000E408 // Interrupt 8-11 Priority +#define NVIC_PRI3 0xE000E40C // Interrupt 12-15 Priority +#define NVIC_PRI4 0xE000E410 // Interrupt 16-19 Priority +#define NVIC_PRI5 0xE000E414 // Interrupt 20-23 Priority +#define NVIC_PRI6 0xE000E418 // Interrupt 24-27 Priority +#define NVIC_PRI7 0xE000E41C // Interrupt 28-31 Priority +#define NVIC_PRI8 0xE000E420 // Interrupt 32-35 Priority +#define NVIC_PRI9 0xE000E424 // Interrupt 36-39 Priority +#define NVIC_PRI10 0xE000E428 // Interrupt 40-43 Priority +#define NVIC_PRI11 0xE000E42C // Interrupt 44-47 Priority +#define NVIC_PRI12 0xE000E430 // Interrupt 48-51 Priority +#define NVIC_PRI13 0xE000E434 // Interrupt 52-53 Priority +#define NVIC_PRI14 0xE000E438 // Interrupt 56-59 Priority +#define NVIC_PRI15 0xE000E43C // Interrupt 60-63 Priority +#define NVIC_PRI16 0xE000E440 // Interrupt 64-67 Priority +#define NVIC_PRI17 0xE000E444 // Interrupt 68-71 Priority +#define NVIC_PRI18 0xE000E448 // Interrupt 72-75 Priority +#define NVIC_PRI19 0xE000E44C // Interrupt 76-79 Priority +#define NVIC_PRI20 0xE000E450 // Interrupt 80-83 Priority +#define NVIC_PRI21 0xE000E454 // Interrupt 84-87 Priority +#define NVIC_PRI22 0xE000E458 // Interrupt 88-91 Priority +#define NVIC_PRI23 0xE000E45C // Interrupt 92-95 Priority +#define NVIC_PRI24 0xE000E460 // Interrupt 96-99 Priority +#define NVIC_PRI25 0xE000E464 // Interrupt 100-103 Priority +#define NVIC_PRI26 0xE000E468 // Interrupt 104-107 Priority +#define NVIC_PRI27 0xE000E46C // Interrupt 108-111 Priority +#define NVIC_PRI28 0xE000E470 // Interrupt 112-115 Priority +#define NVIC_PRI29 0xE000E474 // Interrupt 116-119 Priority +#define NVIC_PRI30 0xE000E478 // Interrupt 120-123 Priority +#define NVIC_PRI31 0xE000E47C // Interrupt 124-127 Priority +#define NVIC_PRI32 0xE000E480 // Interrupt 128-131 Priority +#define NVIC_PRI33 0xE000E484 // Interrupt 132-135 Priority +#define NVIC_PRI34 0xE000E488 // Interrupt 136-139 Priority +#define NVIC_PRI35 0xE000E48C // Interrupt 140-143 Priority +#define NVIC_PRI36 0xE000E490 // Interrupt 144-147 Priority +#define NVIC_CPUID 0xE000ED00 // CPU ID Base +#define NVIC_INT_CTRL 0xE000ED04 // Interrupt Control and State +#define NVIC_VTABLE 0xE000ED08 // Vector Table Offset +#define NVIC_APINT 0xE000ED0C // Application Interrupt and Reset + // Control +#define NVIC_SYS_CTRL 0xE000ED10 // System Control +#define NVIC_CFG_CTRL 0xE000ED14 // Configuration and Control +#define NVIC_SYS_PRI1 0xE000ED18 // System Handler Priority 1 +#define NVIC_SYS_PRI2 0xE000ED1C // System Handler Priority 2 +#define NVIC_SYS_PRI3 0xE000ED20 // System Handler Priority 3 +#define NVIC_SYS_HND_CTRL 0xE000ED24 // System Handler Control and State +#define NVIC_FAULT_STAT 0xE000ED28 // Configurable Fault Status +#define NVIC_HFAULT_STAT 0xE000ED2C // Hard Fault Status +#define NVIC_DEBUG_STAT 0xE000ED30 // Debug Status Register +#define NVIC_MM_ADDR 0xE000ED34 // Memory Management Fault Address +#define NVIC_FAULT_ADDR 0xE000ED38 // Bus Fault Address +#define NVIC_MPU_TYPE 0xE000ED90 // MPU Type +#define NVIC_MPU_CTRL 0xE000ED94 // MPU Control +#define NVIC_MPU_NUMBER 0xE000ED98 // MPU Region Number +#define NVIC_MPU_BASE 0xE000ED9C // MPU Region Base Address +#define NVIC_MPU_ATTR 0xE000EDA0 // MPU Region Attribute and Size +#define NVIC_MPU_BASE1 0xE000EDA4 // MPU Region Base Address Alias 1 +#define NVIC_MPU_ATTR1 0xE000EDA8 // MPU Region Attribute and Size + // Alias 1 +#define NVIC_MPU_BASE2 0xE000EDAC // MPU Region Base Address Alias 2 +#define NVIC_MPU_ATTR2 0xE000EDB0 // MPU Region Attribute and Size + // Alias 2 +#define NVIC_MPU_BASE3 0xE000EDB4 // MPU Region Base Address Alias 3 +#define NVIC_MPU_ATTR3 0xE000EDB8 // MPU Region Attribute and Size + // Alias 3 +#define NVIC_DBG_CTRL 0xE000EDF0 // Debug Control and Status Reg +#define NVIC_DBG_XFER 0xE000EDF4 // Debug Core Reg. Transfer Select +#define NVIC_DBG_DATA 0xE000EDF8 // Debug Core Register Data +#define NVIC_DBG_INT 0xE000EDFC // Debug Reset Interrupt Control +#define NVIC_SW_TRIG 0xE000EF00 // Software Trigger Interrupt + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_INT_TYPE register. +// +//***************************************************************************** +#define NVIC_INT_TYPE_LINES_M 0x0000001F // Number of interrupt lines (x32) +#define NVIC_INT_TYPE_LINES_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ACTLR register. +// +//***************************************************************************** +#define NVIC_ACTLR_DISFOLD 0x00000004 // Disable IT Folding +#define NVIC_ACTLR_DISWBUF 0x00000002 // Disable Write Buffer +#define NVIC_ACTLR_DISMCYC 0x00000001 // Disable Interrupts of Multiple + // Cycle Instructions + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ST_CTRL register. +// +//***************************************************************************** +#define NVIC_ST_CTRL_COUNT 0x00010000 // Count Flag +#define NVIC_ST_CTRL_CLK_SRC 0x00000004 // Clock Source +#define NVIC_ST_CTRL_INTEN 0x00000002 // Interrupt Enable +#define NVIC_ST_CTRL_ENABLE 0x00000001 // Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ST_RELOAD register. +// +//***************************************************************************** +#define NVIC_ST_RELOAD_M 0x00FFFFFF // Reload Value +#define NVIC_ST_RELOAD_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ST_CURRENT +// register. +// +//***************************************************************************** +#define NVIC_ST_CURRENT_M 0x00FFFFFF // Current Value +#define NVIC_ST_CURRENT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ST_CAL register. +// +//***************************************************************************** +#define NVIC_ST_CAL_NOREF 0x80000000 // No reference clock +#define NVIC_ST_CAL_SKEW 0x40000000 // Clock skew +#define NVIC_ST_CAL_ONEMS_M 0x00FFFFFF // 1ms reference value +#define NVIC_ST_CAL_ONEMS_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_EN0 register. +// +//***************************************************************************** +#define NVIC_EN0_INT_M 0xFFFFFFFF // Interrupt Enable +#define NVIC_EN0_INT0 0x00000001 // Interrupt 0 enable +#define NVIC_EN0_INT1 0x00000002 // Interrupt 1 enable +#define NVIC_EN0_INT2 0x00000004 // Interrupt 2 enable +#define NVIC_EN0_INT3 0x00000008 // Interrupt 3 enable +#define NVIC_EN0_INT4 0x00000010 // Interrupt 4 enable +#define NVIC_EN0_INT5 0x00000020 // Interrupt 5 enable +#define NVIC_EN0_INT6 0x00000040 // Interrupt 6 enable +#define NVIC_EN0_INT7 0x00000080 // Interrupt 7 enable +#define NVIC_EN0_INT8 0x00000100 // Interrupt 8 enable +#define NVIC_EN0_INT9 0x00000200 // Interrupt 9 enable +#define NVIC_EN0_INT10 0x00000400 // Interrupt 10 enable +#define NVIC_EN0_INT11 0x00000800 // Interrupt 11 enable +#define NVIC_EN0_INT12 0x00001000 // Interrupt 12 enable +#define NVIC_EN0_INT13 0x00002000 // Interrupt 13 enable +#define NVIC_EN0_INT14 0x00004000 // Interrupt 14 enable +#define NVIC_EN0_INT15 0x00008000 // Interrupt 15 enable +#define NVIC_EN0_INT16 0x00010000 // Interrupt 16 enable +#define NVIC_EN0_INT17 0x00020000 // Interrupt 17 enable +#define NVIC_EN0_INT18 0x00040000 // Interrupt 18 enable +#define NVIC_EN0_INT19 0x00080000 // Interrupt 19 enable +#define NVIC_EN0_INT20 0x00100000 // Interrupt 20 enable +#define NVIC_EN0_INT21 0x00200000 // Interrupt 21 enable +#define NVIC_EN0_INT22 0x00400000 // Interrupt 22 enable +#define NVIC_EN0_INT23 0x00800000 // Interrupt 23 enable +#define NVIC_EN0_INT24 0x01000000 // Interrupt 24 enable +#define NVIC_EN0_INT25 0x02000000 // Interrupt 25 enable +#define NVIC_EN0_INT26 0x04000000 // Interrupt 26 enable +#define NVIC_EN0_INT27 0x08000000 // Interrupt 27 enable +#define NVIC_EN0_INT28 0x10000000 // Interrupt 28 enable +#define NVIC_EN0_INT29 0x20000000 // Interrupt 29 enable +#define NVIC_EN0_INT30 0x40000000 // Interrupt 30 enable +#define NVIC_EN0_INT31 0x80000000 // Interrupt 31 enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_EN1 register. +// +//***************************************************************************** +#define NVIC_EN1_INT_M 0xFFFFFFFF // Interrupt Enable +#define NVIC_EN1_INT32 0x00000001 // Interrupt 32 enable +#define NVIC_EN1_INT33 0x00000002 // Interrupt 33 enable +#define NVIC_EN1_INT34 0x00000004 // Interrupt 34 enable +#define NVIC_EN1_INT35 0x00000008 // Interrupt 35 enable +#define NVIC_EN1_INT36 0x00000010 // Interrupt 36 enable +#define NVIC_EN1_INT37 0x00000020 // Interrupt 37 enable +#define NVIC_EN1_INT38 0x00000040 // Interrupt 38 enable +#define NVIC_EN1_INT39 0x00000080 // Interrupt 39 enable +#define NVIC_EN1_INT40 0x00000100 // Interrupt 40 enable +#define NVIC_EN1_INT41 0x00000200 // Interrupt 41 enable +#define NVIC_EN1_INT42 0x00000400 // Interrupt 42 enable +#define NVIC_EN1_INT43 0x00000800 // Interrupt 43 enable +#define NVIC_EN1_INT44 0x00001000 // Interrupt 44 enable +#define NVIC_EN1_INT45 0x00002000 // Interrupt 45 enable +#define NVIC_EN1_INT46 0x00004000 // Interrupt 46 enable +#define NVIC_EN1_INT47 0x00008000 // Interrupt 47 enable +#define NVIC_EN1_INT48 0x00010000 // Interrupt 48 enable +#define NVIC_EN1_INT49 0x00020000 // Interrupt 49 enable +#define NVIC_EN1_INT50 0x00040000 // Interrupt 50 enable +#define NVIC_EN1_INT51 0x00080000 // Interrupt 51 enable +#define NVIC_EN1_INT52 0x00100000 // Interrupt 52 enable +#define NVIC_EN1_INT53 0x00200000 // Interrupt 53 enable +#define NVIC_EN1_INT54 0x00400000 // Interrupt 54 enable +#define NVIC_EN1_INT55 0x00800000 // Interrupt 55 enable +#define NVIC_EN1_INT56 0x01000000 // Interrupt 56 enable +#define NVIC_EN1_INT57 0x02000000 // Interrupt 57 enable +#define NVIC_EN1_INT58 0x04000000 // Interrupt 58 enable +#define NVIC_EN1_INT59 0x08000000 // Interrupt 59 enable +#define NVIC_EN1_INT60 0x10000000 // Interrupt 60 enable +#define NVIC_EN1_INT61 0x20000000 // Interrupt 61 enable +#define NVIC_EN1_INT62 0x40000000 // Interrupt 62 enable +#define NVIC_EN1_INT63 0x80000000 // Interrupt 63 enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_EN2 register. +// +//***************************************************************************** +#define NVIC_EN2_INT_M 0xFFFFFFFF // Interrupt Enable +#define NVIC_EN2_INT64 0x00000001 // Interrupt 64 enable +#define NVIC_EN2_INT65 0x00000002 // Interrupt 65 enable +#define NVIC_EN2_INT66 0x00000004 // Interrupt 66 enable +#define NVIC_EN2_INT67 0x00000008 // Interrupt 67 enable +#define NVIC_EN2_INT68 0x00000010 // Interrupt 68 enable +#define NVIC_EN2_INT69 0x00000020 // Interrupt 69 enable +#define NVIC_EN2_INT70 0x00000040 // Interrupt 70 enable +#define NVIC_EN2_INT71 0x00000080 // Interrupt 71 enable +#define NVIC_EN2_INT72 0x00000100 // Interrupt 72 enable +#define NVIC_EN2_INT73 0x00000200 // Interrupt 73 enable +#define NVIC_EN2_INT74 0x00000400 // Interrupt 74 enable +#define NVIC_EN2_INT75 0x00000800 // Interrupt 75 enable +#define NVIC_EN2_INT76 0x00001000 // Interrupt 76 enable +#define NVIC_EN2_INT77 0x00002000 // Interrupt 77 enable +#define NVIC_EN2_INT78 0x00004000 // Interrupt 78 enable +#define NVIC_EN2_INT79 0x00008000 // Interrupt 79 enable +#define NVIC_EN2_INT80 0x00010000 // Interrupt 80 enable +#define NVIC_EN2_INT81 0x00020000 // Interrupt 81 enable +#define NVIC_EN2_INT82 0x00040000 // Interrupt 82 enable +#define NVIC_EN2_INT83 0x00080000 // Interrupt 83 enable +#define NVIC_EN2_INT84 0x00100000 // Interrupt 84 enable +#define NVIC_EN2_INT85 0x00200000 // Interrupt 85 enable +#define NVIC_EN2_INT86 0x00400000 // Interrupt 86 enable +#define NVIC_EN2_INT87 0x00800000 // Interrupt 87 enable +#define NVIC_EN2_INT88 0x01000000 // Interrupt 88 enable +#define NVIC_EN2_INT89 0x02000000 // Interrupt 89 enable +#define NVIC_EN2_INT90 0x04000000 // Interrupt 90 enable +#define NVIC_EN2_INT91 0x08000000 // Interrupt 91 enable +#define NVIC_EN2_INT92 0x10000000 // Interrupt 92 enable +#define NVIC_EN2_INT93 0x20000000 // Interrupt 93 enable +#define NVIC_EN2_INT94 0x40000000 // Interrupt 94 enable +#define NVIC_EN2_INT95 0x80000000 // Interrupt 95 enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_EN3 register. +// +//***************************************************************************** +#define NVIC_EN3_INT_M 0xFFFFFFFF // Interrupt Enable +#define NVIC_EN3_INT96 0x00000001 // Interrupt 96 enable +#define NVIC_EN3_INT97 0x00000002 // Interrupt 97 enable +#define NVIC_EN3_INT98 0x00000004 // Interrupt 98 enable +#define NVIC_EN3_INT99 0x00000008 // Interrupt 99 enable +#define NVIC_EN3_INT100 0x00000010 // Interrupt 100 enable +#define NVIC_EN3_INT101 0x00000020 // Interrupt 101 enable +#define NVIC_EN3_INT102 0x00000040 // Interrupt 102 enable +#define NVIC_EN3_INT103 0x00000080 // Interrupt 103 enable +#define NVIC_EN3_INT104 0x00000100 // Interrupt 104 enable +#define NVIC_EN3_INT105 0x00000200 // Interrupt 105 enable +#define NVIC_EN3_INT106 0x00000400 // Interrupt 106 enable +#define NVIC_EN3_INT107 0x00000800 // Interrupt 107 enable +#define NVIC_EN3_INT108 0x00001000 // Interrupt 108 enable +#define NVIC_EN3_INT109 0x00002000 // Interrupt 109 enable +#define NVIC_EN3_INT110 0x00004000 // Interrupt 110 enable +#define NVIC_EN3_INT111 0x00008000 // Interrupt 111 enable +#define NVIC_EN3_INT112 0x00010000 // Interrupt 112 enable +#define NVIC_EN3_INT113 0x00020000 // Interrupt 113 enable +#define NVIC_EN3_INT114 0x00040000 // Interrupt 114 enable +#define NVIC_EN3_INT115 0x00080000 // Interrupt 115 enable +#define NVIC_EN3_INT116 0x00100000 // Interrupt 116 enable +#define NVIC_EN3_INT117 0x00200000 // Interrupt 117 enable +#define NVIC_EN3_INT118 0x00400000 // Interrupt 118 enable +#define NVIC_EN3_INT119 0x00800000 // Interrupt 119 enable +#define NVIC_EN3_INT120 0x01000000 // Interrupt 120 enable +#define NVIC_EN3_INT121 0x02000000 // Interrupt 121 enable +#define NVIC_EN3_INT122 0x04000000 // Interrupt 122 enable +#define NVIC_EN3_INT123 0x08000000 // Interrupt 123 enable +#define NVIC_EN3_INT124 0x10000000 // Interrupt 124 enable +#define NVIC_EN3_INT125 0x20000000 // Interrupt 125 enable +#define NVIC_EN3_INT126 0x40000000 // Interrupt 126 enable +#define NVIC_EN3_INT127 0x80000000 // Interrupt 127 enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_EN4 register. +// +//***************************************************************************** +#define NVIC_EN4_INT_M 0x0000000F // Interrupt Enable +#define NVIC_EN4_INT128 0x00000001 // Interrupt 128 enable +#define NVIC_EN4_INT129 0x00000002 // Interrupt 129 enable +#define NVIC_EN4_INT130 0x00000004 // Interrupt 130 enable +#define NVIC_EN4_INT131 0x00000008 // Interrupt 131 enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DIS0 register. +// +//***************************************************************************** +#define NVIC_DIS0_INT_M 0xFFFFFFFF // Interrupt Disable +#define NVIC_DIS0_INT0 0x00000001 // Interrupt 0 disable +#define NVIC_DIS0_INT1 0x00000002 // Interrupt 1 disable +#define NVIC_DIS0_INT2 0x00000004 // Interrupt 2 disable +#define NVIC_DIS0_INT3 0x00000008 // Interrupt 3 disable +#define NVIC_DIS0_INT4 0x00000010 // Interrupt 4 disable +#define NVIC_DIS0_INT5 0x00000020 // Interrupt 5 disable +#define NVIC_DIS0_INT6 0x00000040 // Interrupt 6 disable +#define NVIC_DIS0_INT7 0x00000080 // Interrupt 7 disable +#define NVIC_DIS0_INT8 0x00000100 // Interrupt 8 disable +#define NVIC_DIS0_INT9 0x00000200 // Interrupt 9 disable +#define NVIC_DIS0_INT10 0x00000400 // Interrupt 10 disable +#define NVIC_DIS0_INT11 0x00000800 // Interrupt 11 disable +#define NVIC_DIS0_INT12 0x00001000 // Interrupt 12 disable +#define NVIC_DIS0_INT13 0x00002000 // Interrupt 13 disable +#define NVIC_DIS0_INT14 0x00004000 // Interrupt 14 disable +#define NVIC_DIS0_INT15 0x00008000 // Interrupt 15 disable +#define NVIC_DIS0_INT16 0x00010000 // Interrupt 16 disable +#define NVIC_DIS0_INT17 0x00020000 // Interrupt 17 disable +#define NVIC_DIS0_INT18 0x00040000 // Interrupt 18 disable +#define NVIC_DIS0_INT19 0x00080000 // Interrupt 19 disable +#define NVIC_DIS0_INT20 0x00100000 // Interrupt 20 disable +#define NVIC_DIS0_INT21 0x00200000 // Interrupt 21 disable +#define NVIC_DIS0_INT22 0x00400000 // Interrupt 22 disable +#define NVIC_DIS0_INT23 0x00800000 // Interrupt 23 disable +#define NVIC_DIS0_INT24 0x01000000 // Interrupt 24 disable +#define NVIC_DIS0_INT25 0x02000000 // Interrupt 25 disable +#define NVIC_DIS0_INT26 0x04000000 // Interrupt 26 disable +#define NVIC_DIS0_INT27 0x08000000 // Interrupt 27 disable +#define NVIC_DIS0_INT28 0x10000000 // Interrupt 28 disable +#define NVIC_DIS0_INT29 0x20000000 // Interrupt 29 disable +#define NVIC_DIS0_INT30 0x40000000 // Interrupt 30 disable +#define NVIC_DIS0_INT31 0x80000000 // Interrupt 31 disable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DIS1 register. +// +//***************************************************************************** +#define NVIC_DIS1_INT_M 0xFFFFFFFF // Interrupt Disable +#define NVIC_DIS1_INT32 0x00000001 // Interrupt 32 disable +#define NVIC_DIS1_INT33 0x00000002 // Interrupt 33 disable +#define NVIC_DIS1_INT34 0x00000004 // Interrupt 34 disable +#define NVIC_DIS1_INT35 0x00000008 // Interrupt 35 disable +#define NVIC_DIS1_INT36 0x00000010 // Interrupt 36 disable +#define NVIC_DIS1_INT37 0x00000020 // Interrupt 37 disable +#define NVIC_DIS1_INT38 0x00000040 // Interrupt 38 disable +#define NVIC_DIS1_INT39 0x00000080 // Interrupt 39 disable +#define NVIC_DIS1_INT40 0x00000100 // Interrupt 40 disable +#define NVIC_DIS1_INT41 0x00000200 // Interrupt 41 disable +#define NVIC_DIS1_INT42 0x00000400 // Interrupt 42 disable +#define NVIC_DIS1_INT43 0x00000800 // Interrupt 43 disable +#define NVIC_DIS1_INT44 0x00001000 // Interrupt 44 disable +#define NVIC_DIS1_INT45 0x00002000 // Interrupt 45 disable +#define NVIC_DIS1_INT46 0x00004000 // Interrupt 46 disable +#define NVIC_DIS1_INT47 0x00008000 // Interrupt 47 disable +#define NVIC_DIS1_INT48 0x00010000 // Interrupt 48 disable +#define NVIC_DIS1_INT49 0x00020000 // Interrupt 49 disable +#define NVIC_DIS1_INT50 0x00040000 // Interrupt 50 disable +#define NVIC_DIS1_INT51 0x00080000 // Interrupt 51 disable +#define NVIC_DIS1_INT52 0x00100000 // Interrupt 52 disable +#define NVIC_DIS1_INT53 0x00200000 // Interrupt 53 disable +#define NVIC_DIS1_INT54 0x00400000 // Interrupt 54 disable +#define NVIC_DIS1_INT55 0x00800000 // Interrupt 55 disable +#define NVIC_DIS1_INT56 0x01000000 // Interrupt 56 disable +#define NVIC_DIS1_INT57 0x02000000 // Interrupt 57 disable +#define NVIC_DIS1_INT58 0x04000000 // Interrupt 58 disable +#define NVIC_DIS1_INT59 0x08000000 // Interrupt 59 disable +#define NVIC_DIS1_INT60 0x10000000 // Interrupt 60 disable +#define NVIC_DIS1_INT61 0x20000000 // Interrupt 61 disable +#define NVIC_DIS1_INT62 0x40000000 // Interrupt 62 disable +#define NVIC_DIS1_INT63 0x80000000 // Interrupt 63 disable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DIS2 register. +// +//***************************************************************************** +#define NVIC_DIS2_INT_M 0xFFFFFFFF // Interrupt Disable +#define NVIC_DIS2_INT64 0x00000001 // Interrupt 64 disable +#define NVIC_DIS2_INT65 0x00000002 // Interrupt 65 disable +#define NVIC_DIS2_INT66 0x00000004 // Interrupt 66 disable +#define NVIC_DIS2_INT67 0x00000008 // Interrupt 67 disable +#define NVIC_DIS2_INT68 0x00000010 // Interrupt 68 disable +#define NVIC_DIS2_INT69 0x00000020 // Interrupt 69 disable +#define NVIC_DIS2_INT70 0x00000040 // Interrupt 70 disable +#define NVIC_DIS2_INT71 0x00000080 // Interrupt 71 disable +#define NVIC_DIS2_INT72 0x00000100 // Interrupt 72 disable +#define NVIC_DIS2_INT73 0x00000200 // Interrupt 73 disable +#define NVIC_DIS2_INT74 0x00000400 // Interrupt 74 disable +#define NVIC_DIS2_INT75 0x00000800 // Interrupt 75 disable +#define NVIC_DIS2_INT76 0x00001000 // Interrupt 76 disable +#define NVIC_DIS2_INT77 0x00002000 // Interrupt 77 disable +#define NVIC_DIS2_INT78 0x00004000 // Interrupt 78 disable +#define NVIC_DIS2_INT79 0x00008000 // Interrupt 79 disable +#define NVIC_DIS2_INT80 0x00010000 // Interrupt 80 disable +#define NVIC_DIS2_INT81 0x00020000 // Interrupt 81 disable +#define NVIC_DIS2_INT82 0x00040000 // Interrupt 82 disable +#define NVIC_DIS2_INT83 0x00080000 // Interrupt 83 disable +#define NVIC_DIS2_INT84 0x00100000 // Interrupt 84 disable +#define NVIC_DIS2_INT85 0x00200000 // Interrupt 85 disable +#define NVIC_DIS2_INT86 0x00400000 // Interrupt 86 disable +#define NVIC_DIS2_INT87 0x00800000 // Interrupt 87 disable +#define NVIC_DIS2_INT88 0x01000000 // Interrupt 88 disable +#define NVIC_DIS2_INT89 0x02000000 // Interrupt 89 disable +#define NVIC_DIS2_INT90 0x04000000 // Interrupt 90 disable +#define NVIC_DIS2_INT91 0x08000000 // Interrupt 91 disable +#define NVIC_DIS2_INT92 0x10000000 // Interrupt 92 disable +#define NVIC_DIS2_INT93 0x20000000 // Interrupt 93 disable +#define NVIC_DIS2_INT94 0x40000000 // Interrupt 94 disable +#define NVIC_DIS2_INT95 0x80000000 // Interrupt 95 disable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DIS3 register. +// +//***************************************************************************** +#define NVIC_DIS3_INT_M 0xFFFFFFFF // Interrupt Disable +#define NVIC_DIS3_INT96 0x00000001 // Interrupt 96 disable +#define NVIC_DIS3_INT97 0x00000002 // Interrupt 97 disable +#define NVIC_DIS3_INT98 0x00000004 // Interrupt 98 disable +#define NVIC_DIS3_INT99 0x00000008 // Interrupt 99 disable +#define NVIC_DIS3_INT100 0x00000010 // Interrupt 100 disable +#define NVIC_DIS3_INT101 0x00000020 // Interrupt 101 disable +#define NVIC_DIS3_INT102 0x00000040 // Interrupt 102 disable +#define NVIC_DIS3_INT103 0x00000080 // Interrupt 103 disable +#define NVIC_DIS3_INT104 0x00000100 // Interrupt 104 disable +#define NVIC_DIS3_INT105 0x00000200 // Interrupt 105 disable +#define NVIC_DIS3_INT106 0x00000400 // Interrupt 106 disable +#define NVIC_DIS3_INT107 0x00000800 // Interrupt 107 disable +#define NVIC_DIS3_INT108 0x00001000 // Interrupt 108 disable +#define NVIC_DIS3_INT109 0x00002000 // Interrupt 109 disable +#define NVIC_DIS3_INT110 0x00004000 // Interrupt 110 disable +#define NVIC_DIS3_INT111 0x00008000 // Interrupt 111 disable +#define NVIC_DIS3_INT112 0x00010000 // Interrupt 112 disable +#define NVIC_DIS3_INT113 0x00020000 // Interrupt 113 disable +#define NVIC_DIS3_INT114 0x00040000 // Interrupt 114 disable +#define NVIC_DIS3_INT115 0x00080000 // Interrupt 115 disable +#define NVIC_DIS3_INT116 0x00100000 // Interrupt 116 disable +#define NVIC_DIS3_INT117 0x00200000 // Interrupt 117 disable +#define NVIC_DIS3_INT118 0x00400000 // Interrupt 118 disable +#define NVIC_DIS3_INT119 0x00800000 // Interrupt 119 disable +#define NVIC_DIS3_INT120 0x01000000 // Interrupt 120 disable +#define NVIC_DIS3_INT121 0x02000000 // Interrupt 121 disable +#define NVIC_DIS3_INT122 0x04000000 // Interrupt 122 disable +#define NVIC_DIS3_INT123 0x08000000 // Interrupt 123 disable +#define NVIC_DIS3_INT124 0x10000000 // Interrupt 124 disable +#define NVIC_DIS3_INT125 0x20000000 // Interrupt 125 disable +#define NVIC_DIS3_INT126 0x40000000 // Interrupt 126 disable +#define NVIC_DIS3_INT127 0x80000000 // Interrupt 127 disable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DIS4 register. +// +//***************************************************************************** +#define NVIC_DIS4_INT_M 0x0000000F // Interrupt Disable +#define NVIC_DIS4_INT128 0x00000001 // Interrupt 128 disable +#define NVIC_DIS4_INT129 0x00000002 // Interrupt 129 disable +#define NVIC_DIS4_INT130 0x00000004 // Interrupt 130 disable +#define NVIC_DIS4_INT131 0x00000008 // Interrupt 131 disable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PEND0 register. +// +//***************************************************************************** +#define NVIC_PEND0_INT_M 0xFFFFFFFF // Interrupt Set Pending +#define NVIC_PEND0_INT0 0x00000001 // Interrupt 0 pend +#define NVIC_PEND0_INT1 0x00000002 // Interrupt 1 pend +#define NVIC_PEND0_INT2 0x00000004 // Interrupt 2 pend +#define NVIC_PEND0_INT3 0x00000008 // Interrupt 3 pend +#define NVIC_PEND0_INT4 0x00000010 // Interrupt 4 pend +#define NVIC_PEND0_INT5 0x00000020 // Interrupt 5 pend +#define NVIC_PEND0_INT6 0x00000040 // Interrupt 6 pend +#define NVIC_PEND0_INT7 0x00000080 // Interrupt 7 pend +#define NVIC_PEND0_INT8 0x00000100 // Interrupt 8 pend +#define NVIC_PEND0_INT9 0x00000200 // Interrupt 9 pend +#define NVIC_PEND0_INT10 0x00000400 // Interrupt 10 pend +#define NVIC_PEND0_INT11 0x00000800 // Interrupt 11 pend +#define NVIC_PEND0_INT12 0x00001000 // Interrupt 12 pend +#define NVIC_PEND0_INT13 0x00002000 // Interrupt 13 pend +#define NVIC_PEND0_INT14 0x00004000 // Interrupt 14 pend +#define NVIC_PEND0_INT15 0x00008000 // Interrupt 15 pend +#define NVIC_PEND0_INT16 0x00010000 // Interrupt 16 pend +#define NVIC_PEND0_INT17 0x00020000 // Interrupt 17 pend +#define NVIC_PEND0_INT18 0x00040000 // Interrupt 18 pend +#define NVIC_PEND0_INT19 0x00080000 // Interrupt 19 pend +#define NVIC_PEND0_INT20 0x00100000 // Interrupt 20 pend +#define NVIC_PEND0_INT21 0x00200000 // Interrupt 21 pend +#define NVIC_PEND0_INT22 0x00400000 // Interrupt 22 pend +#define NVIC_PEND0_INT23 0x00800000 // Interrupt 23 pend +#define NVIC_PEND0_INT24 0x01000000 // Interrupt 24 pend +#define NVIC_PEND0_INT25 0x02000000 // Interrupt 25 pend +#define NVIC_PEND0_INT26 0x04000000 // Interrupt 26 pend +#define NVIC_PEND0_INT27 0x08000000 // Interrupt 27 pend +#define NVIC_PEND0_INT28 0x10000000 // Interrupt 28 pend +#define NVIC_PEND0_INT29 0x20000000 // Interrupt 29 pend +#define NVIC_PEND0_INT30 0x40000000 // Interrupt 30 pend +#define NVIC_PEND0_INT31 0x80000000 // Interrupt 31 pend + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PEND1 register. +// +//***************************************************************************** +#define NVIC_PEND1_INT_M 0xFFFFFFFF // Interrupt Set Pending + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PEND2 register. +// +//***************************************************************************** +#define NVIC_PEND2_INT_M 0xFFFFFFFF // Interrupt Set Pending + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PEND3 register. +// +//***************************************************************************** +#define NVIC_PEND3_INT_M 0xFFFFFFFF // Interrupt Set Pending + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PEND4 register. +// +//***************************************************************************** +#define NVIC_PEND4_INT_M 0x0000000F // Interrupt Set Pending + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_UNPEND0 register. +// +//***************************************************************************** +#define NVIC_UNPEND0_INT_M 0xFFFFFFFF // Interrupt Clear Pending +#define NVIC_UNPEND0_INT0 0x00000001 // Interrupt 0 unpend +#define NVIC_UNPEND0_INT1 0x00000002 // Interrupt 1 unpend +#define NVIC_UNPEND0_INT2 0x00000004 // Interrupt 2 unpend +#define NVIC_UNPEND0_INT3 0x00000008 // Interrupt 3 unpend +#define NVIC_UNPEND0_INT4 0x00000010 // Interrupt 4 unpend +#define NVIC_UNPEND0_INT5 0x00000020 // Interrupt 5 unpend +#define NVIC_UNPEND0_INT6 0x00000040 // Interrupt 6 unpend +#define NVIC_UNPEND0_INT7 0x00000080 // Interrupt 7 unpend +#define NVIC_UNPEND0_INT8 0x00000100 // Interrupt 8 unpend +#define NVIC_UNPEND0_INT9 0x00000200 // Interrupt 9 unpend +#define NVIC_UNPEND0_INT10 0x00000400 // Interrupt 10 unpend +#define NVIC_UNPEND0_INT11 0x00000800 // Interrupt 11 unpend +#define NVIC_UNPEND0_INT12 0x00001000 // Interrupt 12 unpend +#define NVIC_UNPEND0_INT13 0x00002000 // Interrupt 13 unpend +#define NVIC_UNPEND0_INT14 0x00004000 // Interrupt 14 unpend +#define NVIC_UNPEND0_INT15 0x00008000 // Interrupt 15 unpend +#define NVIC_UNPEND0_INT16 0x00010000 // Interrupt 16 unpend +#define NVIC_UNPEND0_INT17 0x00020000 // Interrupt 17 unpend +#define NVIC_UNPEND0_INT18 0x00040000 // Interrupt 18 unpend +#define NVIC_UNPEND0_INT19 0x00080000 // Interrupt 19 unpend +#define NVIC_UNPEND0_INT20 0x00100000 // Interrupt 20 unpend +#define NVIC_UNPEND0_INT21 0x00200000 // Interrupt 21 unpend +#define NVIC_UNPEND0_INT22 0x00400000 // Interrupt 22 unpend +#define NVIC_UNPEND0_INT23 0x00800000 // Interrupt 23 unpend +#define NVIC_UNPEND0_INT24 0x01000000 // Interrupt 24 unpend +#define NVIC_UNPEND0_INT25 0x02000000 // Interrupt 25 unpend +#define NVIC_UNPEND0_INT26 0x04000000 // Interrupt 26 unpend +#define NVIC_UNPEND0_INT27 0x08000000 // Interrupt 27 unpend +#define NVIC_UNPEND0_INT28 0x10000000 // Interrupt 28 unpend +#define NVIC_UNPEND0_INT29 0x20000000 // Interrupt 29 unpend +#define NVIC_UNPEND0_INT30 0x40000000 // Interrupt 30 unpend +#define NVIC_UNPEND0_INT31 0x80000000 // Interrupt 31 unpend + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_UNPEND1 register. +// +//***************************************************************************** +#define NVIC_UNPEND1_INT_M 0xFFFFFFFF // Interrupt Clear Pending + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_UNPEND2 register. +// +//***************************************************************************** +#define NVIC_UNPEND2_INT_M 0xFFFFFFFF // Interrupt Clear Pending + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_UNPEND3 register. +// +//***************************************************************************** +#define NVIC_UNPEND3_INT_M 0xFFFFFFFF // Interrupt Clear Pending + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_UNPEND4 register. +// +//***************************************************************************** +#define NVIC_UNPEND4_INT_M 0x0000000F // Interrupt Clear Pending + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ACTIVE0 register. +// +//***************************************************************************** +#define NVIC_ACTIVE0_INT_M 0xFFFFFFFF // Interrupt Active +#define NVIC_ACTIVE0_INT0 0x00000001 // Interrupt 0 active +#define NVIC_ACTIVE0_INT1 0x00000002 // Interrupt 1 active +#define NVIC_ACTIVE0_INT2 0x00000004 // Interrupt 2 active +#define NVIC_ACTIVE0_INT3 0x00000008 // Interrupt 3 active +#define NVIC_ACTIVE0_INT4 0x00000010 // Interrupt 4 active +#define NVIC_ACTIVE0_INT5 0x00000020 // Interrupt 5 active +#define NVIC_ACTIVE0_INT6 0x00000040 // Interrupt 6 active +#define NVIC_ACTIVE0_INT7 0x00000080 // Interrupt 7 active +#define NVIC_ACTIVE0_INT8 0x00000100 // Interrupt 8 active +#define NVIC_ACTIVE0_INT9 0x00000200 // Interrupt 9 active +#define NVIC_ACTIVE0_INT10 0x00000400 // Interrupt 10 active +#define NVIC_ACTIVE0_INT11 0x00000800 // Interrupt 11 active +#define NVIC_ACTIVE0_INT12 0x00001000 // Interrupt 12 active +#define NVIC_ACTIVE0_INT13 0x00002000 // Interrupt 13 active +#define NVIC_ACTIVE0_INT14 0x00004000 // Interrupt 14 active +#define NVIC_ACTIVE0_INT15 0x00008000 // Interrupt 15 active +#define NVIC_ACTIVE0_INT16 0x00010000 // Interrupt 16 active +#define NVIC_ACTIVE0_INT17 0x00020000 // Interrupt 17 active +#define NVIC_ACTIVE0_INT18 0x00040000 // Interrupt 18 active +#define NVIC_ACTIVE0_INT19 0x00080000 // Interrupt 19 active +#define NVIC_ACTIVE0_INT20 0x00100000 // Interrupt 20 active +#define NVIC_ACTIVE0_INT21 0x00200000 // Interrupt 21 active +#define NVIC_ACTIVE0_INT22 0x00400000 // Interrupt 22 active +#define NVIC_ACTIVE0_INT23 0x00800000 // Interrupt 23 active +#define NVIC_ACTIVE0_INT24 0x01000000 // Interrupt 24 active +#define NVIC_ACTIVE0_INT25 0x02000000 // Interrupt 25 active +#define NVIC_ACTIVE0_INT26 0x04000000 // Interrupt 26 active +#define NVIC_ACTIVE0_INT27 0x08000000 // Interrupt 27 active +#define NVIC_ACTIVE0_INT28 0x10000000 // Interrupt 28 active +#define NVIC_ACTIVE0_INT29 0x20000000 // Interrupt 29 active +#define NVIC_ACTIVE0_INT30 0x40000000 // Interrupt 30 active +#define NVIC_ACTIVE0_INT31 0x80000000 // Interrupt 31 active + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ACTIVE1 register. +// +//***************************************************************************** +#define NVIC_ACTIVE1_INT_M 0xFFFFFFFF // Interrupt Active + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ACTIVE2 register. +// +//***************************************************************************** +#define NVIC_ACTIVE2_INT_M 0xFFFFFFFF // Interrupt Active + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ACTIVE3 register. +// +//***************************************************************************** +#define NVIC_ACTIVE3_INT_M 0xFFFFFFFF // Interrupt Active + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_ACTIVE4 register. +// +//***************************************************************************** +#define NVIC_ACTIVE4_INT_M 0x0000000F // Interrupt Active + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI0 register. +// +//***************************************************************************** +#define NVIC_PRI0_INT3_M 0xE0000000 // Interrupt 3 Priority Mask +#define NVIC_PRI0_INT2_M 0x00E00000 // Interrupt 2 Priority Mask +#define NVIC_PRI0_INT1_M 0x0000E000 // Interrupt 1 Priority Mask +#define NVIC_PRI0_INT0_M 0x000000E0 // Interrupt 0 Priority Mask +#define NVIC_PRI0_INT3_S 29 +#define NVIC_PRI0_INT2_S 21 +#define NVIC_PRI0_INT1_S 13 +#define NVIC_PRI0_INT0_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI1 register. +// +//***************************************************************************** +#define NVIC_PRI1_INT7_M 0xE0000000 // Interrupt 7 Priority Mask +#define NVIC_PRI1_INT6_M 0x00E00000 // Interrupt 6 Priority Mask +#define NVIC_PRI1_INT5_M 0x0000E000 // Interrupt 5 Priority Mask +#define NVIC_PRI1_INT4_M 0x000000E0 // Interrupt 4 Priority Mask +#define NVIC_PRI1_INT7_S 29 +#define NVIC_PRI1_INT6_S 21 +#define NVIC_PRI1_INT5_S 13 +#define NVIC_PRI1_INT4_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI2 register. +// +//***************************************************************************** +#define NVIC_PRI2_INT11_M 0xE0000000 // Interrupt 11 Priority Mask +#define NVIC_PRI2_INT10_M 0x00E00000 // Interrupt 10 Priority Mask +#define NVIC_PRI2_INT9_M 0x0000E000 // Interrupt 9 Priority Mask +#define NVIC_PRI2_INT8_M 0x000000E0 // Interrupt 8 Priority Mask +#define NVIC_PRI2_INT11_S 29 +#define NVIC_PRI2_INT10_S 21 +#define NVIC_PRI2_INT9_S 13 +#define NVIC_PRI2_INT8_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI3 register. +// +//***************************************************************************** +#define NVIC_PRI3_INT15_M 0xE0000000 // Interrupt 15 Priority Mask +#define NVIC_PRI3_INT14_M 0x00E00000 // Interrupt 14 Priority Mask +#define NVIC_PRI3_INT13_M 0x0000E000 // Interrupt 13 Priority Mask +#define NVIC_PRI3_INT12_M 0x000000E0 // Interrupt 12 Priority Mask +#define NVIC_PRI3_INT15_S 29 +#define NVIC_PRI3_INT14_S 21 +#define NVIC_PRI3_INT13_S 13 +#define NVIC_PRI3_INT12_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI4 register. +// +//***************************************************************************** +#define NVIC_PRI4_INT19_M 0xE0000000 // Interrupt 19 Priority Mask +#define NVIC_PRI4_INT18_M 0x00E00000 // Interrupt 18 Priority Mask +#define NVIC_PRI4_INT17_M 0x0000E000 // Interrupt 17 Priority Mask +#define NVIC_PRI4_INT16_M 0x000000E0 // Interrupt 16 Priority Mask +#define NVIC_PRI4_INT19_S 29 +#define NVIC_PRI4_INT18_S 21 +#define NVIC_PRI4_INT17_S 13 +#define NVIC_PRI4_INT16_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI5 register. +// +//***************************************************************************** +#define NVIC_PRI5_INT23_M 0xE0000000 // Interrupt 23 Priority Mask +#define NVIC_PRI5_INT22_M 0x00E00000 // Interrupt 22 Priority Mask +#define NVIC_PRI5_INT21_M 0x0000E000 // Interrupt 21 Priority Mask +#define NVIC_PRI5_INT20_M 0x000000E0 // Interrupt 20 Priority Mask +#define NVIC_PRI5_INT23_S 29 +#define NVIC_PRI5_INT22_S 21 +#define NVIC_PRI5_INT21_S 13 +#define NVIC_PRI5_INT20_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI6 register. +// +//***************************************************************************** +#define NVIC_PRI6_INT27_M 0xE0000000 // Interrupt 27 Priority Mask +#define NVIC_PRI6_INT26_M 0x00E00000 // Interrupt 26 Priority Mask +#define NVIC_PRI6_INT25_M 0x0000E000 // Interrupt 25 Priority Mask +#define NVIC_PRI6_INT24_M 0x000000E0 // Interrupt 24 Priority Mask +#define NVIC_PRI6_INT27_S 29 +#define NVIC_PRI6_INT26_S 21 +#define NVIC_PRI6_INT25_S 13 +#define NVIC_PRI6_INT24_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI7 register. +// +//***************************************************************************** +#define NVIC_PRI7_INT31_M 0xE0000000 // Interrupt 31 Priority Mask +#define NVIC_PRI7_INT30_M 0x00E00000 // Interrupt 30 Priority Mask +#define NVIC_PRI7_INT29_M 0x0000E000 // Interrupt 29 Priority Mask +#define NVIC_PRI7_INT28_M 0x000000E0 // Interrupt 28 Priority Mask +#define NVIC_PRI7_INT31_S 29 +#define NVIC_PRI7_INT30_S 21 +#define NVIC_PRI7_INT29_S 13 +#define NVIC_PRI7_INT28_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI8 register. +// +//***************************************************************************** +#define NVIC_PRI8_INT35_M 0xE0000000 // Interrupt 35 Priority Mask +#define NVIC_PRI8_INT34_M 0x00E00000 // Interrupt 34 Priority Mask +#define NVIC_PRI8_INT33_M 0x0000E000 // Interrupt 33 Priority Mask +#define NVIC_PRI8_INT32_M 0x000000E0 // Interrupt 32 Priority Mask +#define NVIC_PRI8_INT35_S 29 +#define NVIC_PRI8_INT34_S 21 +#define NVIC_PRI8_INT33_S 13 +#define NVIC_PRI8_INT32_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI9 register. +// +//***************************************************************************** +#define NVIC_PRI9_INT39_M 0xE0000000 // Interrupt 39 Priority Mask +#define NVIC_PRI9_INT38_M 0x00E00000 // Interrupt 38 Priority Mask +#define NVIC_PRI9_INT37_M 0x0000E000 // Interrupt 37 Priority Mask +#define NVIC_PRI9_INT36_M 0x000000E0 // Interrupt 36 Priority Mask +#define NVIC_PRI9_INT39_S 29 +#define NVIC_PRI9_INT38_S 21 +#define NVIC_PRI9_INT37_S 13 +#define NVIC_PRI9_INT36_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI10 register. +// +//***************************************************************************** +#define NVIC_PRI10_INT43_M 0xE0000000 // Interrupt 43 Priority Mask +#define NVIC_PRI10_INT42_M 0x00E00000 // Interrupt 42 Priority Mask +#define NVIC_PRI10_INT41_M 0x0000E000 // Interrupt 41 Priority Mask +#define NVIC_PRI10_INT40_M 0x000000E0 // Interrupt 40 Priority Mask +#define NVIC_PRI10_INT43_S 29 +#define NVIC_PRI10_INT42_S 21 +#define NVIC_PRI10_INT41_S 13 +#define NVIC_PRI10_INT40_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI11 register. +// +//***************************************************************************** +#define NVIC_PRI11_INT47_M 0xE0000000 // Interrupt 47 Priority Mask +#define NVIC_PRI11_INT46_M 0x00E00000 // Interrupt 46 Priority Mask +#define NVIC_PRI11_INT45_M 0x0000E000 // Interrupt 45 Priority Mask +#define NVIC_PRI11_INT44_M 0x000000E0 // Interrupt 44 Priority Mask +#define NVIC_PRI11_INT47_S 29 +#define NVIC_PRI11_INT46_S 21 +#define NVIC_PRI11_INT45_S 13 +#define NVIC_PRI11_INT44_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI12 register. +// +//***************************************************************************** +#define NVIC_PRI12_INT51_M 0xE0000000 // Interrupt 51 Priority Mask +#define NVIC_PRI12_INT50_M 0x00E00000 // Interrupt 50 Priority Mask +#define NVIC_PRI12_INT49_M 0x0000E000 // Interrupt 49 Priority Mask +#define NVIC_PRI12_INT48_M 0x000000E0 // Interrupt 48 Priority Mask +#define NVIC_PRI12_INT51_S 29 +#define NVIC_PRI12_INT50_S 21 +#define NVIC_PRI12_INT49_S 13 +#define NVIC_PRI12_INT48_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI13 register. +// +//***************************************************************************** +#define NVIC_PRI13_INT55_M 0xE0000000 // Interrupt 55 Priority Mask +#define NVIC_PRI13_INT54_M 0x00E00000 // Interrupt 54 Priority Mask +#define NVIC_PRI13_INT53_M 0x0000E000 // Interrupt 53 Priority Mask +#define NVIC_PRI13_INT52_M 0x000000E0 // Interrupt 52 Priority Mask +#define NVIC_PRI13_INT55_S 29 +#define NVIC_PRI13_INT54_S 21 +#define NVIC_PRI13_INT53_S 13 +#define NVIC_PRI13_INT52_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI14 register. +// +//***************************************************************************** +#define NVIC_PRI14_INTD_M 0xE0000000 // Interrupt 59 Priority Mask +#define NVIC_PRI14_INTC_M 0x00E00000 // Interrupt 58 Priority Mask +#define NVIC_PRI14_INTB_M 0x0000E000 // Interrupt 57 Priority Mask +#define NVIC_PRI14_INTA_M 0x000000E0 // Interrupt 56 Priority Mask +#define NVIC_PRI14_INTD_S 29 +#define NVIC_PRI14_INTC_S 21 +#define NVIC_PRI14_INTB_S 13 +#define NVIC_PRI14_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI15 register. +// +//***************************************************************************** +#define NVIC_PRI15_INTD_M 0xE0000000 // Interrupt 63 Priority Mask +#define NVIC_PRI15_INTC_M 0x00E00000 // Interrupt 62 Priority Mask +#define NVIC_PRI15_INTB_M 0x0000E000 // Interrupt 61 Priority Mask +#define NVIC_PRI15_INTA_M 0x000000E0 // Interrupt 60 Priority Mask +#define NVIC_PRI15_INTD_S 29 +#define NVIC_PRI15_INTC_S 21 +#define NVIC_PRI15_INTB_S 13 +#define NVIC_PRI15_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI16 register. +// +//***************************************************************************** +#define NVIC_PRI16_INTD_M 0xE0000000 // Interrupt 67 Priority Mask +#define NVIC_PRI16_INTC_M 0x00E00000 // Interrupt 66 Priority Mask +#define NVIC_PRI16_INTB_M 0x0000E000 // Interrupt 65 Priority Mask +#define NVIC_PRI16_INTA_M 0x000000E0 // Interrupt 64 Priority Mask +#define NVIC_PRI16_INTD_S 29 +#define NVIC_PRI16_INTC_S 21 +#define NVIC_PRI16_INTB_S 13 +#define NVIC_PRI16_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI17 register. +// +//***************************************************************************** +#define NVIC_PRI17_INTD_M 0xE0000000 // Interrupt 71 Priority Mask +#define NVIC_PRI17_INTC_M 0x00E00000 // Interrupt 70 Priority Mask +#define NVIC_PRI17_INTB_M 0x0000E000 // Interrupt 69 Priority Mask +#define NVIC_PRI17_INTA_M 0x000000E0 // Interrupt 68 Priority Mask +#define NVIC_PRI17_INTD_S 29 +#define NVIC_PRI17_INTC_S 21 +#define NVIC_PRI17_INTB_S 13 +#define NVIC_PRI17_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI18 register. +// +//***************************************************************************** +#define NVIC_PRI18_INTD_M 0xE0000000 // Interrupt 75 Priority Mask +#define NVIC_PRI18_INTC_M 0x00E00000 // Interrupt 74 Priority Mask +#define NVIC_PRI18_INTB_M 0x0000E000 // Interrupt 73 Priority Mask +#define NVIC_PRI18_INTA_M 0x000000E0 // Interrupt 72 Priority Mask +#define NVIC_PRI18_INTD_S 29 +#define NVIC_PRI18_INTC_S 21 +#define NVIC_PRI18_INTB_S 13 +#define NVIC_PRI18_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI19 register. +// +//***************************************************************************** +#define NVIC_PRI19_INTD_M 0xE0000000 // Interrupt 79 Priority Mask +#define NVIC_PRI19_INTC_M 0x00E00000 // Interrupt 78 Priority Mask +#define NVIC_PRI19_INTB_M 0x0000E000 // Interrupt 77 Priority Mask +#define NVIC_PRI19_INTA_M 0x000000E0 // Interrupt 76 Priority Mask +#define NVIC_PRI19_INTD_S 29 +#define NVIC_PRI19_INTC_S 21 +#define NVIC_PRI19_INTB_S 13 +#define NVIC_PRI19_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI20 register. +// +//***************************************************************************** +#define NVIC_PRI20_INTD_M 0xE0000000 // Interrupt 83 Priority Mask +#define NVIC_PRI20_INTC_M 0x00E00000 // Interrupt 82 Priority Mask +#define NVIC_PRI20_INTB_M 0x0000E000 // Interrupt 81 Priority Mask +#define NVIC_PRI20_INTA_M 0x000000E0 // Interrupt 80 Priority Mask +#define NVIC_PRI20_INTD_S 29 +#define NVIC_PRI20_INTC_S 21 +#define NVIC_PRI20_INTB_S 13 +#define NVIC_PRI20_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI21 register. +// +//***************************************************************************** +#define NVIC_PRI21_INTD_M 0xE0000000 // Interrupt 87 Priority Mask +#define NVIC_PRI21_INTC_M 0x00E00000 // Interrupt 86 Priority Mask +#define NVIC_PRI21_INTB_M 0x0000E000 // Interrupt 85 Priority Mask +#define NVIC_PRI21_INTA_M 0x000000E0 // Interrupt 84 Priority Mask +#define NVIC_PRI21_INTD_S 29 +#define NVIC_PRI21_INTC_S 21 +#define NVIC_PRI21_INTB_S 13 +#define NVIC_PRI21_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI22 register. +// +//***************************************************************************** +#define NVIC_PRI22_INTD_M 0xE0000000 // Interrupt 91 Priority Mask +#define NVIC_PRI22_INTC_M 0x00E00000 // Interrupt 90 Priority Mask +#define NVIC_PRI22_INTB_M 0x0000E000 // Interrupt 89 Priority Mask +#define NVIC_PRI22_INTA_M 0x000000E0 // Interrupt 88 Priority Mask +#define NVIC_PRI22_INTD_S 29 +#define NVIC_PRI22_INTC_S 21 +#define NVIC_PRI22_INTB_S 13 +#define NVIC_PRI22_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI23 register. +// +//***************************************************************************** +#define NVIC_PRI23_INTD_M 0xE0000000 // Interrupt 95 Priority Mask +#define NVIC_PRI23_INTC_M 0x00E00000 // Interrupt 94 Priority Mask +#define NVIC_PRI23_INTB_M 0x0000E000 // Interrupt 93 Priority Mask +#define NVIC_PRI23_INTA_M 0x000000E0 // Interrupt 92 Priority Mask +#define NVIC_PRI23_INTD_S 29 +#define NVIC_PRI23_INTC_S 21 +#define NVIC_PRI23_INTB_S 13 +#define NVIC_PRI23_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI24 register. +// +//***************************************************************************** +#define NVIC_PRI24_INTD_M 0xE0000000 // Interrupt 99 Priority Mask +#define NVIC_PRI24_INTC_M 0x00E00000 // Interrupt 98 Priority Mask +#define NVIC_PRI24_INTB_M 0x0000E000 // Interrupt 97 Priority Mask +#define NVIC_PRI24_INTA_M 0x000000E0 // Interrupt 96 Priority Mask +#define NVIC_PRI24_INTD_S 29 +#define NVIC_PRI24_INTC_S 21 +#define NVIC_PRI24_INTB_S 13 +#define NVIC_PRI24_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI25 register. +// +//***************************************************************************** +#define NVIC_PRI25_INTD_M 0xE0000000 // Interrupt 103 Priority Mask +#define NVIC_PRI25_INTC_M 0x00E00000 // Interrupt 102 Priority Mask +#define NVIC_PRI25_INTB_M 0x0000E000 // Interrupt 101 Priority Mask +#define NVIC_PRI25_INTA_M 0x000000E0 // Interrupt 100 Priority Mask +#define NVIC_PRI25_INTD_S 29 +#define NVIC_PRI25_INTC_S 21 +#define NVIC_PRI25_INTB_S 13 +#define NVIC_PRI25_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI26 register. +// +//***************************************************************************** +#define NVIC_PRI26_INTD_M 0xE0000000 // Interrupt 107 Priority Mask +#define NVIC_PRI26_INTC_M 0x00E00000 // Interrupt 106 Priority Mask +#define NVIC_PRI26_INTB_M 0x0000E000 // Interrupt 105 Priority Mask +#define NVIC_PRI26_INTA_M 0x000000E0 // Interrupt 104 Priority Mask +#define NVIC_PRI26_INTD_S 29 +#define NVIC_PRI26_INTC_S 21 +#define NVIC_PRI26_INTB_S 13 +#define NVIC_PRI26_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI27 register. +// +//***************************************************************************** +#define NVIC_PRI27_INTD_M 0xE0000000 // Interrupt 111 Priority Mask +#define NVIC_PRI27_INTC_M 0x00E00000 // Interrupt 110 Priority Mask +#define NVIC_PRI27_INTB_M 0x0000E000 // Interrupt 109 Priority Mask +#define NVIC_PRI27_INTA_M 0x000000E0 // Interrupt 108 Priority Mask +#define NVIC_PRI27_INTD_S 29 +#define NVIC_PRI27_INTC_S 21 +#define NVIC_PRI27_INTB_S 13 +#define NVIC_PRI27_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI28 register. +// +//***************************************************************************** +#define NVIC_PRI28_INTD_M 0xE0000000 // Interrupt 115 Priority Mask +#define NVIC_PRI28_INTC_M 0x00E00000 // Interrupt 114 Priority Mask +#define NVIC_PRI28_INTB_M 0x0000E000 // Interrupt 113 Priority Mask +#define NVIC_PRI28_INTA_M 0x000000E0 // Interrupt 112 Priority Mask +#define NVIC_PRI28_INTD_S 29 +#define NVIC_PRI28_INTC_S 21 +#define NVIC_PRI28_INTB_S 13 +#define NVIC_PRI28_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI29 register. +// +//***************************************************************************** +#define NVIC_PRI29_INTD_M 0xE0000000 // Interrupt 119 Priority Mask +#define NVIC_PRI29_INTC_M 0x00E00000 // Interrupt 118 Priority Mask +#define NVIC_PRI29_INTB_M 0x0000E000 // Interrupt 117 Priority Mask +#define NVIC_PRI29_INTA_M 0x000000E0 // Interrupt 116 Priority Mask +#define NVIC_PRI29_INTD_S 29 +#define NVIC_PRI29_INTC_S 21 +#define NVIC_PRI29_INTB_S 13 +#define NVIC_PRI29_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI30 register. +// +//***************************************************************************** +#define NVIC_PRI30_INTD_M 0xE0000000 // Interrupt 123 Priority Mask +#define NVIC_PRI30_INTC_M 0x00E00000 // Interrupt 122 Priority Mask +#define NVIC_PRI30_INTB_M 0x0000E000 // Interrupt 121 Priority Mask +#define NVIC_PRI30_INTA_M 0x000000E0 // Interrupt 120 Priority Mask +#define NVIC_PRI30_INTD_S 29 +#define NVIC_PRI30_INTC_S 21 +#define NVIC_PRI30_INTB_S 13 +#define NVIC_PRI30_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI31 register. +// +//***************************************************************************** +#define NVIC_PRI31_INTD_M 0xE0000000 // Interrupt 127 Priority Mask +#define NVIC_PRI31_INTC_M 0x00E00000 // Interrupt 126 Priority Mask +#define NVIC_PRI31_INTB_M 0x0000E000 // Interrupt 125 Priority Mask +#define NVIC_PRI31_INTA_M 0x000000E0 // Interrupt 124 Priority Mask +#define NVIC_PRI31_INTD_S 29 +#define NVIC_PRI31_INTC_S 21 +#define NVIC_PRI31_INTB_S 13 +#define NVIC_PRI31_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI32 register. +// +//***************************************************************************** +#define NVIC_PRI32_INTD_M 0xE0000000 // Interrupt 131 Priority Mask +#define NVIC_PRI32_INTC_M 0x00E00000 // Interrupt 130 Priority Mask +#define NVIC_PRI32_INTB_M 0x0000E000 // Interrupt 129 Priority Mask +#define NVIC_PRI32_INTA_M 0x000000E0 // Interrupt 128 Priority Mask +#define NVIC_PRI32_INTD_S 29 +#define NVIC_PRI32_INTC_S 21 +#define NVIC_PRI32_INTB_S 13 +#define NVIC_PRI32_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI33 register. +// +//***************************************************************************** +#define NVIC_PRI33_INTD_M 0xE0000000 // Interrupt 135 Priority Mask +#define NVIC_PRI33_INTC_M 0x00E00000 // Interrupt 134 Priority Mask +#define NVIC_PRI33_INTB_M 0x0000E000 // Interrupt 133 Priority Mask +#define NVIC_PRI33_INTA_M 0x000000E0 // Interrupt 132 Priority Mask +#define NVIC_PRI33_INTD_S 29 +#define NVIC_PRI33_INTC_S 21 +#define NVIC_PRI33_INTB_S 13 +#define NVIC_PRI33_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI34 register. +// +//***************************************************************************** +#define NVIC_PRI34_INTD_M 0xE0000000 // Interrupt 139 Priority Mask +#define NVIC_PRI34_INTC_M 0x00E00000 // Interrupt 138 Priority Mask +#define NVIC_PRI34_INTB_M 0x0000E000 // Interrupt 137 Priority Mask +#define NVIC_PRI34_INTA_M 0x000000E0 // Interrupt 136 Priority Mask +#define NVIC_PRI34_INTD_S 29 +#define NVIC_PRI34_INTC_S 21 +#define NVIC_PRI34_INTB_S 13 +#define NVIC_PRI34_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI35 register. +// +//***************************************************************************** +#define NVIC_PRI35_INTD_M 0xE0000000 // Interrupt 143 Priority Mask +#define NVIC_PRI35_INTC_M 0x00E00000 // Interrupt 142 Priority Mask +#define NVIC_PRI35_INTB_M 0x0000E000 // Interrupt 141 Priority Mask +#define NVIC_PRI35_INTA_M 0x000000E0 // Interrupt 140 Priority Mask +#define NVIC_PRI35_INTD_S 29 +#define NVIC_PRI35_INTC_S 21 +#define NVIC_PRI35_INTB_S 13 +#define NVIC_PRI35_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_PRI36 register. +// +//***************************************************************************** +#define NVIC_PRI36_INTD_M 0xE0000000 // Interrupt 147 Priority Mask +#define NVIC_PRI36_INTC_M 0x00E00000 // Interrupt 146 Priority Mask +#define NVIC_PRI36_INTB_M 0x0000E000 // Interrupt 145 Priority Mask +#define NVIC_PRI36_INTA_M 0x000000E0 // Interrupt 144 Priority Mask +#define NVIC_PRI36_INTD_S 29 +#define NVIC_PRI36_INTC_S 21 +#define NVIC_PRI36_INTB_S 13 +#define NVIC_PRI36_INTA_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_CPUID register. +// +//***************************************************************************** +#define NVIC_CPUID_IMP_M 0xFF000000 // Implementer Code +#define NVIC_CPUID_IMP_ARM 0x41000000 // ARM +#define NVIC_CPUID_VAR_M 0x00F00000 // Variant Number +#define NVIC_CPUID_CON_M 0x000F0000 // Constant +#define NVIC_CPUID_PARTNO_M 0x0000FFF0 // Part Number +#define NVIC_CPUID_PARTNO_CM3 0x0000C230 // Cortex-M3 processor +#define NVIC_CPUID_PARTNO_CM4 0x0000C240 // Cortex-M4 processor +#define NVIC_CPUID_REV_M 0x0000000F // Revision Number + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_INT_CTRL register. +// +//***************************************************************************** +#define NVIC_INT_CTRL_NMI_SET 0x80000000 // NMI Set Pending +#define NVIC_INT_CTRL_PEND_SV 0x10000000 // PendSV Set Pending +#define NVIC_INT_CTRL_UNPEND_SV 0x08000000 // PendSV Clear Pending +#define NVIC_INT_CTRL_PENDSTSET 0x04000000 // SysTick Set Pending +#define NVIC_INT_CTRL_PENDSTCLR 0x02000000 // SysTick Clear Pending +#define NVIC_INT_CTRL_ISR_PRE 0x00800000 // Debug Interrupt Handling +#define NVIC_INT_CTRL_ISR_PEND 0x00400000 // Interrupt Pending +#define NVIC_INT_CTRL_VEC_PEN_M 0x0007F000 // Interrupt Pending Vector Number +#undef NVIC_INT_CTRL_VEC_PEN_M +#define NVIC_INT_CTRL_VEC_PEN_M 0x000FF000 // Interrupt Pending Vector Number +#define NVIC_INT_CTRL_VEC_PEN_NMI \ + 0x00002000 // NMI +#define NVIC_INT_CTRL_VEC_PEN_HARD \ + 0x00003000 // Hard fault +#define NVIC_INT_CTRL_VEC_PEN_MEM \ + 0x00004000 // Memory management fault +#define NVIC_INT_CTRL_VEC_PEN_BUS \ + 0x00005000 // Bus fault +#define NVIC_INT_CTRL_VEC_PEN_USG \ + 0x00006000 // Usage fault +#define NVIC_INT_CTRL_VEC_PEN_SVC \ + 0x0000B000 // SVCall +#define NVIC_INT_CTRL_VEC_PEN_PNDSV \ + 0x0000E000 // PendSV +#define NVIC_INT_CTRL_VEC_PEN_TICK \ + 0x0000F000 // SysTick +#define NVIC_INT_CTRL_RET_BASE 0x00000800 // Return to Base +#define NVIC_INT_CTRL_VEC_ACT_M 0x0000007F // Interrupt Pending Vector Number +#undef NVIC_INT_CTRL_VEC_ACT_M +#define NVIC_INT_CTRL_VEC_ACT_M 0x000000FF // Interrupt Pending Vector Number +#define NVIC_INT_CTRL_VEC_PEN_S 12 +#define NVIC_INT_CTRL_VEC_ACT_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_VTABLE register. +// +//***************************************************************************** +#define NVIC_VTABLE_BASE 0x20000000 // Vector Table Base +#define NVIC_VTABLE_OFFSET_M 0x1FFFFE00 // Vector Table Offset +#undef NVIC_VTABLE_OFFSET_M +#define NVIC_VTABLE_OFFSET_M 0x1FFFFC00 // Vector Table Offset +#define NVIC_VTABLE_OFFSET_S 9 +#undef NVIC_VTABLE_OFFSET_S +#define NVIC_VTABLE_OFFSET_S 10 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_APINT register. +// +//***************************************************************************** +#define NVIC_APINT_VECTKEY_M 0xFFFF0000 // Register Key +#define NVIC_APINT_VECTKEY 0x05FA0000 // Vector key +#define NVIC_APINT_ENDIANESS 0x00008000 // Data Endianess +#define NVIC_APINT_PRIGROUP_M 0x00000700 // Interrupt Priority Grouping +#define NVIC_APINT_PRIGROUP_7_1 0x00000000 // Priority group 7.1 split +#define NVIC_APINT_PRIGROUP_6_2 0x00000100 // Priority group 6.2 split +#define NVIC_APINT_PRIGROUP_5_3 0x00000200 // Priority group 5.3 split +#define NVIC_APINT_PRIGROUP_4_4 0x00000300 // Priority group 4.4 split +#define NVIC_APINT_PRIGROUP_3_5 0x00000400 // Priority group 3.5 split +#define NVIC_APINT_PRIGROUP_2_6 0x00000500 // Priority group 2.6 split +#define NVIC_APINT_PRIGROUP_1_7 0x00000600 // Priority group 1.7 split +#define NVIC_APINT_PRIGROUP_0_8 0x00000700 // Priority group 0.8 split +#define NVIC_APINT_SYSRESETREQ 0x00000004 // System Reset Request +#define NVIC_APINT_VECT_CLR_ACT 0x00000002 // Clear Active NMI / Fault +#define NVIC_APINT_VECT_RESET 0x00000001 // System Reset + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_SYS_CTRL register. +// +//***************************************************************************** +#define NVIC_SYS_CTRL_SEVONPEND 0x00000010 // Wake Up on Pending +#define NVIC_SYS_CTRL_SLEEPDEEP 0x00000004 // Deep Sleep Enable +#define NVIC_SYS_CTRL_SLEEPEXIT 0x00000002 // Sleep on ISR Exit + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_CFG_CTRL register. +// +//***************************************************************************** +#define NVIC_CFG_CTRL_STKALIGN 0x00000200 // Stack Alignment on Exception + // Entry +#define NVIC_CFG_CTRL_BFHFNMIGN 0x00000100 // Ignore Bus Fault in NMI and + // Fault +#define NVIC_CFG_CTRL_DIV0 0x00000010 // Trap on Divide by 0 +#define NVIC_CFG_CTRL_UNALIGNED 0x00000008 // Trap on Unaligned Access +#define NVIC_CFG_CTRL_MAIN_PEND 0x00000002 // Allow Main Interrupt Trigger +#define NVIC_CFG_CTRL_BASE_THR 0x00000001 // Thread State Control + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_SYS_PRI1 register. +// +//***************************************************************************** +#define NVIC_SYS_PRI1_USAGE_M 0x00E00000 // Usage Fault Priority +#define NVIC_SYS_PRI1_BUS_M 0x0000E000 // Bus Fault Priority +#define NVIC_SYS_PRI1_MEM_M 0x000000E0 // Memory Management Fault Priority +#define NVIC_SYS_PRI1_USAGE_S 21 +#define NVIC_SYS_PRI1_BUS_S 13 +#define NVIC_SYS_PRI1_MEM_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_SYS_PRI2 register. +// +//***************************************************************************** +#define NVIC_SYS_PRI2_SVC_M 0xE0000000 // SVCall Priority +#define NVIC_SYS_PRI2_SVC_S 29 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_SYS_PRI3 register. +// +//***************************************************************************** +#define NVIC_SYS_PRI3_TICK_M 0xE0000000 // SysTick Exception Priority +#define NVIC_SYS_PRI3_PENDSV_M 0x00E00000 // PendSV Priority +#define NVIC_SYS_PRI3_DEBUG_M 0x000000E0 // Debug Priority +#define NVIC_SYS_PRI3_TICK_S 29 +#define NVIC_SYS_PRI3_PENDSV_S 21 +#define NVIC_SYS_PRI3_DEBUG_S 5 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_SYS_HND_CTRL +// register. +// +//***************************************************************************** +#define NVIC_SYS_HND_CTRL_USAGE 0x00040000 // Usage Fault Enable +#define NVIC_SYS_HND_CTRL_BUS 0x00020000 // Bus Fault Enable +#define NVIC_SYS_HND_CTRL_MEM 0x00010000 // Memory Management Fault Enable +#define NVIC_SYS_HND_CTRL_SVC 0x00008000 // SVC Call Pending +#define NVIC_SYS_HND_CTRL_BUSP 0x00004000 // Bus Fault Pending +#define NVIC_SYS_HND_CTRL_MEMP 0x00002000 // Memory Management Fault Pending +#define NVIC_SYS_HND_CTRL_USAGEP \ + 0x00001000 // Usage Fault Pending +#define NVIC_SYS_HND_CTRL_TICK 0x00000800 // SysTick Exception Active +#define NVIC_SYS_HND_CTRL_PNDSV 0x00000400 // PendSV Exception Active +#define NVIC_SYS_HND_CTRL_MON 0x00000100 // Debug Monitor Active +#define NVIC_SYS_HND_CTRL_SVCA 0x00000080 // SVC Call Active +#define NVIC_SYS_HND_CTRL_USGA 0x00000008 // Usage Fault Active +#define NVIC_SYS_HND_CTRL_BUSA 0x00000002 // Bus Fault Active +#define NVIC_SYS_HND_CTRL_MEMA 0x00000001 // Memory Management Fault Active + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_FAULT_STAT +// register. +// +//***************************************************************************** +#define NVIC_FAULT_STAT_DIV0 0x02000000 // Divide-by-Zero Usage Fault +#define NVIC_FAULT_STAT_UNALIGN 0x01000000 // Unaligned Access Usage Fault +#define NVIC_FAULT_STAT_NOCP 0x00080000 // No Coprocessor Usage Fault +#define NVIC_FAULT_STAT_INVPC 0x00040000 // Invalid PC Load Usage Fault +#define NVIC_FAULT_STAT_INVSTAT 0x00020000 // Invalid State Usage Fault +#define NVIC_FAULT_STAT_UNDEF 0x00010000 // Undefined Instruction Usage + // Fault +#define NVIC_FAULT_STAT_BFARV 0x00008000 // Bus Fault Address Register Valid +#define NVIC_FAULT_STAT_BLSPERR 0x00002000 // Bus Fault on Floating-Point Lazy + // State Preservation +#define NVIC_FAULT_STAT_BSTKE 0x00001000 // Stack Bus Fault +#define NVIC_FAULT_STAT_BUSTKE 0x00000800 // Unstack Bus Fault +#define NVIC_FAULT_STAT_IMPRE 0x00000400 // Imprecise Data Bus Error +#define NVIC_FAULT_STAT_PRECISE 0x00000200 // Precise Data Bus Error +#define NVIC_FAULT_STAT_IBUS 0x00000100 // Instruction Bus Error +#define NVIC_FAULT_STAT_MMARV 0x00000080 // Memory Management Fault Address + // Register Valid +#define NVIC_FAULT_STAT_MLSPERR 0x00000020 // Memory Management Fault on + // Floating-Point Lazy State + // Preservation +#define NVIC_FAULT_STAT_MSTKE 0x00000010 // Stack Access Violation +#define NVIC_FAULT_STAT_MUSTKE 0x00000008 // Unstack Access Violation +#define NVIC_FAULT_STAT_DERR 0x00000002 // Data Access Violation +#define NVIC_FAULT_STAT_IERR 0x00000001 // Instruction Access Violation + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_HFAULT_STAT +// register. +// +//***************************************************************************** +#define NVIC_HFAULT_STAT_DBG 0x80000000 // Debug Event +#define NVIC_HFAULT_STAT_FORCED 0x40000000 // Forced Hard Fault +#define NVIC_HFAULT_STAT_VECT 0x00000002 // Vector Table Read Fault + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DEBUG_STAT +// register. +// +//***************************************************************************** +#define NVIC_DEBUG_STAT_EXTRNL 0x00000010 // EDBGRQ asserted +#define NVIC_DEBUG_STAT_VCATCH 0x00000008 // Vector catch +#define NVIC_DEBUG_STAT_DWTTRAP 0x00000004 // DWT match +#define NVIC_DEBUG_STAT_BKPT 0x00000002 // Breakpoint instruction +#define NVIC_DEBUG_STAT_HALTED 0x00000001 // Halt request + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MM_ADDR register. +// +//***************************************************************************** +#define NVIC_MM_ADDR_M 0xFFFFFFFF // Fault Address +#define NVIC_MM_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_FAULT_ADDR +// register. +// +//***************************************************************************** +#define NVIC_FAULT_ADDR_M 0xFFFFFFFF // Fault Address +#define NVIC_FAULT_ADDR_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_TYPE register. +// +//***************************************************************************** +#define NVIC_MPU_TYPE_IREGION_M 0x00FF0000 // Number of I Regions +#define NVIC_MPU_TYPE_DREGION_M 0x0000FF00 // Number of D Regions +#define NVIC_MPU_TYPE_SEPARATE 0x00000001 // Separate or Unified MPU +#define NVIC_MPU_TYPE_IREGION_S 16 +#define NVIC_MPU_TYPE_DREGION_S 8 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_CTRL register. +// +//***************************************************************************** +#define NVIC_MPU_CTRL_PRIVDEFEN 0x00000004 // MPU Default Region +#define NVIC_MPU_CTRL_HFNMIENA 0x00000002 // MPU Enabled During Faults +#define NVIC_MPU_CTRL_ENABLE 0x00000001 // MPU Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_NUMBER +// register. +// +//***************************************************************************** +#define NVIC_MPU_NUMBER_M 0x00000007 // MPU Region to Access +#define NVIC_MPU_NUMBER_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_BASE register. +// +//***************************************************************************** +#define NVIC_MPU_BASE_ADDR_M 0xFFFFFFE0 // Base Address Mask +#define NVIC_MPU_BASE_VALID 0x00000010 // Region Number Valid +#define NVIC_MPU_BASE_REGION_M 0x00000007 // Region Number +#define NVIC_MPU_BASE_ADDR_S 5 +#define NVIC_MPU_BASE_REGION_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_ATTR register. +// +//***************************************************************************** +#define NVIC_MPU_ATTR_M 0xFFFF0000 // Attributes +#define NVIC_MPU_ATTR_XN 0x10000000 // Instruction Access Disable +#define NVIC_MPU_ATTR_AP_M 0x07000000 // Access Privilege +#define NVIC_MPU_ATTR_AP_NO_NO 0x00000000 // prv: no access, usr: no access +#define NVIC_MPU_ATTR_AP_RW_NO 0x01000000 // prv: rw, usr: none +#define NVIC_MPU_ATTR_AP_RW_RO 0x02000000 // prv: rw, usr: read-only +#define NVIC_MPU_ATTR_AP_RW_RW 0x03000000 // prv: rw, usr: rw +#define NVIC_MPU_ATTR_AP_RO_NO 0x05000000 // prv: ro, usr: none +#define NVIC_MPU_ATTR_AP_RO_RO 0x06000000 // prv: ro, usr: ro +#define NVIC_MPU_ATTR_TEX_M 0x00380000 // Type Extension Mask +#define NVIC_MPU_ATTR_SHAREABLE 0x00040000 // Shareable +#define NVIC_MPU_ATTR_CACHEABLE 0x00020000 // Cacheable +#define NVIC_MPU_ATTR_BUFFRABLE 0x00010000 // Bufferable +#define NVIC_MPU_ATTR_SRD_M 0x0000FF00 // Subregion Disable Bits +#define NVIC_MPU_ATTR_SRD_0 0x00000100 // Sub-region 0 disable +#define NVIC_MPU_ATTR_SRD_1 0x00000200 // Sub-region 1 disable +#define NVIC_MPU_ATTR_SRD_2 0x00000400 // Sub-region 2 disable +#define NVIC_MPU_ATTR_SRD_3 0x00000800 // Sub-region 3 disable +#define NVIC_MPU_ATTR_SRD_4 0x00001000 // Sub-region 4 disable +#define NVIC_MPU_ATTR_SRD_5 0x00002000 // Sub-region 5 disable +#define NVIC_MPU_ATTR_SRD_6 0x00004000 // Sub-region 6 disable +#define NVIC_MPU_ATTR_SRD_7 0x00008000 // Sub-region 7 disable +#define NVIC_MPU_ATTR_SIZE_M 0x0000003E // Region Size Mask +#define NVIC_MPU_ATTR_SIZE_32B 0x00000008 // Region size 32 bytes +#define NVIC_MPU_ATTR_SIZE_64B 0x0000000A // Region size 64 bytes +#define NVIC_MPU_ATTR_SIZE_128B 0x0000000C // Region size 128 bytes +#define NVIC_MPU_ATTR_SIZE_256B 0x0000000E // Region size 256 bytes +#define NVIC_MPU_ATTR_SIZE_512B 0x00000010 // Region size 512 bytes +#define NVIC_MPU_ATTR_SIZE_1K 0x00000012 // Region size 1 Kbytes +#define NVIC_MPU_ATTR_SIZE_2K 0x00000014 // Region size 2 Kbytes +#define NVIC_MPU_ATTR_SIZE_4K 0x00000016 // Region size 4 Kbytes +#define NVIC_MPU_ATTR_SIZE_8K 0x00000018 // Region size 8 Kbytes +#define NVIC_MPU_ATTR_SIZE_16K 0x0000001A // Region size 16 Kbytes +#define NVIC_MPU_ATTR_SIZE_32K 0x0000001C // Region size 32 Kbytes +#define NVIC_MPU_ATTR_SIZE_64K 0x0000001E // Region size 64 Kbytes +#define NVIC_MPU_ATTR_SIZE_128K 0x00000020 // Region size 128 Kbytes +#define NVIC_MPU_ATTR_SIZE_256K 0x00000022 // Region size 256 Kbytes +#define NVIC_MPU_ATTR_SIZE_512K 0x00000024 // Region size 512 Kbytes +#define NVIC_MPU_ATTR_SIZE_1M 0x00000026 // Region size 1 Mbytes +#define NVIC_MPU_ATTR_SIZE_2M 0x00000028 // Region size 2 Mbytes +#define NVIC_MPU_ATTR_SIZE_4M 0x0000002A // Region size 4 Mbytes +#define NVIC_MPU_ATTR_SIZE_8M 0x0000002C // Region size 8 Mbytes +#define NVIC_MPU_ATTR_SIZE_16M 0x0000002E // Region size 16 Mbytes +#define NVIC_MPU_ATTR_SIZE_32M 0x00000030 // Region size 32 Mbytes +#define NVIC_MPU_ATTR_SIZE_64M 0x00000032 // Region size 64 Mbytes +#define NVIC_MPU_ATTR_SIZE_128M 0x00000034 // Region size 128 Mbytes +#define NVIC_MPU_ATTR_SIZE_256M 0x00000036 // Region size 256 Mbytes +#define NVIC_MPU_ATTR_SIZE_512M 0x00000038 // Region size 512 Mbytes +#define NVIC_MPU_ATTR_SIZE_1G 0x0000003A // Region size 1 Gbytes +#define NVIC_MPU_ATTR_SIZE_2G 0x0000003C // Region size 2 Gbytes +#define NVIC_MPU_ATTR_SIZE_4G 0x0000003E // Region size 4 Gbytes +#define NVIC_MPU_ATTR_ENABLE 0x00000001 // Region Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_BASE1 register. +// +//***************************************************************************** +#define NVIC_MPU_BASE1_ADDR_M 0xFFFFFFE0 // Base Address Mask +#define NVIC_MPU_BASE1_VALID 0x00000010 // Region Number Valid +#define NVIC_MPU_BASE1_REGION_M 0x00000007 // Region Number +#define NVIC_MPU_BASE1_ADDR_S 5 +#define NVIC_MPU_BASE1_REGION_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_ATTR1 register. +// +//***************************************************************************** +#define NVIC_MPU_ATTR1_XN 0x10000000 // Instruction Access Disable +#define NVIC_MPU_ATTR1_AP_M 0x07000000 // Access Privilege +#define NVIC_MPU_ATTR1_TEX_M 0x00380000 // Type Extension Mask +#define NVIC_MPU_ATTR1_SHAREABLE \ + 0x00040000 // Shareable +#define NVIC_MPU_ATTR1_CACHEABLE \ + 0x00020000 // Cacheable +#define NVIC_MPU_ATTR1_BUFFRABLE \ + 0x00010000 // Bufferable +#define NVIC_MPU_ATTR1_SRD_M 0x0000FF00 // Subregion Disable Bits +#define NVIC_MPU_ATTR1_SIZE_M 0x0000003E // Region Size Mask +#define NVIC_MPU_ATTR1_ENABLE 0x00000001 // Region Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_BASE2 register. +// +//***************************************************************************** +#define NVIC_MPU_BASE2_ADDR_M 0xFFFFFFE0 // Base Address Mask +#define NVIC_MPU_BASE2_VALID 0x00000010 // Region Number Valid +#define NVIC_MPU_BASE2_REGION_M 0x00000007 // Region Number +#define NVIC_MPU_BASE2_ADDR_S 5 +#define NVIC_MPU_BASE2_REGION_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_ATTR2 register. +// +//***************************************************************************** +#define NVIC_MPU_ATTR2_XN 0x10000000 // Instruction Access Disable +#define NVIC_MPU_ATTR2_AP_M 0x07000000 // Access Privilege +#define NVIC_MPU_ATTR2_TEX_M 0x00380000 // Type Extension Mask +#define NVIC_MPU_ATTR2_SHAREABLE \ + 0x00040000 // Shareable +#define NVIC_MPU_ATTR2_CACHEABLE \ + 0x00020000 // Cacheable +#define NVIC_MPU_ATTR2_BUFFRABLE \ + 0x00010000 // Bufferable +#define NVIC_MPU_ATTR2_SRD_M 0x0000FF00 // Subregion Disable Bits +#define NVIC_MPU_ATTR2_SIZE_M 0x0000003E // Region Size Mask +#define NVIC_MPU_ATTR2_ENABLE 0x00000001 // Region Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_BASE3 register. +// +//***************************************************************************** +#define NVIC_MPU_BASE3_ADDR_M 0xFFFFFFE0 // Base Address Mask +#define NVIC_MPU_BASE3_VALID 0x00000010 // Region Number Valid +#define NVIC_MPU_BASE3_REGION_M 0x00000007 // Region Number +#define NVIC_MPU_BASE3_ADDR_S 5 +#define NVIC_MPU_BASE3_REGION_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_MPU_ATTR3 register. +// +//***************************************************************************** +#define NVIC_MPU_ATTR3_XN 0x10000000 // Instruction Access Disable +#define NVIC_MPU_ATTR3_AP_M 0x07000000 // Access Privilege +#define NVIC_MPU_ATTR3_TEX_M 0x00380000 // Type Extension Mask +#define NVIC_MPU_ATTR3_SHAREABLE \ + 0x00040000 // Shareable +#define NVIC_MPU_ATTR3_CACHEABLE \ + 0x00020000 // Cacheable +#define NVIC_MPU_ATTR3_BUFFRABLE \ + 0x00010000 // Bufferable +#define NVIC_MPU_ATTR3_SRD_M 0x0000FF00 // Subregion Disable Bits +#define NVIC_MPU_ATTR3_SIZE_M 0x0000003E // Region Size Mask +#define NVIC_MPU_ATTR3_ENABLE 0x00000001 // Region Enable + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DBG_CTRL register. +// +//***************************************************************************** +#define NVIC_DBG_CTRL_DBGKEY_M 0xFFFF0000 // Debug key mask +#define NVIC_DBG_CTRL_DBGKEY 0xA05F0000 // Debug key +#define NVIC_DBG_CTRL_S_RESET_ST \ + 0x02000000 // Core has reset since last read +#define NVIC_DBG_CTRL_S_RETIRE_ST \ + 0x01000000 // Core has executed insruction + // since last read +#define NVIC_DBG_CTRL_S_LOCKUP 0x00080000 // Core is locked up +#define NVIC_DBG_CTRL_S_SLEEP 0x00040000 // Core is sleeping +#define NVIC_DBG_CTRL_S_HALT 0x00020000 // Core status on halt +#define NVIC_DBG_CTRL_S_REGRDY 0x00010000 // Register read/write available +#define NVIC_DBG_CTRL_C_SNAPSTALL \ + 0x00000020 // Breaks a stalled load/store +#define NVIC_DBG_CTRL_C_MASKINT 0x00000008 // Mask interrupts when stepping +#define NVIC_DBG_CTRL_C_STEP 0x00000004 // Step the core +#define NVIC_DBG_CTRL_C_HALT 0x00000002 // Halt the core +#define NVIC_DBG_CTRL_C_DEBUGEN 0x00000001 // Enable debug + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DBG_XFER register. +// +//***************************************************************************** +#define NVIC_DBG_XFER_REG_WNR 0x00010000 // Write or not read +#define NVIC_DBG_XFER_REG_SEL_M 0x0000001F // Register +#define NVIC_DBG_XFER_REG_R0 0x00000000 // Register R0 +#define NVIC_DBG_XFER_REG_R1 0x00000001 // Register R1 +#define NVIC_DBG_XFER_REG_R2 0x00000002 // Register R2 +#define NVIC_DBG_XFER_REG_R3 0x00000003 // Register R3 +#define NVIC_DBG_XFER_REG_R4 0x00000004 // Register R4 +#define NVIC_DBG_XFER_REG_R5 0x00000005 // Register R5 +#define NVIC_DBG_XFER_REG_R6 0x00000006 // Register R6 +#define NVIC_DBG_XFER_REG_R7 0x00000007 // Register R7 +#define NVIC_DBG_XFER_REG_R8 0x00000008 // Register R8 +#define NVIC_DBG_XFER_REG_R9 0x00000009 // Register R9 +#define NVIC_DBG_XFER_REG_R10 0x0000000A // Register R10 +#define NVIC_DBG_XFER_REG_R11 0x0000000B // Register R11 +#define NVIC_DBG_XFER_REG_R12 0x0000000C // Register R12 +#define NVIC_DBG_XFER_REG_R13 0x0000000D // Register R13 +#define NVIC_DBG_XFER_REG_R14 0x0000000E // Register R14 +#define NVIC_DBG_XFER_REG_R15 0x0000000F // Register R15 +#define NVIC_DBG_XFER_REG_FLAGS 0x00000010 // xPSR/Flags register +#define NVIC_DBG_XFER_REG_MSP 0x00000011 // Main SP +#define NVIC_DBG_XFER_REG_PSP 0x00000012 // Process SP +#define NVIC_DBG_XFER_REG_DSP 0x00000013 // Deep SP +#define NVIC_DBG_XFER_REG_CFBP 0x00000014 // Control/Fault/BasePri/PriMask + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DBG_DATA register. +// +//***************************************************************************** +#define NVIC_DBG_DATA_M 0xFFFFFFFF // Data temporary cache +#define NVIC_DBG_DATA_S 0 + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_DBG_INT register. +// +//***************************************************************************** +#define NVIC_DBG_INT_HARDERR 0x00000400 // Debug trap on hard fault +#define NVIC_DBG_INT_INTERR 0x00000200 // Debug trap on interrupt errors +#define NVIC_DBG_INT_BUSERR 0x00000100 // Debug trap on bus error +#define NVIC_DBG_INT_STATERR 0x00000080 // Debug trap on usage fault state +#define NVIC_DBG_INT_CHKERR 0x00000040 // Debug trap on usage fault check +#define NVIC_DBG_INT_NOCPERR 0x00000020 // Debug trap on coprocessor error +#define NVIC_DBG_INT_MMERR 0x00000010 // Debug trap on mem manage fault +#define NVIC_DBG_INT_RESET 0x00000008 // Core reset status +#define NVIC_DBG_INT_RSTPENDCLR 0x00000004 // Clear pending core reset +#define NVIC_DBG_INT_RSTPENDING 0x00000002 // Core reset is pending +#define NVIC_DBG_INT_RSTVCATCH 0x00000001 // Reset vector catch + +//***************************************************************************** +// +// The following are defines for the bit fields in the NVIC_SW_TRIG register. +// +//***************************************************************************** +#define NVIC_SW_TRIG_INTID_M 0x0000003F // Interrupt ID +#undef NVIC_SW_TRIG_INTID_M +#define NVIC_SW_TRIG_INTID_M 0x000000FF // Interrupt ID +#define NVIC_SW_TRIG_INTID_S 0 + +#endif // __HW_NVIC_H__ diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_pka.h b/bsp/boards/mimsy2-cc2538/headers/hw_pka.h new file mode 100644 index 0000000000..7c2adf430d --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_pka.h @@ -0,0 +1,792 @@ +/****************************************************************************** +* Filename: hw_pka.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_PKA_H__ +#define __HW_PKA_H__ + +//***************************************************************************** +// +// The following are defines for the PKA register offsets. +// +//***************************************************************************** +#define PKA_APTR 0x44004000 // PKA vector A address During + // execution of basic PKCP + // operations, this register is + // double buffered and can be + // written with a new value for the + // next operation; when not + // written, the value remains + // intact. During the execution of + // sequencer-controlled complex + // operations, this register may + // not be written and its value is + // undefined at the conclusion of + // the operation. The driver + // software cannot rely on the + // written value to remain intact. +#define PKA_BPTR 0x44004004 // PKA vector B address During + // execution of basic PKCP + // operations, this register is + // double buffered and can be + // written with a new value for the + // next operation; when not + // written, the value remains + // intact. During the execution of + // sequencer-controlled complex + // operations, this register may + // not be written and its value is + // undefined at the conclusion of + // the operation. The driver + // software cannot rely on the + // written value to remain intact. +#define PKA_CPTR 0x44004008 // PKA vector C address During + // execution of basic PKCP + // operations, this register is + // double buffered and can be + // written with a new value for the + // next operation; when not + // written, the value remains + // intact. During the execution of + // sequencer-controlled complex + // operations, this register may + // not be written and its value is + // undefined at the conclusion of + // the operation. The driver + // software cannot rely on the + // written value to remain intact. +#define PKA_DPTR 0x4400400C // PKA vector D address During + // execution of basic PKCP + // operations, this register is + // double buffered and can be + // written with a new value for the + // next operation; when not + // written, the value remains + // intact. During the execution of + // sequencer-controlled complex + // operations, this register may + // not be written and its value is + // undefined at the conclusion of + // the operation. The driver + // software cannot rely on the + // written value to remain intact. +#define PKA_ALENGTH 0x44004010 // PKA vector A length During + // execution of basic PKCP + // operations, this register is + // double buffered and can be + // written with a new value for the + // next operation; when not + // written, the value remains + // intact. During the execution of + // sequencer-controlled complex + // operations, this register may + // not be written and its value is + // undefined at the conclusion of + // the operation. The driver + // software cannot rely on the + // written value to remain intact. +#define PKA_BLENGTH 0x44004014 // PKA vector B length During + // execution of basic PKCP + // operations, this register is + // double buffered and can be + // written with a new value for the + // next operation; when not + // written, the value remains + // intact. During the execution of + // sequencer-controlled complex + // operations, this register may + // not be written and its value is + // undefined at the conclusion of + // the operation. The driver + // software cannot rely on the + // written value to remain intact. +#define PKA_SHIFT 0x44004018 // PKA bit shift value For basic + // PKCP operations, modifying the + // contents of this register is + // made impossible while the + // operation is being performed. + // For the ExpMod-variable and + // ExpMod-CRT operations, this + // register is used to indicate the + // number of odd powers to use + // (directly as a value in the + // range 1-16). For the ModInv and + // ECC operations, this register is + // used to hold a completion code. +#define PKA_FUNCTION 0x4400401C // PKA function This register + // contains the control bits to + // start basic PKCP as well as + // complex sequencer operations. + // The run bit can be used to poll + // for the completion of the + // operation. Modifying bits [11:0] + // is made impossible during the + // execution of a basic PKCP + // operation. During the execution + // of sequencer-controlled complex + // operations, this register is + // modified; the run and stall + // result bits are set to zero at + // the conclusion, but other bits + // are undefined. Attention: + // Continuously reading this + // register to poll the run bit is + // not allowed when executing + // complex sequencer operations + // (the sequencer cannot access the + // PKCP when this is done). Leave + // at least one sysclk cycle + // between poll operations. +#define PKA_COMPARE 0x44004020 // PKA compare result This + // register provides the result of + // a basic PKCP compare operation. + // It is updated when the run bit + // in the PKA_FUNCTION register is + // reset at the end of that + // operation. Status after a + // complex sequencer operation is + // unknown +#define PKA_MSW 0x44004024 // PKA most-significant-word of + // result vector This register + // indicates the (word) address in + // the PKA RAM where the most + // significant nonzero 32-bit word + // of the result is stored. Should + // be ignored for modulo + // operations. For basic PKCP + // operations, this register is + // updated when the run bit in the + // PKA_FUNCTION register is reset + // at the end of the operation. For + // the complex-sequencer controlled + // operations, updating of the + // final value matching the actual + // result is done near the end of + // the operation; note that the + // result is only meaningful if no + // errors were detected and that + // for ECC operations, the PKA_MSW + // register will provide + // information for the x-coordinate + // of the result point only. +#define PKA_DIVMSW 0x44004028 // PKA most-significant-word of + // divide remainder This register + // indicates the (32-bit word) + // address in the PKA RAM where the + // most significant nonzero 32-bit + // word of the remainder result for + // the basic divide and modulo + // operations is stored. Bits [4:0] + // are loaded with the bit number + // of the most-significant nonzero + // bit in the most-significant + // nonzero word when MS one control + // bit is set. For divide, modulo, + // and MS one reporting, this + // register is updated when the RUN + // bit in the PKA_FUNCTION register + // is reset at the end of the + // operation. For the complex + // sequencer controlled operations, + // updating of bits [4:0] of this + // register with the + // most-significant bit location of + // the actual result is done near + // the end of the operation. The + // result is meaningful only if no + // errors were detected and that + // for ECC operations; the + // PKA_DIVMSW register provides + // information for the x-coordinate + // of the result point only. +#define PKA_SEQ_CTRL 0x440040C8 // PKA sequencer control and + // status register The sequencer is + // interfaced with the outside + // world through a single control + // and status register. With the + // exception of bit [31], the + // actual use of bits in the + // separate sub-fields of this + // register is determined by the + // sequencer firmware. This + // register need only be accessed + // when the sequencer program is + // stored in RAM. The reset value + // of the RESTE bit depends upon + // the option chosen for sequencer + // program storage. +#define PKA_OPTIONS 0x440040F4 // PKA hardware options register + // This register provides the host + // with a means to determine the + // hardware configuration + // implemented in this PKA engine, + // focused on options that have an + // effect on software interacting + // with the module. Note: (32 x + // (1st LNME nr. of PEs + 1st LNME + // FIFO RAM depth - 10)) equals the + // maximum modulus vector length + // (in bits) that can be handled by + // the modular exponentiation and + // ECC operations executed on a PKA + // engine that includes an LNME. +#define PKA_SW_REV 0x440040F8 // PKA firmware revision and + // capabilities register This + // register allows the host access + // to the internal firmware + // revision number of the PKA + // Engine for software driver + // matching and diagnostic + // purposes. This register also + // contains a field that encodes + // the capabilities of the embedded + // firmware. The PKA_SW_REV + // register is written by the + // firmware within a few clock + // cycles after starting up that + // firmware. The hardware reset + // value is zero, indicating that + // the information has not been + // written yet. +#define PKA_REVISION 0x440040FC // PKA hardware revision register + // This register allows the host + // access to the hardware revision + // number of the PKA engine for + // software driver matching and + // diagnostic purposes. It is + // always located at the highest + // address in the access space of + // the module and contains an + // encoding of the EIP number (with + // its complement as signature) for + // recognition of the hardware + // module. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_APTR register. +// +//***************************************************************************** +#define PKA_APTR_APTR_M 0x000007FF // This register specifies the + // location of vector A within the + // PKA RAM. Vectors are identified + // through the location of their + // least-significant 32-bit word. + // Note that bit [0] must be zero + // to ensure that the vector starts + // at an 8-byte boundary. +#define PKA_APTR_APTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_BPTR register. +// +//***************************************************************************** +#define PKA_BPTR_BPTR_M 0x000007FF // This register specifies the + // location of vector B within the + // PKA RAM. Vectors are identified + // through the location of their + // least-significant 32-bit word. + // Note that bit [0] must be zero + // to ensure that the vector starts + // at an 8-byte boundary. +#define PKA_BPTR_BPTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_CPTR register. +// +//***************************************************************************** +#define PKA_CPTR_CPTR_M 0x000007FF // This register specifies the + // location of vector C within the + // PKA RAM. Vectors are identified + // through the location of their + // least-significant 32-bit word. + // Note that bit [0] must be zero + // to ensure that the vector starts + // at an 8-byte boundary. +#define PKA_CPTR_CPTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_DPTR register. +// +//***************************************************************************** +#define PKA_DPTR_DPTR_M 0x000007FF // This register specifies the + // location of vector D within the + // PKA RAM. Vectors are identified + // through the location of their + // least-significant 32-bit word. + // Note that bit [0] must be zero + // to ensure that the vector starts + // at an 8-byte boundary. +#define PKA_DPTR_DPTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_ALENGTH register. +// +//***************************************************************************** +#define PKA_ALENGTH_ALENGTH_M 0x000001FF // This register specifies the + // length (in 32-bit words) of + // Vector A. +#define PKA_ALENGTH_ALENGTH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_BLENGTH register. +// +//***************************************************************************** +#define PKA_BLENGTH_BLENGTH_M 0x000001FF // This register specifies the + // length (in 32-bit words) of + // Vector B. +#define PKA_BLENGTH_BLENGTH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_SHIFT register. +// +//***************************************************************************** +#define PKA_SHIFT_NUM_BITS_TO_SHIFT_M \ + 0x0000001F // This register specifies the + // number of bits to shift the + // input vector (in the range 0-31) + // during a Rshift or Lshift + // operation. + +#define PKA_SHIFT_NUM_BITS_TO_SHIFT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_FUNCTION register. +// +//***************************************************************************** +#define PKA_FUNCTION_STALL_RESULT \ + 0x01000000 // When written with a 1b, + // updating of the PKA_COMPARE, + // PKA_MSW and PKA_DIVMSW + // registers, as well as resetting + // the run bit is stalled beyond + // the point that a running + // operation is actually finished. + // Use this to allow software + // enough time to read results from + // a previous operation when the + // newly started operation is known + // to take only a short amount of + // time. If a result is waiting, + // the result registers is updated + // and the run bit is reset in the + // clock cycle following writing + // the stall result bit back to 0b. + // The Stall result function may + // only be used for basic PKCP + // operations. + +#define PKA_FUNCTION_STALL_RESULT_M \ + 0x01000000 +#define PKA_FUNCTION_STALL_RESULT_S 24 +#define PKA_FUNCTION_RUN 0x00008000 // The host sets this bit to + // instruct the PKA module to begin + // processing the basic PKCP or + // complex sequencer operation. + // This bit is reset low + // automatically when the operation + // is complete. The complement of + // this bit is output as + // interrupts[1]. After a reset, + // the run bit is always set to 1b. + // Depending on the option, program + // ROM or program RAM, the + // following applies: Program ROM - + // The first sequencer instruction + // sets the bit to 0b. This is done + // immediately after the hardware + // reset is released. Program RAM - + // The sequencer must set the bit + // to 0b. As a valid firmware may + // not have been loaded, the + // sequencer is held in software + // reset after the hardware reset + // is released (the reset bit in + // PKA_SEQ_CRTL is set to 1b). + // After the FW image is loaded and + // the Reset bit is cleared, the + // sequencer starts to execute the + // FW. The first instruction clears + // the run bit. In both cases a few + // clock cycles are needed before + // the first instruction is + // executed and the run bit state + // has been propagated. +#define PKA_FUNCTION_RUN_M 0x00008000 +#define PKA_FUNCTION_RUN_S 15 +#define PKA_FUNCTION_SEQUENCER_OPERATIONS_M \ + 0x00007000 // These bits select the complex + // sequencer operation to perform: + // 000b: None 001b: ExpMod-CRT + // 010b: ExpMod-ACT4 (compatible + // with EIP2315) 011b: ECC-ADD (if + // available in firmware, otherwise + // reserved) 100b: ExpMod-ACT2 + // (compatible with EIP2316) 101b: + // ECC-MUL (if available in + // firmware, otherwise reserved) + // 110b: ExpMod-variable 111b: + // ModInv (if available in + // firmware, otherwise reserved) + // The encoding of these operations + // is determined by sequencer + // firmware. + +#define PKA_FUNCTION_SEQUENCER_OPERATIONS_S 12 +#define PKA_FUNCTION_COPY 0x00000800 // Perform copy operation +#define PKA_FUNCTION_COPY_M 0x00000800 +#define PKA_FUNCTION_COPY_S 11 +#define PKA_FUNCTION_COMPARE 0x00000400 // Perform compare operation +#define PKA_FUNCTION_COMPARE_M 0x00000400 +#define PKA_FUNCTION_COMPARE_S 10 +#define PKA_FUNCTION_MODULO 0x00000200 // Perform modulo operation +#define PKA_FUNCTION_MODULO_M 0x00000200 +#define PKA_FUNCTION_MODULO_S 9 +#define PKA_FUNCTION_DIVIDE 0x00000100 // Perform divide operation +#define PKA_FUNCTION_DIVIDE_M 0x00000100 +#define PKA_FUNCTION_DIVIDE_S 8 +#define PKA_FUNCTION_LSHIFT 0x00000080 // Perform left shift operation +#define PKA_FUNCTION_LSHIFT_M 0x00000080 +#define PKA_FUNCTION_LSHIFT_S 7 +#define PKA_FUNCTION_RSHIFT 0x00000040 // Perform right shift operation +#define PKA_FUNCTION_RSHIFT_M 0x00000040 +#define PKA_FUNCTION_RSHIFT_S 6 +#define PKA_FUNCTION_SUBTRACT 0x00000020 // Perform subtract operation +#define PKA_FUNCTION_SUBTRACT_M 0x00000020 +#define PKA_FUNCTION_SUBTRACT_S 5 +#define PKA_FUNCTION_ADD 0x00000010 // Perform add operation +#define PKA_FUNCTION_ADD_M 0x00000010 +#define PKA_FUNCTION_ADD_S 4 +#define PKA_FUNCTION_MS_ONE 0x00000008 // Loads the location of the Most + // Significant one bit within the + // result word indicated in the + // PKA_MSW register into bits [4:0] + // of the PKA_DIVMSW register - can + // only be used with basic PKCP + // operations, except for Divide, + // Modulo and Compare. +#define PKA_FUNCTION_MS_ONE_M 0x00000008 +#define PKA_FUNCTION_MS_ONE_S 3 +#define PKA_FUNCTION_ADDSUB 0x00000002 // Perform combined add/subtract + // operation +#define PKA_FUNCTION_ADDSUB_M 0x00000002 +#define PKA_FUNCTION_ADDSUB_S 1 +#define PKA_FUNCTION_MULTIPLY 0x00000001 // Perform multiply operation +#define PKA_FUNCTION_MULTIPLY_M 0x00000001 +#define PKA_FUNCTION_MULTIPLY_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_COMPARE register. +// +//***************************************************************************** +#define PKA_COMPARE_A_GREATER_THAN_B \ + 0x00000004 // Vector_A is greater than + // Vector_B + +#define PKA_COMPARE_A_GREATER_THAN_B_M \ + 0x00000004 +#define PKA_COMPARE_A_GREATER_THAN_B_S 2 +#define PKA_COMPARE_A_LESS_THAN_B \ + 0x00000002 // Vector_A is less than Vector_B + +#define PKA_COMPARE_A_LESS_THAN_B_M \ + 0x00000002 +#define PKA_COMPARE_A_LESS_THAN_B_S 1 +#define PKA_COMPARE_A_EQUALS_B 0x00000001 // Vector_A is equal to Vector_B +#define PKA_COMPARE_A_EQUALS_B_M \ + 0x00000001 +#define PKA_COMPARE_A_EQUALS_B_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_MSW register. +// +//***************************************************************************** +#define PKA_MSW_RESULT_IS_ZERO 0x00008000 // The result vector is all + // zeroes, ignore the address + // returned in bits [10:0] +#define PKA_MSW_RESULT_IS_ZERO_M \ + 0x00008000 +#define PKA_MSW_RESULT_IS_ZERO_S 15 +#define PKA_MSW_MSW_ADDRESS_M 0x000007FF // Address of the most-significant + // nonzero 32-bit word of the + // result vector in PKA RAM +#define PKA_MSW_MSW_ADDRESS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_DIVMSW register. +// +//***************************************************************************** +#define PKA_DIVMSW_RESULT_IS_ZERO \ + 0x00008000 // The result vector is all + // zeroes, ignore the address + // returned in bits [10:0] + +#define PKA_DIVMSW_RESULT_IS_ZERO_M \ + 0x00008000 +#define PKA_DIVMSW_RESULT_IS_ZERO_S 15 +#define PKA_DIVMSW_MSW_ADDRESS_M \ + 0x000007FF // Address of the most significant + // nonzero 32-bit word of the + // remainder result vector in PKA + // RAM + +#define PKA_DIVMSW_MSW_ADDRESS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_SEQ_CTRL register. +// +//***************************************************************************** +#define PKA_SEQ_CTRL_RESET 0x80000000 // Option program ROM: Reset value + // = 0. Read/Write, reset value 0b + // (ZERO). Writing 1b resets the + // sequencer, write to 0b to + // restart operations again. As the + // reset value is 0b, the sequencer + // will automatically start + // operations executing from + // program ROM. This bit should + // always be written with zero and + // ignored when reading this + // register. Option Program RAM: + // Reset value =1. Read/Write, + // reset value 1b (ONE). When 1b, + // the sequencer is held in a reset + // state and the PKA_PROGRAM area + // is accessible for loading the + // sequencer program (while the + // PKA_DATA_RAM is inaccessible), + // write to 0b to (re)start + // sequencer operations and disable + // PKA_PROGRAM area accessibility + // (also enables the PKA_DATA_RAM + // accesses). Resetting the + // sequencer (in order to load + // other firmware) should only be + // done when the PKA Engine is not + // performing any operations (i.e. + // the run bit in the PKA_FUNCTION + // register should be zero). +#define PKA_SEQ_CTRL_RESET_M 0x80000000 +#define PKA_SEQ_CTRL_RESET_S 31 +#define PKA_SEQ_CTRL_SEQUENCER_STATUS_M \ + 0x0000FF00 // These read-only bits can be + // used by the sequencer to + // communicate status to the + // outside world. Bit [8] is also + // used as sequencer interrupt, + // with the complement of this bit + // ORed into the run bit in + // PKA_FUNCTION. This field should + // always be written with zeroes + // and ignored when reading this + // register. + +#define PKA_SEQ_CTRL_SEQUENCER_STATUS_S 8 +#define PKA_SEQ_CTRL_SW_CONTROL_STATUS_M \ + 0x000000FF // These bits can be used by + // software to trigger sequencer + // operations. External logic can + // set these bits by writing 1b, + // cannot reset them by writing 0b. + // The sequencer can reset these + // bits by writing 0b, cannot set + // them by writing 1b. Setting the + // run bit in PKA_FUNCTION together + // with a nonzero sequencer + // operations field automatically + // sets bit [0] here. This field + // should always be written with + // zeroes and ignored when reading + // this register. + +#define PKA_SEQ_CTRL_SW_CONTROL_STATUS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_OPTIONS register. +// +//***************************************************************************** +#define PKA_OPTIONS_FIRST_LNME_FIFO_DEPTH_M \ + 0xFF000000 // Number of words in the first + // LNME's FIFO RAM Should be + // ignored if LNME configuration is + // 0. The contents of this field + // indicate the actual depth as + // selected by the LNME FIFO RAM + // size strap input, fifo_size_sel. + // Note: Reset value is undefined + +#define PKA_OPTIONS_FIRST_LNME_FIFO_DEPTH_S 24 +#define PKA_OPTIONS_FIRST_LNME_NR_OF_PES_M \ + 0x003F0000 // Number of processing elements + // in the pipeline of the first + // LNME Should be ignored if LNME + // configuration is 0. Note: Reset + // value is undefined. + +#define PKA_OPTIONS_FIRST_LNME_NR_OF_PES_S 16 +#define PKA_OPTIONS_MMM3A 0x00001000 // Reserved for a future + // functional extension to the LNME + // Always 0b +#define PKA_OPTIONS_MMM3A_M 0x00001000 +#define PKA_OPTIONS_MMM3A_S 12 +#define PKA_OPTIONS_INT_MASKING 0x00000800 // Value 0b indicates that the + // main interrupt output (bit [1] + // of the interrupts output bus) is + // the direct complement of the run + // bit in the PKA_CONTROL register, + // value 1b indicates that + // interrupt masking logic is + // present for this output. Note: + // Reset value is undefined +#define PKA_OPTIONS_INT_MASKING_M \ + 0x00000800 +#define PKA_OPTIONS_INT_MASKING_S 11 +#define PKA_OPTIONS_PROTECTION_OPTION_M \ + 0x00000700 // Value 0 indicates no additional + // protection against side channel + // attacks, value 1 indicates the + // SCAP option, value 3 indicates + // the PROT option; other values + // are reserved. Note: Reset value + // is undefined + +#define PKA_OPTIONS_PROTECTION_OPTION_S 8 +#define PKA_OPTIONS_PROGRAM_RAM 0x00000080 // Value 1b indicates sequencer + // program storage in RAM, value 0b + // in ROM. Note: Reset value is + // undefined +#define PKA_OPTIONS_PROGRAM_RAM_M \ + 0x00000080 +#define PKA_OPTIONS_PROGRAM_RAM_S 7 +#define PKA_OPTIONS_SEQUENCER_CONFIGURATION_M \ + 0x00000060 // Value 1 indicates a standard + // sequencer; other values are + // reserved. + +#define PKA_OPTIONS_SEQUENCER_CONFIGURATION_S 5 +#define PKA_OPTIONS_LNME_CONFIGURATION_M \ + 0x0000001C // Value 0 indicates NO LNME, + // value 1 indicates one standard + // LNME (with alpha = 32, beta = + // 8); other values reserved. Note: + // Reset value is undefined + +#define PKA_OPTIONS_LNME_CONFIGURATION_S 2 +#define PKA_OPTIONS_PKCP_CONFIGURATION_M \ + 0x00000003 // Value 1 indicates a PKCP with a + // 16x16 multiplier, value 2 + // indicates a PKCP with a 32x32 + // multiplier, other values + // reserved. Note: Reset value is + // undefined. + +#define PKA_OPTIONS_PKCP_CONFIGURATION_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_SW_REV register. +// +//***************************************************************************** +#define PKA_SW_REV_FW_CAPABILITIES_M \ + 0xF0000000 // 4-bit binary encoding for the + // functionality implemented in the + // firmware. Value 0 indicates + // basic ModExp with/without CRT. + // Value 1 adds Modular Inversion, + // value 2 adds Modular Inversion + // and ECC operations. Values 3-15 + // are reserved. + +#define PKA_SW_REV_FW_CAPABILITIES_S 28 +#define PKA_SW_REV_MAJOR_FW_REVISION_M \ + 0x0F000000 // 4-bit binary encoding of the + // major firmware revision number + +#define PKA_SW_REV_MAJOR_FW_REVISION_S 24 +#define PKA_SW_REV_MINOR_FW_REVISION_M \ + 0x00F00000 // 4-bit binary encoding of the + // minor firmware revision number + +#define PKA_SW_REV_MINOR_FW_REVISION_S 20 +#define PKA_SW_REV_FW_PATCH_LEVEL_M \ + 0x000F0000 // 4-bit binary encoding of the + // firmware patch level, initial + // release will carry value zero + // Patches are used to remove bugs + // without changing the + // functionality or interface of a + // module. + +#define PKA_SW_REV_FW_PATCH_LEVEL_S 16 +//***************************************************************************** +// +// The following are defines for the bit fields in the PKA_REVISION register. +// +//***************************************************************************** +#define PKA_REVISION_MAJOR_HW_REVISION_M \ + 0x0F000000 // 4-bit binary encoding of the + // major hardware revision number + +#define PKA_REVISION_MAJOR_HW_REVISION_S 24 +#define PKA_REVISION_MINOR_HW_REVISION_M \ + 0x00F00000 // 4-bit binary encoding of the + // minor hardware revision number + +#define PKA_REVISION_MINOR_HW_REVISION_S 20 +#define PKA_REVISION_HW_PATCH_LEVEL_M \ + 0x000F0000 // 4-bit binary encoding of the + // hardware patch level, initial + // release will carry value zero + // Patches are used to remove bugs + // without changing the + // functionality or interface of a + // module. + +#define PKA_REVISION_HW_PATCH_LEVEL_S 16 +#define PKA_REVISION_COMPLEMENT_OF_BASIC_EIP_NUMBER_M \ + 0x0000FF00 // Bit-by-bit logic complement of + // bits [7:0], EIP-28 gives 0xE3 + +#define PKA_REVISION_COMPLEMENT_OF_BASIC_EIP_NUMBER_S 8 +#define PKA_REVISION_BASIC_EIP_NUMBER_M \ + 0x000000FF // 8-bit binary encoding of the + // EIP number, EIP-28 gives 0x1C + +#define PKA_REVISION_BASIC_EIP_NUMBER_S 0 + + +#endif // __HW_PKA_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_rfcore_ffsm.h b/bsp/boards/mimsy2-cc2538/headers/hw_rfcore_ffsm.h new file mode 100644 index 0000000000..42faeb4c73 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_rfcore_ffsm.h @@ -0,0 +1,440 @@ +/****************************************************************************** +* Filename: hw_rfcore_ffsm.h +* Revised: $Date: 2013-04-12 15:10:54 +0200 (Fri, 12 Apr 2013) $ +* Revision: $Revision: 9735 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_RFCORE_FFSM_H__ +#define __HW_RFCORE_FFSM_H__ + +//***************************************************************************** +// +// The following are defines for the RFCORE_FFSM register offsets. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCRESMASK0 \ + 0x40088580 // Source address matching result + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_SRCRESMASK1 \ + 0x40088584 // Source address matching result + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_SRCRESMASK2 \ + 0x40088588 // Source address matching result + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_SRCRESINDEX \ + 0x4008858C // Source address matching result + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_SRCEXTPENDEN0 \ + 0x40088590 // Source address matching control + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_SRCEXTPENDEN1 \ + 0x40088594 // Source address matching control + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_SRCEXTPENDEN2 \ + 0x40088598 // Source address matching control + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_SRCSHORTPENDEN0 \ + 0x4008859C // Source address matching control + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_SRCSHORTPENDEN1 \ + 0x400885A0 // Source address matching control + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_SRCSHORTPENDEN2 \ + 0x400885A4 // Source address matching control + // This register is stored in RAM; + // the reset value is undefined. + +#define RFCORE_FFSM_EXT_ADDR0 0x400885A8 // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_EXT_ADDR1 0x400885AC // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_EXT_ADDR2 0x400885B0 // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_EXT_ADDR3 0x400885B4 // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_EXT_ADDR4 0x400885B8 // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_EXT_ADDR5 0x400885BC // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_EXT_ADDR6 0x400885C0 // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_EXT_ADDR7 0x400885C4 // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_PAN_ID0 0x400885C8 // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_PAN_ID1 0x400885CC // Local address information This + // register is stored in RAM; the + // reset value is undefined. +#define RFCORE_FFSM_SHORT_ADDR0 \ + 0x400885D0 // Local address information This + // register is stored in RAM; the + // reset value is undefined. + +#define RFCORE_FFSM_SHORT_ADDR1 \ + 0x400885D4 // Local address information This + // register is stored in RAM; the + // reset value is undefined. + + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCRESMASK0 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCRESMASK0_SRCRESMASK0_M \ + 0x000000FF // Extended address matching When + // there is a match on entry ext_n, + // bits 2n and 2n + 1 are set in + // SRCRESMASK. + +#define RFCORE_FFSM_SRCRESMASK0_SRCRESMASK0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCRESMASK1 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCRESMASK1_SRCRESMASK1_M \ + 0x000000FF // Short address matching When + // there is a match on entry + // panid_n + short_n, bit n is set + // in SRCRESMASK. + +#define RFCORE_FFSM_SRCRESMASK1_SRCRESMASK1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCRESMASK2 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCRESMASK2_SRCRESMASK2_M \ + 0x000000FF // 24-bit mask that indicates + // source address match for each + // individual entry in the source + // address table + +#define RFCORE_FFSM_SRCRESMASK2_SRCRESMASK2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCRESINDEX register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCRESINDEX_SRCRESINDEX_M \ + 0x000000FF // The bit index of the + // least-significant entry (0-23 + // for short addresses or 0-11 for + // extended addresses) in + // SRCRESMASK, or 0x3F when there + // is no source match On a match, + // bit 5 is 0 when the match is on + // a short address and 1 when it is + // on an extended address. On a + // match, bit 6 is 1 when the + // conditions for automatic pending + // bit in acknowledgment have been + // met (see the description of + // SRCMATCH.AUTOPEND). The bit does + // not indicate if the + // acknowledgment is actually + // transmitted, and does not + // consider the PENDING_OR register + // bit and the SACK/SACKPEND/SNACK + // strobes. + +#define RFCORE_FFSM_SRCRESINDEX_SRCRESINDEX_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCEXTPENDEN0 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCEXTPENDEN0_SRCEXTPENDEN0_M \ + 0x000000FF // 8 LSBs of the 24-bit mask that + // enables or disables automatic + // pending for each of the 12 + // extended addresses. Entry n is + // mapped to SRCEXTPENDEN[2n]. All + // SRCEXTPENDEN[2n + 1] bits are + // don't care. + +#define RFCORE_FFSM_SRCEXTPENDEN0_SRCEXTPENDEN0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCEXTPENDEN1 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCEXTPENDEN1_SRCEXTPENDEN1_M \ + 0x000000FF // 8 middle bits of the 24-bit + // mask that enables or disables + // automatic pending for each of + // the 12 extended addresses Entry + // n is mapped to SRCEXTPENDEN[2n]. + // All SRCEXTPENDEN[2n + 1] bits + // are don't care. + +#define RFCORE_FFSM_SRCEXTPENDEN1_SRCEXTPENDEN1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCEXTPENDEN2 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCEXTPENDEN2_SRCEXTPENDEN2_M \ + 0x000000FF // 8 MSBs of the 24-bit mask that + // enables or disables automatic + // pending for each of the 12 + // extended addresses Entry n is + // mapped to SRCEXTPENDEN[2n]. All + // SRCEXTPENDEN[2n + 1] bits are + // don't care. + +#define RFCORE_FFSM_SRCEXTPENDEN2_SRCEXTPENDEN2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCSHORTPENDEN0 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCSHORTPENDEN0_SRCSHORTPENDEN0_M \ + 0x000000FF // 8 LSBs of the 24-bit mask that + // enables or disables automatic + // pending for each of the 24 short + // addresses + +#define RFCORE_FFSM_SRCSHORTPENDEN0_SRCSHORTPENDEN0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCSHORTPENDEN1 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCSHORTPENDEN1_SRCSHORTPENDEN1_M \ + 0x000000FF // 8 middle bits of the 24-bit + // mask that enables or disables + // automatic pending for each of + // the 24 short addresses + +#define RFCORE_FFSM_SRCSHORTPENDEN1_SRCSHORTPENDEN1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SRCSHORTPENDEN2 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SRCSHORTPENDEN2_SRCSHORTPENDEN2_M \ + 0x000000FF // 8 MSBs of the 24-bit mask that + // enables or disables automatic + // pending for each of the 24 short + // addresses + +#define RFCORE_FFSM_SRCSHORTPENDEN2_SRCSHORTPENDEN2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_EXT_ADDR0 register. +// +//***************************************************************************** +#define RFCORE_FFSM_EXT_ADDR0_EXT_ADDR0_M \ + 0x000000FF // EXT_ADDR[7:0] The IEEE extended + // address used during destination + // address filtering + +#define RFCORE_FFSM_EXT_ADDR0_EXT_ADDR0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_EXT_ADDR1 register. +// +//***************************************************************************** +#define RFCORE_FFSM_EXT_ADDR1_EXT_ADDR1_M \ + 0x000000FF // EXT_ADDR[15:8] The IEEE + // extended address used during + // destination address filtering + +#define RFCORE_FFSM_EXT_ADDR1_EXT_ADDR1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_EXT_ADDR2 register. +// +//***************************************************************************** +#define RFCORE_FFSM_EXT_ADDR2_EXT_ADDR2_M \ + 0x000000FF // EXT_ADDR[23:16] The IEEE + // extended address used during + // destination address filtering + +#define RFCORE_FFSM_EXT_ADDR2_EXT_ADDR2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_EXT_ADDR3 register. +// +//***************************************************************************** +#define RFCORE_FFSM_EXT_ADDR3_EXT_ADDR3_M \ + 0x000000FF // EXT_ADDR[31:24] The IEEE + // extended address used during + // destination address filtering + +#define RFCORE_FFSM_EXT_ADDR3_EXT_ADDR3_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_EXT_ADDR4 register. +// +//***************************************************************************** +#define RFCORE_FFSM_EXT_ADDR4_EXT_ADDR4_M \ + 0x000000FF // EXT_ADDR[39:32] The IEEE + // extended address used during + // destination address filtering + +#define RFCORE_FFSM_EXT_ADDR4_EXT_ADDR4_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_EXT_ADDR5 register. +// +//***************************************************************************** +#define RFCORE_FFSM_EXT_ADDR5_EXT_ADDR5_M \ + 0x000000FF // EXT_ADDR[47:40] The IEEE + // extended address used during + // destination address filtering + +#define RFCORE_FFSM_EXT_ADDR5_EXT_ADDR5_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_EXT_ADDR6 register. +// +//***************************************************************************** +#define RFCORE_FFSM_EXT_ADDR6_EXT_ADDR6_M \ + 0x000000FF // EXT_ADDR[55:48] The IEEE + // extended address used during + // destination address filtering + +#define RFCORE_FFSM_EXT_ADDR6_EXT_ADDR6_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_EXT_ADDR7 register. +// +//***************************************************************************** +#define RFCORE_FFSM_EXT_ADDR7_EXT_ADDR7_M \ + 0x000000FF // EXT_ADDR[63:56] The IEEE + // extended address used during + // destination address filtering + +#define RFCORE_FFSM_EXT_ADDR7_EXT_ADDR7_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_PAN_ID0 register. +// +//***************************************************************************** +#define RFCORE_FFSM_PAN_ID0_PAN_ID0_M \ + 0x000000FF // PAN_ID[7:0] The PAN ID used + // during destination address + // filtering + +#define RFCORE_FFSM_PAN_ID0_PAN_ID0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_PAN_ID1 register. +// +//***************************************************************************** +#define RFCORE_FFSM_PAN_ID1_PAN_ID1_M \ + 0x000000FF // PAN_ID[15:8] The PAN ID used + // during destination address + // filtering + +#define RFCORE_FFSM_PAN_ID1_PAN_ID1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SHORT_ADDR0 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SHORT_ADDR0_SHORT_ADDR0_M \ + 0x000000FF // SHORT_ADDR[7:0] The short + // address used during destination + // address filtering + +#define RFCORE_FFSM_SHORT_ADDR0_SHORT_ADDR0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_FFSM_SHORT_ADDR1 register. +// +//***************************************************************************** +#define RFCORE_FFSM_SHORT_ADDR1_SHORT_ADDR1_M \ + 0x000000FF // SHORT_ADDR[15:8] The short + // address used during destination + // address filtering + +#define RFCORE_FFSM_SHORT_ADDR1_SHORT_ADDR1_S 0 + + +#endif // __HW_RFCORE_FFSM_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_rfcore_sfr.h b/bsp/boards/mimsy2-cc2538/headers/hw_rfcore_sfr.h new file mode 100644 index 0000000000..ce18ae704b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_rfcore_sfr.h @@ -0,0 +1,614 @@ +/****************************************************************************** +* Filename: hw_rfcore_sfr.h +* Revised: $Date: 2013-04-12 15:10:54 +0200 (Fri, 12 Apr 2013) $ +* Revision: $Revision: 9735 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_RFCORE_SFR_H__ +#define __HW_RFCORE_SFR_H__ + +//***************************************************************************** +// +// The following are defines for the RFCORE_SFR register offsets. +// +//***************************************************************************** +#define RFCORE_SFR_MTCSPCFG 0x40088800 // MAC Timer event configuration +#define RFCORE_SFR_MTCTRL 0x40088804 // MAC Timer control register +#define RFCORE_SFR_MTIRQM 0x40088808 // MAC Timer interrupt mask +#define RFCORE_SFR_MTIRQF 0x4008880C // MAC Timer interrupt flags +#define RFCORE_SFR_MTMSEL 0x40088810 // MAC Timer multiplex select +#define RFCORE_SFR_MTM0 0x40088814 // MAC Timer multiplexed register + // 0 +#define RFCORE_SFR_MTM1 0x40088818 // MAC Timer multiplexed register + // 1 +#define RFCORE_SFR_MTMOVF2 0x4008881C // MAC Timer multiplexed overflow + // register 2 +#define RFCORE_SFR_MTMOVF1 0x40088820 // MAC Timer multiplexed overflow + // register 1 +#define RFCORE_SFR_MTMOVF0 0x40088824 // MAC Timer multiplexed overflow + // register 0 +#define RFCORE_SFR_RFDATA 0x40088828 // The TX FIFO and RX FIFO may be + // accessed through this register. + // Data is written to the TX FIFO + // when writing to the RFD + // register. Data is read from the + // RX FIFO when the RFD register is + // read. The XREG registers + // RXFIFOCNT and TXFIFOCNT provide + // information on the amount of + // data in the FIFOs. The FIFO + // contents can be cleared by + // issuing SFLUSHRX and SFLUSHTX. +#define RFCORE_SFR_RFERRF 0x4008882C // RF error interrupt flags +#define RFCORE_SFR_RFIRQF1 0x40088830 // RF interrupt flags +#define RFCORE_SFR_RFIRQF0 0x40088834 // RF interrupt flags +#define RFCORE_SFR_RFST 0x40088838 // RF CSMA-CA/strobe processor + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTCSPCFG register. +// +//***************************************************************************** +#define RFCORE_SFR_MTCSPCFG_MACTIMER_EVENMT_CFG_M \ + 0x00000070 // Selects the event that triggers + // an MT_EVENT2 pulse 000: + // MT_per_event 001: MT_cmp1_event + // 010: MT_cmp2_event 011: + // MTovf_per_event 100: + // MTovf_cmp1_event 101: + // MTovf_cmp2_event 110: Reserved + // 111: No event + +#define RFCORE_SFR_MTCSPCFG_MACTIMER_EVENMT_CFG_S 4 +#define RFCORE_SFR_MTCSPCFG_MACTIMER_EVENT1_CFG_M \ + 0x00000007 // Selects the event that triggers + // an MT_EVENT1 pulse 000: + // MT_per_event 001: MT_cmp1_event + // 010: MT_cmp2_event 011: + // MTovf_per_event 100: + // MTovf_cmp1_event 101: + // MTovf_cmp2_event 110: Reserved + // 111: No event + +#define RFCORE_SFR_MTCSPCFG_MACTIMER_EVENT1_CFG_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTCTRL register. +// +//***************************************************************************** +#define RFCORE_SFR_MTCTRL_LATCH_MODE \ + 0x00000008 // 0: Reading MTM0 with + // MTMSEL.MTMSEL = 000 latches the + // high byte of the timer, making + // it ready to be read from MTM1. + // Reading MTMOVF0 with + // MTMSEL.MTMOVFSEL = 000 latches + // the two most-significant bytes + // of the overflow counter, making + // it possible to read these from + // MTMOVF1 and MTMOVF2. 1: Reading + // MTM0 with MTMSEL.MTMSEL = 000 + // latches the high byte of the + // timer and the entire overflow + // counter at once, making it + // possible to read the values from + // MTM1, MTMOVF0, MTMOVF1, and + // MTMOVF2. + +#define RFCORE_SFR_MTCTRL_LATCH_MODE_M \ + 0x00000008 +#define RFCORE_SFR_MTCTRL_LATCH_MODE_S 3 +#define RFCORE_SFR_MTCTRL_STATE 0x00000004 // State of MAC Timer 0: Timer + // idle 1: Timer running +#define RFCORE_SFR_MTCTRL_STATE_M \ + 0x00000004 +#define RFCORE_SFR_MTCTRL_STATE_S 2 +#define RFCORE_SFR_MTCTRL_SYNC 0x00000002 // 0: Starting and stopping of + // timer is immediate; that is, + // synchronous with clk_rf_32m. 1: + // Starting and stopping of timer + // occurs at the first positive + // edge of the 32-kHz clock. For + // more details regarding timer + // start and stop, see Section + // 22.4. +#define RFCORE_SFR_MTCTRL_SYNC_M \ + 0x00000002 +#define RFCORE_SFR_MTCTRL_SYNC_S 1 +#define RFCORE_SFR_MTCTRL_RUN 0x00000001 // Write 1 to start timer, write 0 + // to stop timer. When read, it + // returns the last written value. +#define RFCORE_SFR_MTCTRL_RUN_M 0x00000001 +#define RFCORE_SFR_MTCTRL_RUN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTIRQM register. +// +//***************************************************************************** +#define RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE2M \ + 0x00000020 // Enables the + // MACTIMER_OVF_COMPARE2 interrupt + +#define RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE2M_M \ + 0x00000020 +#define RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE2M_S 5 +#define RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE1M \ + 0x00000010 // Enables the + // MACTIMER_OVF_COMPARE1 interrupt + +#define RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE1M_M \ + 0x00000010 +#define RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE1M_S 4 +#define RFCORE_SFR_MTIRQM_MACTIMER_OVF_PERM \ + 0x00000008 // Enables the MACTIMER_OVF_PER + // interrupt + +#define RFCORE_SFR_MTIRQM_MACTIMER_OVF_PERM_M \ + 0x00000008 +#define RFCORE_SFR_MTIRQM_MACTIMER_OVF_PERM_S 3 +#define RFCORE_SFR_MTIRQM_MACTIMER_COMPARE2M \ + 0x00000004 // Enables the MACTIMER_COMPARE2 + // interrupt + +#define RFCORE_SFR_MTIRQM_MACTIMER_COMPARE2M_M \ + 0x00000004 +#define RFCORE_SFR_MTIRQM_MACTIMER_COMPARE2M_S 2 +#define RFCORE_SFR_MTIRQM_MACTIMER_COMPARE1M \ + 0x00000002 // Enables the MACTIMER_COMPARE1 + // interrupt + +#define RFCORE_SFR_MTIRQM_MACTIMER_COMPARE1M_M \ + 0x00000002 +#define RFCORE_SFR_MTIRQM_MACTIMER_COMPARE1M_S 1 +#define RFCORE_SFR_MTIRQM_MACTIMER_PERM \ + 0x00000001 // Enables the MACTIMER_PER + // interrupt + +#define RFCORE_SFR_MTIRQM_MACTIMER_PERM_M \ + 0x00000001 +#define RFCORE_SFR_MTIRQM_MACTIMER_PERM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTIRQF register. +// +//***************************************************************************** +#define RFCORE_SFR_MTIRQF_MACTIMER_OVF_COMPARE2F \ + 0x00000020 // Set when the MAC Timer overflow + // counter counts to the value set + // at MTovf_cmp2 + +#define RFCORE_SFR_MTIRQF_MACTIMER_OVF_COMPARE2F_M \ + 0x00000020 +#define RFCORE_SFR_MTIRQF_MACTIMER_OVF_COMPARE2F_S 5 +#define RFCORE_SFR_MTIRQF_MACTIMER_OVF_COMPARE1F \ + 0x00000010 // Set when the MAC Timer overflow + // counter counts to the value set + // at Timer 2 MTovf_cmp1 + +#define RFCORE_SFR_MTIRQF_MACTIMER_OVF_COMPARE1F_M \ + 0x00000010 +#define RFCORE_SFR_MTIRQF_MACTIMER_OVF_COMPARE1F_S 4 +#define RFCORE_SFR_MTIRQF_MACTIMER_OVF_PERF \ + 0x00000008 // Set when the MAC Timer overflow + // counter would have counted to a + // value equal to MTovf_per, but + // instead wraps to 0 + +#define RFCORE_SFR_MTIRQF_MACTIMER_OVF_PERF_M \ + 0x00000008 +#define RFCORE_SFR_MTIRQF_MACTIMER_OVF_PERF_S 3 +#define RFCORE_SFR_MTIRQF_MACTIMER_COMPARE2F \ + 0x00000004 // Set when the MAC Timer counter + // counts to the value set at + // MT_cmp2 + +#define RFCORE_SFR_MTIRQF_MACTIMER_COMPARE2F_M \ + 0x00000004 +#define RFCORE_SFR_MTIRQF_MACTIMER_COMPARE2F_S 2 +#define RFCORE_SFR_MTIRQF_MACTIMER_COMPARE1F \ + 0x00000002 // Set when the MAC Timer counter + // counts to the value set at + // MT_cmp1 + +#define RFCORE_SFR_MTIRQF_MACTIMER_COMPARE1F_M \ + 0x00000002 +#define RFCORE_SFR_MTIRQF_MACTIMER_COMPARE1F_S 1 +#define RFCORE_SFR_MTIRQF_MACTIMER_PERF \ + 0x00000001 // Set when the MAC Timer counter + // would have counted to a value + // equal to MT_per, but instead + // wraps to 0 + +#define RFCORE_SFR_MTIRQF_MACTIMER_PERF_M \ + 0x00000001 +#define RFCORE_SFR_MTIRQF_MACTIMER_PERF_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTMSEL register. +// +//***************************************************************************** +#define RFCORE_SFR_MTMSEL_MTMOVFSEL_M \ + 0x00000070 // The value of this register + // selects the internal registers + // that are modified or read when + // accessing MTMOVF0, MTMOVF1, and + // MTMOVF2. 000: MTovf (overflow + // counter) 001: MTovf_cap + // (overflow capture) 010: + // MTovf_per (overflow period) 011: + // MTovf_cmp1 (overflow compare 1) + // 100: MTovf_cmp2 (overflow + // compare 2) 101 to 111: Reserved + +#define RFCORE_SFR_MTMSEL_MTMOVFSEL_S 4 +#define RFCORE_SFR_MTMSEL_MTMSEL_M \ + 0x00000007 // The value of this register + // selects the internal registers + // that are modified or read when + // accessing MTM0 and MTM1. 000: + // MTtim (timer count value) 001: + // MT_cap (timer capture) 010: + // MT_per (timer period) 011: + // MT_cmp1 (timer compare 1) 100: + // MT_cmp2 (timer compare 2) 101 to + // 111: Reserved MTM0 + +#define RFCORE_SFR_MTMSEL_MTMSEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTM0 register. +// +//***************************************************************************** +#define RFCORE_SFR_MTM0_MTM0_M 0x000000FF // Indirectly returns and modifies + // bits [7:0] of an internal + // register depending on the value + // of MTMSEL.MTMSEL. When reading + // the MTM0 register with + // MTMSEL.MTMSEL set to 000 and + // MTCTRL.LATCH_MODE set to 0, the + // timer (MTtim) value is latched. + // When reading the MTM0 register + // with MTMSEL.MTMSEL set to 000 + // and MTCTRL.LATCH_MODE set to 1, + // the timer (MTtim) and overflow + // counter (MTovf) values are + // latched. +#define RFCORE_SFR_MTM0_MTM0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTM1 register. +// +//***************************************************************************** +#define RFCORE_SFR_MTM1_MTM1_M 0x000000FF // Indirectly returns and modifies + // bits [15:8] of an internal + // register, depending on the value + // of MTMSEL.MTMSEL. When reading + // the MTM0 register with + // MTMSEL.MTMSEL set to 000, the + // timer (MTtim) value is latched. + // Reading this register with + // MTMSEL.MTMSEL set to 000 returns + // the latched value of + // MTtim[15:8]. +#define RFCORE_SFR_MTM1_MTM1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTMOVF2 register. +// +//***************************************************************************** +#define RFCORE_SFR_MTMOVF2_MTMOVF2_M \ + 0x000000FF // Indirectly returns and modifies + // bits [23:16] of an internal + // register, depending on the value + // of MTMSEL.MTMOVFSEL. Reading + // this register with + // MTMSEL.MTMOVFSEL set to 000 + // returns the latched value of + // MTovf[23:16]. + +#define RFCORE_SFR_MTMOVF2_MTMOVF2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTMOVF1 register. +// +//***************************************************************************** +#define RFCORE_SFR_MTMOVF1_MTMOVF1_M \ + 0x000000FF // Indirectly returns and modifies + // bits [15:8] of an internal + // register, depending on the value + // of MTMSEL.MTMSEL. Reading this + // register with MTMSEL.MTMOVFSEL + // set to 000 returns the latched + // value of MTovf[15:8]. + +#define RFCORE_SFR_MTMOVF1_MTMOVF1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_MTMOVF0 register. +// +//***************************************************************************** +#define RFCORE_SFR_MTMOVF0_MTMOVF0_M \ + 0x000000FF // Indirectly returns and modifies + // bits [7:0] of an internal + // register, depending on the value + // of MTMSEL.MTMOVFSEL. When + // reading the MTMOVF0 register + // with MTMSEL.MTMOVFSEL set to 000 + // and MTCTRL.LATCH_MODE set to 0, + // the overflow counter value + // (MTovf) is latched. When reading + // the MTM0 register with + // MTMSEL.MTMOVFSEL set to 000 and + // MTCTRL.LATCH_MODE set to 1, the + // overflow counter value (MTovf) + // is latched. + +#define RFCORE_SFR_MTMOVF0_MTMOVF0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_RFDATA register. +// +//***************************************************************************** +#define RFCORE_SFR_RFDATA_RFD_M 0x000000FF // Data written to the register is + // written to the TX FIFO. When + // reading this register, data from + // the RX FIFO is read. +#define RFCORE_SFR_RFDATA_RFD_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_RFERRF register. +// +//***************************************************************************** +#define RFCORE_SFR_RFERRF_STROBEERR \ + 0x00000040 // A command strobe was issued + // when it could not be processed. + // Triggered if trying to disable + // the radio when it is already + // disabled, or when trying to do a + // SACK, SACKPEND, or SNACK command + // when not in active RX. 0: No + // interrupt pending 1: Interrupt + // pending + +#define RFCORE_SFR_RFERRF_STROBEERR_M \ + 0x00000040 +#define RFCORE_SFR_RFERRF_STROBEERR_S 6 +#define RFCORE_SFR_RFERRF_TXUNDERF \ + 0x00000020 // TX FIFO underflowed. 0: No + // interrupt pending 1: Interrupt + // pending + +#define RFCORE_SFR_RFERRF_TXUNDERF_M \ + 0x00000020 +#define RFCORE_SFR_RFERRF_TXUNDERF_S 5 +#define RFCORE_SFR_RFERRF_TXOVERF \ + 0x00000010 // TX FIFO overflowed. 0: No + // interrupt pending 1: Interrupt + // pending + +#define RFCORE_SFR_RFERRF_TXOVERF_M \ + 0x00000010 +#define RFCORE_SFR_RFERRF_TXOVERF_S 4 +#define RFCORE_SFR_RFERRF_RXUNDERF \ + 0x00000008 // RX FIFO underflowed. 0: No + // interrupt pending 1: Interrupt + // pending + +#define RFCORE_SFR_RFERRF_RXUNDERF_M \ + 0x00000008 +#define RFCORE_SFR_RFERRF_RXUNDERF_S 3 +#define RFCORE_SFR_RFERRF_RXOVERF \ + 0x00000004 // RX FIFO overflowed. 0: No + // interrupt pending 1: Interrupt + // pending + +#define RFCORE_SFR_RFERRF_RXOVERF_M \ + 0x00000004 +#define RFCORE_SFR_RFERRF_RXOVERF_S 2 +#define RFCORE_SFR_RFERRF_RXABO 0x00000002 // Reception of a frame was + // aborted. 0: No interrupt pending + // 1: Interrupt pending +#define RFCORE_SFR_RFERRF_RXABO_M \ + 0x00000002 +#define RFCORE_SFR_RFERRF_RXABO_S 1 +#define RFCORE_SFR_RFERRF_NLOCK 0x00000001 // The frequency synthesizer + // failed to achieve lock after + // time-out, or lock is lost during + // reception. The receiver must be + // restarted to clear this error + // situation. 0: No interrupt + // pending 1: Interrupt pending +#define RFCORE_SFR_RFERRF_NLOCK_M \ + 0x00000001 +#define RFCORE_SFR_RFERRF_NLOCK_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_RFIRQF1 register. +// +//***************************************************************************** +#define RFCORE_SFR_RFIRQF1_CSP_WAIT \ + 0x00000020 // Execution continued after a + // wait instruction in CSP. 0: No + // interrupt pending 1: Interrupt + // pending + +#define RFCORE_SFR_RFIRQF1_CSP_WAIT_M \ + 0x00000020 +#define RFCORE_SFR_RFIRQF1_CSP_WAIT_S 5 +#define RFCORE_SFR_RFIRQF1_CSP_STOP \ + 0x00000010 // CSP has stopped program + // execution. 0: No interrupt + // pending 1: Interrupt pending + +#define RFCORE_SFR_RFIRQF1_CSP_STOP_M \ + 0x00000010 +#define RFCORE_SFR_RFIRQF1_CSP_STOP_S 4 +#define RFCORE_SFR_RFIRQF1_CSP_MANINT \ + 0x00000008 // Manual interrupt generated from + // CSP 0: No interrupt pending 1: + // Interrupt pending + +#define RFCORE_SFR_RFIRQF1_CSP_MANINT_M \ + 0x00000008 +#define RFCORE_SFR_RFIRQF1_CSP_MANINT_S 3 +#define RFCORE_SFR_RFIRQF1_RFIDLE \ + 0x00000004 // Radio state-machine has entered + // the IDLE state. 0: No interrupt + // pending 1: Interrupt pending + +#define RFCORE_SFR_RFIRQF1_RFIDLE_M \ + 0x00000004 +#define RFCORE_SFR_RFIRQF1_RFIDLE_S 2 +#define RFCORE_SFR_RFIRQF1_TXDONE \ + 0x00000002 // A complete frame has been + // transmitted. 0: No interrupt + // pending 1: Interrupt pending + +#define RFCORE_SFR_RFIRQF1_TXDONE_M \ + 0x00000002 +#define RFCORE_SFR_RFIRQF1_TXDONE_S 1 +#define RFCORE_SFR_RFIRQF1_TXACKDONE \ + 0x00000001 // An acknowledgement frame has + // been completely transmitted. 0: + // No interrupt pending 1: + // Interrupt pending + +#define RFCORE_SFR_RFIRQF1_TXACKDONE_M \ + 0x00000001 +#define RFCORE_SFR_RFIRQF1_TXACKDONE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_RFIRQF0 register. +// +//***************************************************************************** +#define RFCORE_SFR_RFIRQF0_RXMASKZERO \ + 0x00000080 // The RXENABLE register has gone + // from a nonzero state to an + // all-zero state. 0: No interrupt + // pending 1: Interrupt pending + +#define RFCORE_SFR_RFIRQF0_RXMASKZERO_M \ + 0x00000080 +#define RFCORE_SFR_RFIRQF0_RXMASKZERO_S 7 +#define RFCORE_SFR_RFIRQF0_RXPKTDONE \ + 0x00000040 // A complete frame has been + // received. 0: No interrupt + // pending 1: Interrupt pending + +#define RFCORE_SFR_RFIRQF0_RXPKTDONE_M \ + 0x00000040 +#define RFCORE_SFR_RFIRQF0_RXPKTDONE_S 6 +#define RFCORE_SFR_RFIRQF0_FRAME_ACCEPTED \ + 0x00000020 // Frame has passed frame + // filtering. 0: No interrupt + // pending 1: Interrupt pending + +#define RFCORE_SFR_RFIRQF0_FRAME_ACCEPTED_M \ + 0x00000020 +#define RFCORE_SFR_RFIRQF0_FRAME_ACCEPTED_S 5 +#define RFCORE_SFR_RFIRQF0_SRC_MATCH_FOUND \ + 0x00000010 // Source match is found. 0: No + // interrupt pending 1: Interrupt + // pending + +#define RFCORE_SFR_RFIRQF0_SRC_MATCH_FOUND_M \ + 0x00000010 +#define RFCORE_SFR_RFIRQF0_SRC_MATCH_FOUND_S 4 +#define RFCORE_SFR_RFIRQF0_SRC_MATCH_DONE \ + 0x00000008 // Source matching is complete. 0: + // No interrupt pending 1: + // Interrupt pending + +#define RFCORE_SFR_RFIRQF0_SRC_MATCH_DONE_M \ + 0x00000008 +#define RFCORE_SFR_RFIRQF0_SRC_MATCH_DONE_S 3 +#define RFCORE_SFR_RFIRQF0_FIFOP \ + 0x00000004 // The number of bytes in the RX + // FIFO is greater than the + // threshold. Also raised when a + // complete frame is received, and + // when a packet is read out + // completely and more complete + // packets are available. 0: No + // interrupt pending 1: Interrupt + // pending + +#define RFCORE_SFR_RFIRQF0_FIFOP_M \ + 0x00000004 +#define RFCORE_SFR_RFIRQF0_FIFOP_S 2 +#define RFCORE_SFR_RFIRQF0_SFD 0x00000002 // SFD has been received or + // transmitted. 0: No interrupt + // pending 1: Interrupt pending +#define RFCORE_SFR_RFIRQF0_SFD_M \ + 0x00000002 +#define RFCORE_SFR_RFIRQF0_SFD_S 1 +#define RFCORE_SFR_RFIRQF0_ACT_UNUSED \ + 0x00000001 // Reserved 0: No interrupt + // pending 1: Interrupt pending + +#define RFCORE_SFR_RFIRQF0_ACT_UNUSED_M \ + 0x00000001 +#define RFCORE_SFR_RFIRQF0_ACT_UNUSED_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_SFR_RFST register. +// +//***************************************************************************** +#define RFCORE_SFR_RFST_INSTR_M 0x000000FF // Data written to this register + // is written to the CSP + // instruction memory. Reading this + // register returns the CSP + // instruction currently being + // executed. +#define RFCORE_SFR_RFST_INSTR_S 0 + + +#endif // __HW_RFCORE_SFR_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_rfcore_xreg.h b/bsp/boards/mimsy2-cc2538/headers/hw_rfcore_xreg.h new file mode 100644 index 0000000000..4abb6b18fd --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_rfcore_xreg.h @@ -0,0 +1,2434 @@ +/****************************************************************************** +* Filename: hw_rfcore_xreg.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_RFCORE_XREG_H__ +#define __HW_RFCORE_XREG_H__ + +//***************************************************************************** +// +// The following are defines for the RFCORE_XREG register offsets. +// +//***************************************************************************** +#define RFCORE_XREG_FRMFILT0 0x40088600 // The frame filtering function + // rejects unintended frames as + // specified by IEEE 802.15.4, + // section 7.5.6.2, third filtering + // level. In addition, it provides + // filtering on: - The eight + // different frame types (see the + // FRMFILT1 register) - The + // reserved bits in the frame + // control field (FCF) The function + // is controlled by: - The FRMFILT0 + // and FRMFILT1 registers - The + // PAN_ID, SHORT_ADDR, and EXT_ADDR + // values in RAM +#define RFCORE_XREG_FRMFILT1 0x40088604 // The frame filtering function + // rejects unintended frames as + // specified by IEEE 802.15.4, + // section 7.5.6.2, third filtering + // level. In addition, it provides + // filtering on: - The eight + // different frame types (see the + // FRMFILT1 register) - The + // reserved bits in the frame + // control field (FCF) The function + // is controlled by: - The FRMFILT0 + // and FRMFILT1 registers - The + // PAN_ID, SHORT_ADDR, and EXT_ADDR + // values in RAM +#define RFCORE_XREG_SRCMATCH 0x40088608 // Source address matching and + // pending bits +#define RFCORE_XREG_SRCSHORTEN0 \ + 0x4008860C // Short address matching + +#define RFCORE_XREG_SRCSHORTEN1 \ + 0x40088610 // Short address matching + +#define RFCORE_XREG_SRCSHORTEN2 \ + 0x40088614 // Short address matching + +#define RFCORE_XREG_SRCEXTEN0 0x40088618 // Extended address matching +#define RFCORE_XREG_SRCEXTEN1 0x4008861C // Extended address matching +#define RFCORE_XREG_SRCEXTEN2 0x40088620 // Extended address matching +#define RFCORE_XREG_FRMCTRL0 0x40088624 // Frame handling +#define RFCORE_XREG_FRMCTRL1 0x40088628 // Frame handling +#define RFCORE_XREG_RXENABLE 0x4008862C // RX enabling +#define RFCORE_XREG_RXMASKSET 0x40088630 // RX enabling +#define RFCORE_XREG_RXMASKCLR 0x40088634 // RX disabling +#define RFCORE_XREG_FREQTUNE 0x40088638 // Crystal oscillator frequency + // tuning +#define RFCORE_XREG_FREQCTRL 0x4008863C // Controls the RF frequency +#define RFCORE_XREG_TXPOWER 0x40088640 // Controls the output power +#define RFCORE_XREG_TXCTRL 0x40088644 // Controls the TX settings +#define RFCORE_XREG_FSMSTAT0 0x40088648 // Radio status register +#define RFCORE_XREG_FSMSTAT1 0x4008864C // Radio status register +#define RFCORE_XREG_FIFOPCTRL 0x40088650 // FIFOP threshold +#define RFCORE_XREG_FSMCTRL 0x40088654 // FSM options +#define RFCORE_XREG_CCACTRL0 0x40088658 // CCA threshold +#define RFCORE_XREG_CCACTRL1 0x4008865C // Other CCA Options +#define RFCORE_XREG_RSSI 0x40088660 // RSSI status register +#define RFCORE_XREG_RSSISTAT 0x40088664 // RSSI valid status register +#define RFCORE_XREG_RXFIRST 0x40088668 // First byte in RX FIFO +#define RFCORE_XREG_RXFIFOCNT 0x4008866C // Number of bytes in RX FIFO +#define RFCORE_XREG_TXFIFOCNT 0x40088670 // Number of bytes in TX FIFO +#define RFCORE_XREG_RXFIRST_PTR \ + 0x40088674 // RX FIFO pointer + +#define RFCORE_XREG_RXLAST_PTR \ + 0x40088678 // RX FIFO pointer + +#define RFCORE_XREG_RXP1_PTR 0x4008867C // RX FIFO pointer +#define RFCORE_XREG_TXFIRST_PTR \ + 0x40088684 // TX FIFO pointer + +#define RFCORE_XREG_TXLAST_PTR \ + 0x40088688 // TX FIFO pointer + +#define RFCORE_XREG_RFIRQM0 0x4008868C // RF interrupt masks +#define RFCORE_XREG_RFIRQM1 0x40088690 // RF interrupt masks +#define RFCORE_XREG_RFERRM 0x40088694 // RF error interrupt mask +#define RFCORE_XREG_RFRND 0x4008869C // Random data +#define RFCORE_XREG_MDMCTRL0 0x400886A0 // Controls modem +#define RFCORE_XREG_MDMCTRL1 0x400886A4 // Controls modem +#define RFCORE_XREG_FREQEST 0x400886A8 // Estimated RF frequency offset +#define RFCORE_XREG_RXCTRL 0x400886AC // Tune receive section +#define RFCORE_XREG_FSCTRL 0x400886B0 // Tune frequency synthesizer +#define RFCORE_XREG_FSCAL0 0x400886B4 // Tune frequency calibration +#define RFCORE_XREG_FSCAL1 0x400886B8 // Tune frequency calibration +#define RFCORE_XREG_FSCAL2 0x400886BC // Tune frequency calibration +#define RFCORE_XREG_FSCAL3 0x400886C0 // Tune frequency calibration +#define RFCORE_XREG_AGCCTRL0 0x400886C4 // AGC dynamic range control +#define RFCORE_XREG_AGCCTRL1 0x400886C8 // AGC reference level +#define RFCORE_XREG_AGCCTRL2 0x400886CC // AGC gain override +#define RFCORE_XREG_AGCCTRL3 0x400886D0 // AGC control +#define RFCORE_XREG_ADCTEST0 0x400886D4 // ADC tuning +#define RFCORE_XREG_ADCTEST1 0x400886D8 // ADC tuning +#define RFCORE_XREG_ADCTEST2 0x400886DC // ADC tuning +#define RFCORE_XREG_MDMTEST0 0x400886E0 // Test register for modem +#define RFCORE_XREG_MDMTEST1 0x400886E4 // Test Register for Modem +#define RFCORE_XREG_DACTEST0 0x400886E8 // DAC override value +#define RFCORE_XREG_DACTEST1 0x400886EC // DAC override value +#define RFCORE_XREG_DACTEST2 0x400886F0 // DAC test setting +#define RFCORE_XREG_ATEST 0x400886F4 // Analog test control +#define RFCORE_XREG_PTEST0 0x400886F8 // Override power-down register +#define RFCORE_XREG_PTEST1 0x400886FC // Override power-down register +#define RFCORE_XREG_CSPPROG0 0x40088700 // CSP program +#define RFCORE_XREG_CSPPROG1 0x40088704 // CSP program +#define RFCORE_XREG_CSPPROG2 0x40088708 // CSP program +#define RFCORE_XREG_CSPPROG3 0x4008870C // CSP program +#define RFCORE_XREG_CSPPROG4 0x40088710 // CSP program +#define RFCORE_XREG_CSPPROG5 0x40088714 // CSP program +#define RFCORE_XREG_CSPPROG6 0x40088718 // CSP program +#define RFCORE_XREG_CSPPROG7 0x4008871C // CSP program +#define RFCORE_XREG_CSPPROG8 0x40088720 // CSP program +#define RFCORE_XREG_CSPPROG9 0x40088724 // CSP program +#define RFCORE_XREG_CSPPROG10 0x40088728 // CSP program +#define RFCORE_XREG_CSPPROG11 0x4008872C // CSP program +#define RFCORE_XREG_CSPPROG12 0x40088730 // CSP program +#define RFCORE_XREG_CSPPROG13 0x40088734 // CSP program +#define RFCORE_XREG_CSPPROG14 0x40088738 // CSP program +#define RFCORE_XREG_CSPPROG15 0x4008873C // CSP program +#define RFCORE_XREG_CSPPROG16 0x40088740 // CSP program +#define RFCORE_XREG_CSPPROG17 0x40088744 // CSP program +#define RFCORE_XREG_CSPPROG18 0x40088748 // CSP program +#define RFCORE_XREG_CSPPROG19 0x4008874C // CSP program +#define RFCORE_XREG_CSPPROG20 0x40088750 // CSP program +#define RFCORE_XREG_CSPPROG21 0x40088754 // CSP program +#define RFCORE_XREG_CSPPROG22 0x40088758 // CSP program +#define RFCORE_XREG_CSPPROG23 0x4008875C // CSP program +#define RFCORE_XREG_CSPCTRL 0x40088780 // CSP control bit +#define RFCORE_XREG_CSPSTAT 0x40088784 // CSP status register +#define RFCORE_XREG_CSPX 0x40088788 // CSP X data register +#define RFCORE_XREG_CSPY 0x4008878C // CSP Y data register +#define RFCORE_XREG_CSPZ 0x40088790 // CSP Z data register +#define RFCORE_XREG_CSPT 0x40088794 // CSP T data register +#define RFCORE_XREG_RFC_OBS_CTRL0 \ + 0x400887AC // RF observation mux control + +#define RFCORE_XREG_RFC_OBS_CTRL1 \ + 0x400887B0 // RF observation mux control + +#define RFCORE_XREG_RFC_OBS_CTRL2 \ + 0x400887B4 // RF observation mux control + +#define RFCORE_XREG_TXFILTCFG 0x400887E8 // TX filter configuration + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FRMFILT0 register. +// +//***************************************************************************** +#define RFCORE_XREG_FRMFILT0_MAX_FRAME_VERSION_M \ + 0x0000000C // Used for filtering on the frame + // version field of the frame + // control field (FCF) If + // FCF[13:12] (the frame version + // subfield) is higher than + // MAX_FRAME_VERSION[1:0] and frame + // filtering is enabled, the frame + // is rejected. + +#define RFCORE_XREG_FRMFILT0_MAX_FRAME_VERSION_S 2 +#define RFCORE_XREG_FRMFILT0_PAN_COORDINATOR \ + 0x00000002 // Should be set high when the + // device is a PAN coordinator, to + // accept frames with no + // destination address (as + // specified in Section 7.5.6.2 in + // IEEE 802.15.4) 0: Device is not + // a PAN coordinator 1: Device is a + // PAN coordinator + +#define RFCORE_XREG_FRMFILT0_PAN_COORDINATOR_M \ + 0x00000002 +#define RFCORE_XREG_FRMFILT0_PAN_COORDINATOR_S 1 +#define RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN \ + 0x00000001 // Enables frame filtering When + // this bit is set, the radio + // performs frame filtering as + // specified in section 7.5.6.2 of + // IEEE 802.15.4(b), third + // filtering level. FRMFILT0[6:1] + // and FRMFILT1[7:1], together with + // the local address information, + // define the behavior of the + // filtering algorithm. 0: Frame + // filtering off. (FRMFILT0[6:1], + // FRMFILT1[7:1] and SRCMATCH[2:0] + // are don't care.) 1: Frame + // filtering on. + +#define RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN_M \ + 0x00000001 +#define RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FRMFILT1 register. +// +//***************************************************************************** +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_3_MAC_CMD \ + 0x00000040 // Defines whether MAC command + // frames are accepted or not. MAC + // command frames have frame type = + // 011. 0: Reject 1: Accept + +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_3_MAC_CMD_M \ + 0x00000040 +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_3_MAC_CMD_S 6 +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_2_ACK \ + 0x00000020 // Defines whether acknowledgment + // frames are accepted or not. + // Acknowledgement frames have + // frame type = 010. 0: Reject 1: + // Accept + +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_2_ACK_M \ + 0x00000020 +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_2_ACK_S 5 +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_1_DATA \ + 0x00000010 // Defines whether data frames are + // accepted or not. Data frames + // have frame type = 001. 0: Reject + // 1: Accept + +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_1_DATA_M \ + 0x00000010 +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_1_DATA_S 4 +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_0_BEACON \ + 0x00000008 // Defines whether beacon frames + // are accepted or not. Beacon + // frames have frame type = 000. 0: + // Reject 1: Accept + +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_0_BEACON_M \ + 0x00000008 +#define RFCORE_XREG_FRMFILT1_ACCEPT_FT_0_BEACON_S 3 +#define RFCORE_XREG_FRMFILT1_MODIFY_FT_FILTER_M \ + 0x00000006 // These bits are used to modify + // the frame type field of a + // received frame before frame type + // filtering is performed. The + // modification does not influence + // the frame that is written to the + // RX FIFO. 00: Leave the frame + // type as it is. 01: Invert MSB of + // the frame type. 10: Set MSB of + // the frame type to 0. 11: Set MSB + // of the frame type to 1. + +#define RFCORE_XREG_FRMFILT1_MODIFY_FT_FILTER_S 1 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_SRCMATCH register. +// +//***************************************************************************** +#define RFCORE_XREG_SRCMATCH_PEND_DATAREQ_ONLY \ + 0x00000004 // When this bit is set, the + // AUTOPEND function also requires + // that the received frame is a + // DATA REQUEST MAC command frame. + +#define RFCORE_XREG_SRCMATCH_PEND_DATAREQ_ONLY_M \ + 0x00000004 +#define RFCORE_XREG_SRCMATCH_PEND_DATAREQ_ONLY_S 2 +#define RFCORE_XREG_SRCMATCH_AUTOPEND \ + 0x00000002 // Automatic acknowledgment + // pending flag enable When a frame + // is received, the pending bit in + // the (possibly) returned + // acknowledgment is set + // automatically when the following + // conditions are met: - + // FRMFILT.FRAME_FILTER_EN is set. + // - SRCMATCH.SRC_MATCH_EN is set. + // - SRCMATCH.AUTOPEND is set. - + // The received frame matches the + // current + // SRCMATCH.PEND_DATAREQ_ONLY + // setting. - The received source + // address matches at least one + // source match table entry, which + // is enabled in SHORT_ADDR_EN and + // SHORT_PEND_EN or in EXT_ADDR_EN + // and EXT_PEND_EN. + +#define RFCORE_XREG_SRCMATCH_AUTOPEND_M \ + 0x00000002 +#define RFCORE_XREG_SRCMATCH_AUTOPEND_S 1 +#define RFCORE_XREG_SRCMATCH_SRC_MATCH_EN \ + 0x00000001 // Source address matching enable + // (requires that + // FRMFILT.FRAME_FILTER_EN = 1) + +#define RFCORE_XREG_SRCMATCH_SRC_MATCH_EN_M \ + 0x00000001 +#define RFCORE_XREG_SRCMATCH_SRC_MATCH_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_SRCSHORTEN0 register. +// +//***************************************************************************** +#define RFCORE_XREG_SRCSHORTEN0_SHORT_ADDR_EN_M \ + 0x000000FF // 7:0 part of the 24-bit word + // SHORT_ADDR_EN that enables or + // disables source address matching + // for each of the 24 short address + // table entries Optional safety + // feature: To ensure that an entry + // in the source matching table is + // not used while it is being + // updated, set the corresponding + // SHORT_ADDR_EN bit to 0 while + // updating. + +#define RFCORE_XREG_SRCSHORTEN0_SHORT_ADDR_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_SRCSHORTEN1 register. +// +//***************************************************************************** +#define RFCORE_XREG_SRCSHORTEN1_SHORT_ADDR_EN_M \ + 0x000000FF // 15:8 part of the 24-bit word + // SHORT_ADDR_EN See description of + // SRCSHORTEN0.SHORT_ADDR_EN. + +#define RFCORE_XREG_SRCSHORTEN1_SHORT_ADDR_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_SRCSHORTEN2 register. +// +//***************************************************************************** +#define RFCORE_XREG_SRCSHORTEN2_SHORT_ADDR_EN_M \ + 0x000000FF // 23:16 part of the 24-bit word + // SHORT_ADDR_EN See description of + // SRCSHORTEN0.SHORT_ADDR_EN. + +#define RFCORE_XREG_SRCSHORTEN2_SHORT_ADDR_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_SRCEXTEN0 register. +// +//***************************************************************************** +#define RFCORE_XREG_SRCEXTEN0_EXT_ADDR_EN_M \ + 0x000000FF // 7:0 part of the 24-bit word + // EXT_ADDR_EN that enables or + // disables source address matching + // for each of the 12 extended + // address table entries Write + // access: Extended address enable + // for table entry n (0 to 11) is + // mapped to EXT_ADDR_EN[2n]. All + // EXT_ADDR_EN[2n + 1] bits are + // read only. Read access: Extended + // address enable for table entry n + // (0 to 11) is mapped to + // EXT_ADDR_EN[2n] and + // EXT_ADDR_EN[2n + 1]. Optional + // safety feature: To ensure that + // an entry in the source matching + // table is not used while it is + // being updated, set the + // corresponding EXT_ADDR_EN bit to + // 0 while updating. + +#define RFCORE_XREG_SRCEXTEN0_EXT_ADDR_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_SRCEXTEN1 register. +// +//***************************************************************************** +#define RFCORE_XREG_SRCEXTEN1_EXT_ADDR_EN_M \ + 0x000000FF // 15:8 part of the 24-bit word + // EXT_ADDR_EN See description of + // SRCEXTEN0.EXT_ADDR_EN. + +#define RFCORE_XREG_SRCEXTEN1_EXT_ADDR_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_SRCEXTEN2 register. +// +//***************************************************************************** +#define RFCORE_XREG_SRCEXTEN2_EXT_ADDR_EN_M \ + 0x000000FF // 23:16 part of the 24-bit word + // EXT_ADDR_EN See description of + // SRCEXTEN0.EXT_ADDR_EN. + +#define RFCORE_XREG_SRCEXTEN2_EXT_ADDR_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FRMCTRL0 register. +// +//***************************************************************************** +#define RFCORE_XREG_FRMCTRL0_APPEND_DATA_MODE \ + 0x00000080 // When AUTOCRC = 0: Don't care + // When AUTOCRC = 1: 0: RSSI + The + // CRC_OK bit and the 7-bit + // correlation value are appended + // at the end of each received + // frame 1: RSSI + The CRC_OK bit + // and the 7-bit SRCRESINDEX are + // appended at the end of each + // received frame. + +#define RFCORE_XREG_FRMCTRL0_APPEND_DATA_MODE_M \ + 0x00000080 +#define RFCORE_XREG_FRMCTRL0_APPEND_DATA_MODE_S 7 +#define RFCORE_XREG_FRMCTRL0_AUTOCRC \ + 0x00000040 // In TX 1: A CRC-16 (ITU-T) is + // generated in hardware and + // appended to the transmitted + // frame. There is no need to write + // the last 2 bytes to TXBUF. 0: No + // CRC-16 is appended to the frame. + // The last 2 bytes of the frame + // must be generated manually and + // written to TXBUF (if not, + // TX_UNDERFLOW occurs). In RX 1: + // The CRC-16 is checked in + // hardware, and replaced in the + // RXFIFO by a 16-bit status word + // which contains a CRC OK bit. The + // status word is controllable + // through APPEND_DATA_MODE. 0: The + // last 2 bytes of the frame + // (CRC-16 field) are stored in the + // RX FIFO. The CRC (if any) must + // be done manually. This setting + // does not influence + // acknowledgment transmission + // (including AUTOACK). + +#define RFCORE_XREG_FRMCTRL0_AUTOCRC_M \ + 0x00000040 +#define RFCORE_XREG_FRMCTRL0_AUTOCRC_S 6 +#define RFCORE_XREG_FRMCTRL0_AUTOACK \ + 0x00000020 // Defines whether the radio + // automatically transmits + // acknowledge frames or not. When + // autoack is enabled, all frames + // that are accepted by address + // filtering, have the acknowledge + // request flag set, and have a + // valid CRC are automatically + // acknowledged 12 symbol periods + // after being received. 0: Autoack + // disabled 1: Autoack enabled + +#define RFCORE_XREG_FRMCTRL0_AUTOACK_M \ + 0x00000020 +#define RFCORE_XREG_FRMCTRL0_AUTOACK_S 5 +#define RFCORE_XREG_FRMCTRL0_ENERGY_SCAN \ + 0x00000010 // Defines whether the RSSI + // register contains the + // most-recent signal strength or + // the peak signal strength since + // the energy scan was enabled. 0: + // Most-recent signal strength 1: + // Peak signal strength + +#define RFCORE_XREG_FRMCTRL0_ENERGY_SCAN_M \ + 0x00000010 +#define RFCORE_XREG_FRMCTRL0_ENERGY_SCAN_S 4 +#define RFCORE_XREG_FRMCTRL0_RX_MODE_M \ + 0x0000000C // Set RX modes. 00: Normal + // operation, use RX FIFO 01: + // Receive serial mode, output + // received data on to IOC; + // infinite RX 10: RX FIFO looping + // ignore overflow in RX FIFO; + // infinite reception 11: Same as + // normal operation except that + // symbol search is disabled. Can + // be used for RSSI or CCA + // measurements when finding symbol + // is not desired. + +#define RFCORE_XREG_FRMCTRL0_RX_MODE_S 2 +#define RFCORE_XREG_FRMCTRL0_TX_MODE_M \ + 0x00000003 // Set test modes for TX. 00: + // Normal operation, transmit TX + // FIFO 01: Reserved, should not be + // used 10: TX FIFO looping ignore + // underflow in TX FIFO and read + // cyclic; infinite transmission + // 11: Send random data from CRC; + // infinite transmission + +#define RFCORE_XREG_FRMCTRL0_TX_MODE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FRMCTRL1 register. +// +//***************************************************************************** +#define RFCORE_XREG_FRMCTRL1_PENDING_OR \ + 0x00000004 // Defines whether the pending + // data bit in outgoing + // acknowledgment frames is always + // set to 1 or controlled by the + // main FSM and the address + // filtering 0: Pending data bit is + // controlled by main FSM and + // address filtering. 1: Pending + // data bit is always 1. + +#define RFCORE_XREG_FRMCTRL1_PENDING_OR_M \ + 0x00000004 +#define RFCORE_XREG_FRMCTRL1_PENDING_OR_S 2 +#define RFCORE_XREG_FRMCTRL1_IGNORE_TX_UNDERF \ + 0x00000002 // Defines whether or not TX + // underflow should be ignored 0: + // Normal TX operation. TX + // underflow is detected and TX is + // aborted if underflow occurs. 1: + // Ignore TX underflow. Transmit + // the number of bytes given by the + // frame-length field. + +#define RFCORE_XREG_FRMCTRL1_IGNORE_TX_UNDERF_M \ + 0x00000002 +#define RFCORE_XREG_FRMCTRL1_IGNORE_TX_UNDERF_S 1 +#define RFCORE_XREG_FRMCTRL1_SET_RXENMASK_ON_TX \ + 0x00000001 // Defines whether STXON sets bit + // 6 in the RXENABLE register or + // leaves it unchanged 0: Does not + // affect RXENABLE 1: Sets bit 6 in + // RXENABLE. Used for backward + // compatibility with the CC2420. + +#define RFCORE_XREG_FRMCTRL1_SET_RXENMASK_ON_TX_M \ + 0x00000001 +#define RFCORE_XREG_FRMCTRL1_SET_RXENMASK_ON_TX_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RXENABLE register. +// +//***************************************************************************** +#define RFCORE_XREG_RXENABLE_RXENMASK_M \ + 0x000000FF // RXENABLE enables the receiver. + // A nonzero value in this register + // causes FFCTRL to enable the + // receiver when in idle, after + // transmission and after + // acknowledgement transmission. + // The following strobes can modify + // RXENMASK: SRXON: Set bit 7 in + // RXENMASK. STXON: Set bit 6 in + // RXENMASK if SET_RXENMASK_ON_TX = + // 1. SRFOFF: Clears all bits in + // RXENMASK. SRXMASKBITSET: Set bit + // 5 in RXENMASK. SRXMASKBITCLR: + // Clear bit 5 in RXENMASK. There + // could be conflicts between the + // CSP and xreg_bus write + // operations if both operations + // try to modify RXENMASK + // simultaneously. To handle the + // case of simultaneous access to + // RXENMASK the following rules + // apply: - If the two sources + // agree (they modify different + // parts of the register) both of + // their requests to modify + // RXENMASK are processed. - If + // both operations try to modify + // the mask simultaneously, bus + // write operations to RXMASKSET + // and RXMASKCLR have priority over + // the CSP. This situation must be + // avoided. + +#define RFCORE_XREG_RXENABLE_RXENMASK_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RXMASKSET register. +// +//***************************************************************************** +#define RFCORE_XREG_RXMASKSET_RXENMASKSET_M \ + 0x000000FF // When written, the written data + // is ORed with the RXENMASK and + // stored in RXENMASK. + +#define RFCORE_XREG_RXMASKSET_RXENMASKSET_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RXMASKCLR register. +// +//***************************************************************************** +#define RFCORE_XREG_RXMASKCLR_RXENMASKCLR_M \ + 0x000000FF // When written, the written data + // is inverted and ANDed with the + // RXENMASK and stored in RXENMASK. + // For example, if 1 is written to + // one or more bit positions in + // this register, the corresponding + // bits are cleared in RXENMASK. + +#define RFCORE_XREG_RXMASKCLR_RXENMASKCLR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FREQTUNE register. +// +//***************************************************************************** +#define RFCORE_XREG_FREQTUNE_XOSC32M_TUNE_M \ + 0x0000000F // Tune crystal oscillator The + // default setting 1111 leaves the + // XOSC untuned. Changing the + // setting from the default setting + // (1111) switches in extra + // capacitance to the oscillator, + // effectively lowering the XOSC + // frequency. Hence, a higher + // setting gives a higher + // frequency. + +#define RFCORE_XREG_FREQTUNE_XOSC32M_TUNE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FREQCTRL register. +// +//***************************************************************************** +#define RFCORE_XREG_FREQCTRL_FREQ_M \ + 0x0000007F // Frequency control word The + // frequency word in FREQ[6:0] is + // an offset value from 2394 (fRF = + // FREQ[6 0] + 2394). The + // RF-frequency is specified from + // 2405 to 2480 MHz in 1-MHz steps; + // hence, the only valid settings + // for FREQ[6:0] are 11 to 86 (11 + + // 2394 = 2405 and 86 + 2394 = + // 2480). The device supports the + // frequency range from 2394 to + // 2507 MHz. Consequently, the + // usable settings for FREQ[6:0] + // are 0 to 113. Settings outside + // of the usable range (114 to 127) + // give a frequency of 2507 MHz. + // IEEE 802.15.4-2006 specifies a + // frequency range from 2405 MHz to + // 2480 MHz with 16 channels 5 MHz + // apart. The channels are numbered + // 11 through 26. For an IEEE + // 802.15.4-2006 compliant system, + // the only valid settings are thus + // FREQ[6:0] = 11 + 5 (channel + // number - 11). + +#define RFCORE_XREG_FREQCTRL_FREQ_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_TXPOWER register. +// +//***************************************************************************** +#define RFCORE_XREG_TXPOWER_PA_POWER_M \ + 0x000000F0 // PA power control + +#define RFCORE_XREG_TXPOWER_PA_POWER_S 4 +#define RFCORE_XREG_TXPOWER_PA_BIAS_M \ + 0x0000000F // PA bias control + +#define RFCORE_XREG_TXPOWER_PA_BIAS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_TXCTRL register. +// +//***************************************************************************** +#define RFCORE_XREG_TXCTRL_DAC_CURR_M \ + 0x00000070 // Change the current in the DAC. + +#define RFCORE_XREG_TXCTRL_DAC_CURR_S 4 +#define RFCORE_XREG_TXCTRL_DAC_DC_M \ + 0x0000000C // Adjusts the DC level to the TX + // mixer. + +#define RFCORE_XREG_TXCTRL_DAC_DC_S 2 +#define RFCORE_XREG_TXCTRL_TXMIX_CURRENT_M \ + 0x00000003 // Transmit mixers core current + // Current increases with + // increasing setting. + +#define RFCORE_XREG_TXCTRL_TXMIX_CURRENT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FSMSTAT0 register. +// +//***************************************************************************** +#define RFCORE_XREG_FSMSTAT0_CAL_DONE \ + 0x00000080 // Frequency synthesis calibration + // has been performed since the + // last time the FS was turned on. + +#define RFCORE_XREG_FSMSTAT0_CAL_DONE_M \ + 0x00000080 +#define RFCORE_XREG_FSMSTAT0_CAL_DONE_S 7 +#define RFCORE_XREG_FSMSTAT0_CAL_RUNNING \ + 0x00000040 // Frequency synthesis calibration + // status 0: Calibration is + // complete or not started. 1: + // Calibration is in progress. + +#define RFCORE_XREG_FSMSTAT0_CAL_RUNNING_M \ + 0x00000040 +#define RFCORE_XREG_FSMSTAT0_CAL_RUNNING_S 6 +#define RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE_M \ + 0x0000003F // Gives the current state of the + // FIFO and frame control (FFCTRL) + // finite state-machine. + +#define RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FSMSTAT1 register. +// +//***************************************************************************** +#define RFCORE_XREG_FSMSTAT1_FIFO \ + 0x00000080 // FIFO is high when there is data + // in the RX FIFO. FIFO is low + // during RX FIFO overflow. + +#define RFCORE_XREG_FSMSTAT1_FIFO_M \ + 0x00000080 +#define RFCORE_XREG_FSMSTAT1_FIFO_S 7 +#define RFCORE_XREG_FSMSTAT1_FIFOP \ + 0x00000040 // FIFOP is set high when there + // are at more than FIFOP_THR bytes + // of data in the RX FIFO that has + // passed frame filtering. FIFOP is + // set high when there is at least + // one complete frame in the RX + // FIFO. FIFOP is high during RX + // FIFO overflow. + +#define RFCORE_XREG_FSMSTAT1_FIFOP_M \ + 0x00000040 +#define RFCORE_XREG_FSMSTAT1_FIFOP_S 6 +#define RFCORE_XREG_FSMSTAT1_SFD \ + 0x00000020 // In TX 0: When a complete frame + // with SFD was sent or no SFD was + // sent 1: SFD was sent. In RX 0: + // When a complete frame was + // received or no SFD was received + // 1: SFD was received. + +#define RFCORE_XREG_FSMSTAT1_SFD_M \ + 0x00000020 +#define RFCORE_XREG_FSMSTAT1_SFD_S 5 +#define RFCORE_XREG_FSMSTAT1_CCA \ + 0x00000010 // Clear channel assessment + // Dependent on CCA_MODE settings. + // See CCACTRL1 for details. + +#define RFCORE_XREG_FSMSTAT1_CCA_M \ + 0x00000010 +#define RFCORE_XREG_FSMSTAT1_CCA_S 4 +#define RFCORE_XREG_FSMSTAT1_SAMPLED_CCA \ + 0x00000008 // Contains a sampled value of the + // CCA The value is updated when a + // SSAMPLECCA or STXONCCA strobe is + // issued. + +#define RFCORE_XREG_FSMSTAT1_SAMPLED_CCA_M \ + 0x00000008 +#define RFCORE_XREG_FSMSTAT1_SAMPLED_CCA_S 3 +#define RFCORE_XREG_FSMSTAT1_LOCK_STATUS \ + 0x00000004 // 1 when PLL is in lock; + // otherwise 0 + +#define RFCORE_XREG_FSMSTAT1_LOCK_STATUS_M \ + 0x00000004 +#define RFCORE_XREG_FSMSTAT1_LOCK_STATUS_S 2 +#define RFCORE_XREG_FSMSTAT1_TX_ACTIVE \ + 0x00000002 // Status signal Active when FFC + // is in one of the transmit states + +#define RFCORE_XREG_FSMSTAT1_TX_ACTIVE_M \ + 0x00000002 +#define RFCORE_XREG_FSMSTAT1_TX_ACTIVE_S 1 +#define RFCORE_XREG_FSMSTAT1_RX_ACTIVE \ + 0x00000001 // Status signal Active when FFC + // is in one of the receive states + +#define RFCORE_XREG_FSMSTAT1_RX_ACTIVE_M \ + 0x00000001 +#define RFCORE_XREG_FSMSTAT1_RX_ACTIVE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FIFOPCTRL register. +// +//***************************************************************************** +#define RFCORE_XREG_FIFOPCTRL_FIFOP_THR_M \ + 0x0000007F // Threshold used when generating + // FIFOP signal + +#define RFCORE_XREG_FIFOPCTRL_FIFOP_THR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FSMCTRL register. +// +//***************************************************************************** +#define RFCORE_XREG_FSMCTRL_SLOTTED_ACK \ + 0x00000002 // Controls timing of transmission + // of acknowledge frames 0: The + // acknowledge frame is sent 12 + // symbol periods after the end of + // the received frame which + // requests the aknowledge. 1: The + // acknowledge frame is sent at the + // first backoff-slot boundary more + // than 12 symbol periods after the + // end of the received frame which + // requests the aknowledge. + +#define RFCORE_XREG_FSMCTRL_SLOTTED_ACK_M \ + 0x00000002 +#define RFCORE_XREG_FSMCTRL_SLOTTED_ACK_S 1 +#define RFCORE_XREG_FSMCTRL_RX2RX_TIME_OFF \ + 0x00000001 // Defines whether or not a + // 12-symbol time-out should be + // used after frame reception has + // ended. 0: No time-out 1: + // 12-symbol-period time-out + +#define RFCORE_XREG_FSMCTRL_RX2RX_TIME_OFF_M \ + 0x00000001 +#define RFCORE_XREG_FSMCTRL_RX2RX_TIME_OFF_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CCACTRL0 register. +// +//***************************************************************************** +#define RFCORE_XREG_CCACTRL0_CCA_THR_M \ + 0x000000FF // Clear-channel-assessment + // threshold value, signed + // 2's-complement number for + // comparison with the RSSI. The + // unit is 1 dB, offset is 73dB The + // CCA signal goes high when the + // received signal is below this + // value. The CCA signal is + // available on the CCA pin and in + // the FSMSTAT1 register. The value + // must never be set lower than + // CCA_HYST - 128 to avoid + // erroneous behavior of the CCA + // signal. Note: The reset value + // translates to an input level of + // approximately -32 - 73 = -105 + // dBm, which is well below the + // sensitivity limit. This means + // that the CCA signal never + // indicates a clear channel. This + // register should be updated to + // 0xF8, which translates to an + // input level of about -8 - 73 = + // -81 dBm. + +#define RFCORE_XREG_CCACTRL0_CCA_THR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CCACTRL1 register. +// +//***************************************************************************** +#define RFCORE_XREG_CCACTRL1_CCA_MODE_M \ + 0x00000018 // 00: CCA always set to 1 01: CCA + // = 1 when RSSI < CCA_THR - + // CCA_HYST; CCA = 0 when RSSI >= + // CCA_THR 10: CCA = 1 when not + // receiving a frame, else CCA = 0 + // 11: CCA = 1 when RSSI < CCA_THR + // - CCA_HYST and not receiving a + // frame; CCA = 0 when RSSI >= + // CCA_THR or when receiving a + // frame + +#define RFCORE_XREG_CCACTRL1_CCA_MODE_S 3 +#define RFCORE_XREG_CCACTRL1_CCA_HYST_M \ + 0x00000007 // Sets the level of CCA + // hysteresis. Unsigned values + // given in dB + +#define RFCORE_XREG_CCACTRL1_CCA_HYST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RSSI register. +// +//***************************************************************************** +#define RFCORE_XREG_RSSI_RSSI_VAL_M \ + 0x000000FF // RSSI estimate on a logarithmic + // scale, signed number on 2's + // complement Unit is 1 dB, offset + // is 73dB. The RSSI value is + // averaged over eight symbol + // periods. The RSSI_VALID status + // bit should be checked before + // reading RSSI_VAL for the first + // time. The reset value of -128 + // also indicates that the RSSI + // value is invalid. + +#define RFCORE_XREG_RSSI_RSSI_VAL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RSSISTAT register. +// +//***************************************************************************** +#define RFCORE_XREG_RSSISTAT_RSSI_VALID \ + 0x00000001 // RSSI value is valid. Occurs + // eight symbol periods after + // entering RX. + +#define RFCORE_XREG_RSSISTAT_RSSI_VALID_M \ + 0x00000001 +#define RFCORE_XREG_RSSISTAT_RSSI_VALID_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RXFIRST register. +// +//***************************************************************************** +#define RFCORE_XREG_RXFIRST_DATA_M \ + 0x000000FF // First byte of the RX FIFO Note: + // Reading this register does not + // modify the contents of the FIFO. + +#define RFCORE_XREG_RXFIRST_DATA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RXFIFOCNT register. +// +//***************************************************************************** +#define RFCORE_XREG_RXFIFOCNT_RXFIFOCNT_M \ + 0x000000FF // Number of bytes in the RX FIFO + // (unsigned integer) + +#define RFCORE_XREG_RXFIFOCNT_RXFIFOCNT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_TXFIFOCNT register. +// +//***************************************************************************** +#define RFCORE_XREG_TXFIFOCNT_TXFIFOCNT_M \ + 0x000000FF // Number of bytes in the TX FIFO + // (unsigned integer) + +#define RFCORE_XREG_TXFIFOCNT_TXFIFOCNT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RXFIRST_PTR register. +// +//***************************************************************************** +#define RFCORE_XREG_RXFIRST_PTR_RXFIRST_PTR_M \ + 0x000000FF // RAM address offset of the first + // byte in the RX FIFO + +#define RFCORE_XREG_RXFIRST_PTR_RXFIRST_PTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RXLAST_PTR register. +// +//***************************************************************************** +#define RFCORE_XREG_RXLAST_PTR_RXLAST_PTR_M \ + 0x000000FF // RAM address offset of the last + // byte + 1 byte in the RX FIFO + +#define RFCORE_XREG_RXLAST_PTR_RXLAST_PTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RXP1_PTR register. +// +//***************************************************************************** +#define RFCORE_XREG_RXP1_PTR_RXP1_PTR_M \ + 0x000000FF // RAM address offset of the first + // byte of the first frame in the + // RX FIFO + +#define RFCORE_XREG_RXP1_PTR_RXP1_PTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_TXFIRST_PTR register. +// +//***************************************************************************** +#define RFCORE_XREG_TXFIRST_PTR_TXFIRST_PTR_M \ + 0x000000FF // RAM address offset of the next + // byte to be transmitted from the + // TX FIFO + +#define RFCORE_XREG_TXFIRST_PTR_TXFIRST_PTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_TXLAST_PTR register. +// +//***************************************************************************** +#define RFCORE_XREG_TXLAST_PTR_TXLAST_PTR_M \ + 0x000000FF // RAM address offset of the last + // byte + 1 byte of the TX FIFO + +#define RFCORE_XREG_TXLAST_PTR_TXLAST_PTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RFIRQM0 register. +// +//***************************************************************************** +#define RFCORE_XREG_RFIRQM0_RFIRQM_M \ + 0x000000FF // Bit mask is masking out + // interrupt sources. Bit position: + // 7: RXMASKZERO 6: RXPKTDONE 5: + // FRAME_ACCEPTED 4: + // SRC_MATCH_FOUND 3: + // SRC_MATCH_DONE 2: FIFOP 1: SFD + // 0: ACT_UNUSED + +#define RFCORE_XREG_RFIRQM0_RFIRQM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RFIRQM1 register. +// +//***************************************************************************** +#define RFCORE_XREG_RFIRQM1_RFIRQM_M \ + 0x0000003F // Bit mask is masking out + // interrupt sources. Bit position: + // 5: CSP_WAIT 4: CSP_STOP 3: + // CSP_MANINT 2: RF_IDLE 1: TXDONE + // 0: TXACKDONE + +#define RFCORE_XREG_RFIRQM1_RFIRQM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RFERRM register. +// +//***************************************************************************** +#define RFCORE_XREG_RFERRM_RFERRM_M \ + 0x0000007F // Bit mask is masking out + // interrupt sources. Bit position: + // 6: STROBE_ERR 5: TXUNDERF 4: + // TXOVERF 3: RXUNDERF 2: RXOVERF + // 1: RXABO 0: NLOCK + +#define RFCORE_XREG_RFERRM_RFERRM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RFRND register. +// +//***************************************************************************** +#define RFCORE_XREG_RFRND_QRND 0x00000002 // Random bit from the Q channel + // of the receiver +#define RFCORE_XREG_RFRND_QRND_M \ + 0x00000002 +#define RFCORE_XREG_RFRND_QRND_S 1 +#define RFCORE_XREG_RFRND_IRND 0x00000001 // Random bit from the I channel + // of the receiver +#define RFCORE_XREG_RFRND_IRND_M \ + 0x00000001 +#define RFCORE_XREG_RFRND_IRND_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_MDMCTRL0 register. +// +//***************************************************************************** +#define RFCORE_XREG_MDMCTRL0_DEM_NUM_ZEROS_M \ + 0x000000C0 // Sets how many zero symbols must + // be detected before the sync word + // when searching for sync. Only + // one zero symbol is required to + // have a correlation value above + // the correlation threshold set in + // the MDMCTRL1 register. 00: + // Reserved 01: 1 zero symbol 10: 2 + // zero symbols 11: 3 zero symbols + +#define RFCORE_XREG_MDMCTRL0_DEM_NUM_ZEROS_S 6 +#define RFCORE_XREG_MDMCTRL0_DEMOD_AVG_MODE \ + 0x00000020 // Defines the behavior or the + // frequency offset averaging + // filter. 0: Lock average level + // after preamble match. Restart + // frequency offset calibration + // when searching for the next + // frame. 1: Continuously update + // average level. + +#define RFCORE_XREG_MDMCTRL0_DEMOD_AVG_MODE_M \ + 0x00000020 +#define RFCORE_XREG_MDMCTRL0_DEMOD_AVG_MODE_S 5 +#define RFCORE_XREG_MDMCTRL0_PREAMBLE_LENGTH_M \ + 0x0000001E // The number of preamble bytes + // (two zero-symbols) to be sent in + // TX mode before the SFD, encoded + // in steps of 2 symbols (1 byte). + // The reset value of 2 is + // compliant with IEEE 802.15.4. + // 0000: 2 leading-zero bytes 0001: + // 3 leading-zero bytes 0010: 4 + // leading-zero bytes ... 1111: 17 + // leading-zero bytes + +#define RFCORE_XREG_MDMCTRL0_PREAMBLE_LENGTH_S 1 +#define RFCORE_XREG_MDMCTRL0_TX_FILTER \ + 0x00000001 // Defines the kind of TX filter + // that is used. The normal TX + // filter is as defined by the IEEE + // 802.15.4 standard. Extra + // filtering may be applied to + // lower the out-of-band emissions. + // 0: Normal TX filtering 1: Enable + // extra filtering + +#define RFCORE_XREG_MDMCTRL0_TX_FILTER_M \ + 0x00000001 +#define RFCORE_XREG_MDMCTRL0_TX_FILTER_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_MDMCTRL1 register. +// +//***************************************************************************** +#define RFCORE_XREG_MDMCTRL1_CORR_THR_SFD \ + 0x00000020 // Defines requirements for SFD + // detection: 0: The correlation + // value of one of the zero symbols + // of the preamble must be above + // the correlation threshold. 1: + // The correlation value of one + // zero symbol of the preamble and + // both symbols in the SFD must be + // above the correlation threshold. + +#define RFCORE_XREG_MDMCTRL1_CORR_THR_SFD_M \ + 0x00000020 +#define RFCORE_XREG_MDMCTRL1_CORR_THR_SFD_S 5 +#define RFCORE_XREG_MDMCTRL1_CORR_THR_M \ + 0x0000001F // Demodulator correlator + // threshold value, required before + // SFD search. Threshold value + // adjusts how the receiver + // synchronizes to data from the + // radio. If the threshold is set + // too low, sync can more easily be + // found on noise. If set too high, + // the sensitivity is reduced, but + // sync is not likely to be found + // on noise. In combination with + // DEM_NUM_ZEROS, the system can be + // tuned so sensitivity is high + // with less sync found on noise. + +#define RFCORE_XREG_MDMCTRL1_CORR_THR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FREQEST register. +// +//***************************************************************************** +#define RFCORE_XREG_FREQEST_FREQEST_M \ + 0x000000FF // Signed 2's-complement value. + // Contains an estimate of the + // frequency offset between carrier + // and the receiver LO. The offset + // frequency is FREQEST x 7800 Hz. + // DEM_AVG_MODE controls when this + // estimate is updated. If + // DEM_AVG_MODE = 0, it is updated + // until sync is found. Then the + // frequency offset estimate is + // frozen until the end of the + // received frame. If DEM_AVG_MODE + // = 1, it is updated as long as + // the demodulator is enabled. To + // calculate the correct value, one + // must use an offset + // (FREQEST_offset), which can be + // found in the device data sheet. + // Real FREQEST value = FREQEST - + // FREQEST_offset. + +#define RFCORE_XREG_FREQEST_FREQEST_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RXCTRL register. +// +//***************************************************************************** +#define RFCORE_XREG_RXCTRL_GBIAS_LNA2_REF_M \ + 0x00000030 // Adjusts front-end LNA2/mixer + // PTAT current output (from M = 3 + // to M = 6), default: M = 5 + +#define RFCORE_XREG_RXCTRL_GBIAS_LNA2_REF_S 4 +#define RFCORE_XREG_RXCTRL_GBIAS_LNA_REF_M \ + 0x0000000C // Adjusts front-end LNA PTAT + // current output (from M = 3 to M + // = 6), default: M = 5 + +#define RFCORE_XREG_RXCTRL_GBIAS_LNA_REF_S 2 +#define RFCORE_XREG_RXCTRL_MIX_CURRENT_M \ + 0x00000003 // Control of the output current + // from the receiver mixers The + // current increases with + // increasing setting set. + +#define RFCORE_XREG_RXCTRL_MIX_CURRENT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FSCTRL register. +// +//***************************************************************************** +#define RFCORE_XREG_FSCTRL_PRE_CURRENT_M \ + 0x000000C0 // Prescaler current setting + +#define RFCORE_XREG_FSCTRL_PRE_CURRENT_S 6 +#define RFCORE_XREG_FSCTRL_LODIV_BUF_CURRENT_TX_M \ + 0x00000030 // Adjusts current in mixer and PA + // buffers Used when TX_ACTIVE = 1 + +#define RFCORE_XREG_FSCTRL_LODIV_BUF_CURRENT_TX_S 4 +#define RFCORE_XREG_FSCTRL_LODIV_BUF_CURRENT_RX_M \ + 0x0000000C // Adjusts current in mixer and PA + // buffers Used when TX_ACTIVE = 0 + +#define RFCORE_XREG_FSCTRL_LODIV_BUF_CURRENT_RX_S 2 +#define RFCORE_XREG_FSCTRL_LODIV_CURRENT_M \ + 0x00000003 // Adjusts divider currents, + // except mixer and PA buffers + +#define RFCORE_XREG_FSCTRL_LODIV_CURRENT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FSCAL0 register. +// +//***************************************************************************** +#define RFCORE_XREG_FSCAL0_VCO_CURR_COMP_EN_OV \ + 0x00000080 // Force on the current comparator + // in the VCO. This signal is ORed + // with the signal coming from the + // calibration module. + +#define RFCORE_XREG_FSCAL0_VCO_CURR_COMP_EN_OV_M \ + 0x00000080 +#define RFCORE_XREG_FSCAL0_VCO_CURR_COMP_EN_OV_S 7 +#define RFCORE_XREG_FSCAL0_CHP_DISABLE \ + 0x00000040 // Set this bit to manually + // disable charge pump by masking + // the up and down pulses from the + // phase detector. + +#define RFCORE_XREG_FSCAL0_CHP_DISABLE_M \ + 0x00000040 +#define RFCORE_XREG_FSCAL0_CHP_DISABLE_S 6 +#define RFCORE_XREG_FSCAL0_CHP_CURRENT_M \ + 0x0000003C // Digital bit vector defining the + // charge-pump output current on an + // exponential scale If + // FFC_BW_BOOST = 0, the read value + // is the value stored in + // CHP_CURRENT. If FFC_BW_BOOST = + // 1, the read value is CHP_CURRENT + // + 4. If the addition causes + // overflow, the signal is + // saturated. + +#define RFCORE_XREG_FSCAL0_CHP_CURRENT_S 2 +#define RFCORE_XREG_FSCAL0_BW_BOOST_MODE_M \ + 0x00000003 // Control signal Defines the + // synthesizer boost mode 00: No + // BW_BOOST 01: BW_BOOST is high + // during calibration and + // approximately 30 us into the + // settling. 10: BW_BOOST is always + // on (or high). 11: Reserved + +#define RFCORE_XREG_FSCAL0_BW_BOOST_MODE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FSCAL1 register. +// +//***************************************************************************** +#define RFCORE_XREG_FSCAL1_VCO_CURR_CAL_OE \ + 0x00000080 // Override current calibration + +#define RFCORE_XREG_FSCAL1_VCO_CURR_CAL_OE_M \ + 0x00000080 +#define RFCORE_XREG_FSCAL1_VCO_CURR_CAL_OE_S 7 +#define RFCORE_XREG_FSCAL1_VCO_CURR_CAL_M \ + 0x0000007C // Calibration result Override + // value if VCO_CURR_CAL_OE = 1 + +#define RFCORE_XREG_FSCAL1_VCO_CURR_CAL_S 2 +#define RFCORE_XREG_FSCAL1_VCO_CURR_M \ + 0x00000003 // Defines current in VCO core + // Sets the multiplier between + // calibrated current and VCO + // current. + +#define RFCORE_XREG_FSCAL1_VCO_CURR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FSCAL2 register. +// +//***************************************************************************** +#define RFCORE_XREG_FSCAL2_VCO_CAPARR_OE \ + 0x00000040 // Override the calibration result + // with the value from + // VCO_CAPARR[5:0]. + +#define RFCORE_XREG_FSCAL2_VCO_CAPARR_OE_M \ + 0x00000040 +#define RFCORE_XREG_FSCAL2_VCO_CAPARR_OE_S 6 +#define RFCORE_XREG_FSCAL2_VCO_CAPARR_M \ + 0x0000003F // VCO capacitor array setting + // Programmed during calibration + // Override value when + // VCO_CAPARR_OE = 1 + +#define RFCORE_XREG_FSCAL2_VCO_CAPARR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_FSCAL3 register. +// +//***************************************************************************** +#define RFCORE_XREG_FSCAL3_VCO_DAC_EN_OV \ + 0x00000040 // Enables the VCO DAC when 1 + +#define RFCORE_XREG_FSCAL3_VCO_DAC_EN_OV_M \ + 0x00000040 +#define RFCORE_XREG_FSCAL3_VCO_DAC_EN_OV_S 6 +#define RFCORE_XREG_FSCAL3_VCO_VC_DAC_M \ + 0x0000003C // Bit vector for programming + // varactor control voltage from VC + // DAC + +#define RFCORE_XREG_FSCAL3_VCO_VC_DAC_S 2 +#define RFCORE_XREG_FSCAL3_VCO_CAPARR_CAL_CTRL_M \ + 0x00000003 // Calibration accuracy setting + // for the cap_array calibration + // part of the calibration 00: 80 + // XOSC periods 01: 100 XOSC + // periods 10: 125 XOSC periods 11: + // 250 XOSC periods + +#define RFCORE_XREG_FSCAL3_VCO_CAPARR_CAL_CTRL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_AGCCTRL0 register. +// +//***************************************************************************** +#define RFCORE_XREG_AGCCTRL0_AGC_DR_XTND_EN \ + 0x00000040 // 0: The AGC performs no + // adjustment of attenuation in the + // AAF. 1: The AGC adjusts the gain + // in the AAF to achieve extra + // dynamic range for the receiver. + +#define RFCORE_XREG_AGCCTRL0_AGC_DR_XTND_EN_M \ + 0x00000040 +#define RFCORE_XREG_AGCCTRL0_AGC_DR_XTND_EN_S 6 +#define RFCORE_XREG_AGCCTRL0_AGC_DR_XTND_THR_M \ + 0x0000003F // If the measured error between + // the AGC reference magnitude and + // the actual magnitude in dB is + // larger than this threshold, the + // extra attenuation is enabled in + // the front end. This threshold + // must be set higher than 0x0C. + // This feature is enabled by + // AGC_DR_XTND_EN. + +#define RFCORE_XREG_AGCCTRL0_AGC_DR_XTND_THR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_AGCCTRL1 register. +// +//***************************************************************************** +#define RFCORE_XREG_AGCCTRL1_AGC_REF_M \ + 0x0000003F // Target value for the AGC + // control loop, given in 1-dB + // steps + +#define RFCORE_XREG_AGCCTRL1_AGC_REF_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_AGCCTRL2 register. +// +//***************************************************************************** +#define RFCORE_XREG_AGCCTRL2_LNA1_CURRENT_M \ + 0x000000C0 // Overrride value for LNA 1 Used + // only when LNA_CURRENT_OE = 1 + // When read, this register returns + // the current applied gain + // setting. 00: 0-dB gain + // (reference level) 01: 3-dB gain + // 10: Reserved 11: 6-dB gain + +#define RFCORE_XREG_AGCCTRL2_LNA1_CURRENT_S 6 +#define RFCORE_XREG_AGCCTRL2_LNA2_CURRENT_M \ + 0x00000038 // Overrride value for LNA 2 Used + // only when LNA_CURRENT_OE = 1 + // When read, this register returns + // the current applied gain + // setting. 000: 0-dB gain + // (reference level) 001: 3-dB gain + // 010: 6-dB gain 011: 9-dB gain + // 100: 12-dB gain 101: 15-dB gain + // 110: 18-dB gain 111: 21-dB gain + +#define RFCORE_XREG_AGCCTRL2_LNA2_CURRENT_S 3 +#define RFCORE_XREG_AGCCTRL2_LNA3_CURRENT_M \ + 0x00000006 // Overrride value for LNA 3 Used + // only when LNA_CURRENT_OE = 1 + // When read, this register returns + // the current applied gain + // setting. 00: 0-dB gain + // (reference level) 01: 3-dB gain + // 10: 6-dB gain 11: 9-dB gain + +#define RFCORE_XREG_AGCCTRL2_LNA3_CURRENT_S 1 +#define RFCORE_XREG_AGCCTRL2_LNA_CURRENT_OE \ + 0x00000001 // Write 1 to override the AGC LNA + // current setting with the values + // above (LNA1_CURRENT, + // LNA2_CURRENT, and LNA3_CURRENT). + +#define RFCORE_XREG_AGCCTRL2_LNA_CURRENT_OE_M \ + 0x00000001 +#define RFCORE_XREG_AGCCTRL2_LNA_CURRENT_OE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_AGCCTRL3 register. +// +//***************************************************************************** +#define RFCORE_XREG_AGCCTRL3_AGC_SETTLE_WAIT_M \ + 0x00000060 // Timing for AGC to wait for + // analog gain to settle after a + // gain change. During this period, + // the energy measurement in the + // AGC is paused. 00: 15 periods + // 01: 20 periods 10: 25 periods + // 11: 30 periods + +#define RFCORE_XREG_AGCCTRL3_AGC_SETTLE_WAIT_S 5 +#define RFCORE_XREG_AGCCTRL3_AGC_WIN_SIZE_M \ + 0x00000018 // Window size for the + // accumulate-and-dump function in + // the AGC. 00: 16 samples 01: 32 + // samples 10: 64 samples 11: 128 + // samples + +#define RFCORE_XREG_AGCCTRL3_AGC_WIN_SIZE_S 3 +#define RFCORE_XREG_AGCCTRL3_AAF_RP_M \ + 0x00000006 // Overrides the control signals + // of the AGC to AAF when AAF_RP_OE + // = 1. When read, it returns the + // applied signal to the AAF. 00: + // 9-dB attenuation in AAF 01: 6-dB + // attenuation in AAF 10: 3-dB + // attenuation in AAF 11: 0-dB + // attenuation in AAF (reference + // level) + +#define RFCORE_XREG_AGCCTRL3_AAF_RP_S 1 +#define RFCORE_XREG_AGCCTRL3_AAF_RP_OE \ + 0x00000001 // Override the AAF control + // signals of the AGC with the + // values stored in AAF_RP. + +#define RFCORE_XREG_AGCCTRL3_AAF_RP_OE_M \ + 0x00000001 +#define RFCORE_XREG_AGCCTRL3_AAF_RP_OE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_ADCTEST0 register. +// +//***************************************************************************** +#define RFCORE_XREG_ADCTEST0_ADC_VREF_ADJ_M \ + 0x000000C0 // Quantizer threshold control for + // test and debug + +#define RFCORE_XREG_ADCTEST0_ADC_VREF_ADJ_S 6 +#define RFCORE_XREG_ADCTEST0_ADC_QUANT_ADJ_M \ + 0x00000030 // Quantizer threshold control for + // test and debug + +#define RFCORE_XREG_ADCTEST0_ADC_QUANT_ADJ_S 4 +#define RFCORE_XREG_ADCTEST0_ADC_GM_ADJ_M \ + 0x0000000E // Gm-control for test and debug + +#define RFCORE_XREG_ADCTEST0_ADC_GM_ADJ_S 1 +#define RFCORE_XREG_ADCTEST0_ADC_DAC2_EN \ + 0x00000001 // Enables DAC2 for enhanced ADC + // stability + +#define RFCORE_XREG_ADCTEST0_ADC_DAC2_EN_M \ + 0x00000001 +#define RFCORE_XREG_ADCTEST0_ADC_DAC2_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_ADCTEST1 register. +// +//***************************************************************************** +#define RFCORE_XREG_ADCTEST1_ADC_TEST_CTRL_M \ + 0x000000F0 // ADC test mode selector + +#define RFCORE_XREG_ADCTEST1_ADC_TEST_CTRL_S 4 +#define RFCORE_XREG_ADCTEST1_ADC_C2_ADJ_M \ + 0x0000000C // Used to adjust capacitor values + // in ADC + +#define RFCORE_XREG_ADCTEST1_ADC_C2_ADJ_S 2 +#define RFCORE_XREG_ADCTEST1_ADC_C3_ADJ_M \ + 0x00000003 // Used to adjust capacitor values + // in ADC + +#define RFCORE_XREG_ADCTEST1_ADC_C3_ADJ_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_ADCTEST2 register. +// +//***************************************************************************** +#define RFCORE_XREG_ADCTEST2_ADC_TEST_MODE_M \ + 0x00000060 // Test mode to enable output of + // ADC data from demodulator. When + // enabled, raw ADC data is clocked + // out on the GPIO pins. 00: Test + // mode disabled 01: Data from the + // I and Q ADCs are output (data + // rate 76 MHz) 10: Data from the I + // ADC is output. Two and two ADC + // samples grouped (data rate 38 + // MHz) 11: Data from the Q ADC is + // output. Two and two ADC samples + // grouped (data rate 38 MHz) + +#define RFCORE_XREG_ADCTEST2_ADC_TEST_MODE_S 5 +#define RFCORE_XREG_ADCTEST2_AAF_RS_M \ + 0x00000018 // Controls series resistance of + // AAF + +#define RFCORE_XREG_ADCTEST2_AAF_RS_S 3 +#define RFCORE_XREG_ADCTEST2_ADC_FF_ADJ_M \ + 0x00000006 // Adjust feed forward + +#define RFCORE_XREG_ADCTEST2_ADC_FF_ADJ_S 1 +#define RFCORE_XREG_ADCTEST2_ADC_DAC_ROT \ + 0x00000001 // Control of DAC DWA scheme 0 = + // DWA (scrambling) disabled 1 = + // DWA enabled + +#define RFCORE_XREG_ADCTEST2_ADC_DAC_ROT_M \ + 0x00000001 +#define RFCORE_XREG_ADCTEST2_ADC_DAC_ROT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_MDMTEST0 register. +// +//***************************************************************************** +#define RFCORE_XREG_MDMTEST0_TX_TONE_M \ + 0x000000F0 // Enables the possibility to + // transmit a baseband tone by + // picking samples from the sine + // tables with a controllable phase + // step between the samples. The + // step size is controlled by + // TX_TONE. If MDMTEST1.MOD_IF is + // 0, the tone is superpositioned + // on the modulated data, + // effectively giving modulation + // with an IF. If MDMTEST1.MOD_IF + // is 1, only the tone is + // transmitted. 0000: -6 MHz 0001: + // -4 MHz 0010: -3 MHz 0011: -2 MHz + // 0100: -1 MHz 0101: -500 kHz + // 0110: -4 kHz 0111: 0 1000: 4 kHz + // 1001: 500 kHz 1010: 1 MHz 1011: + // 2 MHz 1100: 3 MHz 1101: 4 MHz + // 1110: 6 MHz Others: Reserved + +#define RFCORE_XREG_MDMTEST0_TX_TONE_S 4 +#define RFCORE_XREG_MDMTEST0_DC_WIN_SIZE_M \ + 0x0000000C // Controls the numbers of samples + // to be accumulated between each + // dump of the accumulate-and-dump + // filter used in DC removal 00: 32 + // samples 01: 64 samples 10: 128 + // samples 11: 256 samples + +#define RFCORE_XREG_MDMTEST0_DC_WIN_SIZE_S 2 +#define RFCORE_XREG_MDMTEST0_DC_BLOCK_MODE_M \ + 0x00000003 // Selects the mode of operation + // 00: The input signal to the DC + // blocker is passed to the output + // without any attempt to remove + // DC. 01: Enable DC cancellation. + // Normal operation 10: Freeze + // estimates of DC when sync is + // found. Resume estimating DC when + // searching for the next frame. + // 11: Reserved + +#define RFCORE_XREG_MDMTEST0_DC_BLOCK_MODE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_MDMTEST1 register. +// +//***************************************************************************** +#define RFCORE_XREG_MDMTEST1_USEMIRROR_IF \ + 0x00000020 // 0: Use the normal IF frequency + // (MDMTEST0.TX_TONE) for automatic + // IF compensation of channel + // frequency on TX. 1: Use mirror + // IF frequency for automatic + // compensation of channel + // frequency on TX. + +#define RFCORE_XREG_MDMTEST1_USEMIRROR_IF_M \ + 0x00000020 +#define RFCORE_XREG_MDMTEST1_USEMIRROR_IF_S 5 +#define RFCORE_XREG_MDMTEST1_MOD_IF \ + 0x00000010 // 0: Modulation is performed at + // an IF set by MDMTEST0.TX_TONE. + // The tone set by MDMTEST0.TX_TONE + // is superimposed on the data. 1: + // Modulate a tone set by + // MDMTEST0.TX_TONE. A tone is + // transmitted with frequency set + // by MDMTEST0.TX_TONE. + +#define RFCORE_XREG_MDMTEST1_MOD_IF_M \ + 0x00000010 +#define RFCORE_XREG_MDMTEST1_MOD_IF_S 4 +#define RFCORE_XREG_MDMTEST1_RAMP_AMP \ + 0x00000008 // 1: Enable ramping of DAC output + // amplitude during startup and + // finish. 0: Disable ramping of + // DAC output amplitude. + +#define RFCORE_XREG_MDMTEST1_RAMP_AMP_M \ + 0x00000008 +#define RFCORE_XREG_MDMTEST1_RAMP_AMP_S 3 +#define RFCORE_XREG_MDMTEST1_RFC_SNIFF_EN \ + 0x00000004 // 0: Packet sniffer module + // disabled 1: Packet sniffer + // module enabled. The received and + // transmitted data can be observed + // on GPIO pins. + +#define RFCORE_XREG_MDMTEST1_RFC_SNIFF_EN_M \ + 0x00000004 +#define RFCORE_XREG_MDMTEST1_RFC_SNIFF_EN_S 2 +#define RFCORE_XREG_MDMTEST1_LOOPBACK_EN \ + 0x00000001 // Enables loopback of modulated + // data into the receiver chain 0: + // An STXCAL instruction calibrates + // for TX. Use STXON to continue to + // active TX. 1: An STXCAL + // instruction enables the loopback + // mode. + +#define RFCORE_XREG_MDMTEST1_LOOPBACK_EN_M \ + 0x00000001 +#define RFCORE_XREG_MDMTEST1_LOOPBACK_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_DACTEST0 register. +// +//***************************************************************************** +#define RFCORE_XREG_DACTEST0_DAC_Q_M \ + 0x400886FF // Q-branch DAC override value + // when DAC_SRC = 001 If DAC_SRC is + // set to be ADC data, CORDIC + // magnitude, or channel filtered + // data, then DAC_Q_O controls the + // part of the word in question + // that is actually multiplexed to + // the DAC, as described below. + // 000111: Bits 7:0 001000: Bits + // 8:1 001001: Bits 9:2 ... If an + // invalid setting is chosen, the + // DAC outputs only zeros (minimum + // value). + +#define RFCORE_XREG_DACTEST0_DAC_Q_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_DACTEST1 register. +// +//***************************************************************************** +#define RFCORE_XREG_DACTEST1_DAC_I_M \ + 0x400886FF // I-branch DAC override value + // when DAC_SRC = 001 If DAC_SRC is + // set to be ADC data, CORDIC + // magnitude, channel filtered + // data, or DC filtered data, then + // DAC_I_O controls the part of the + // word in question that is + // actually multiplexed to the DAC + // as described below. 000111: Bits + // 7:0 001000: Bits 8:1 001001: + // Bits 9:2 ... If an invalid + // setting is chosen, then the DAC + // outputs only zeros (minimum + // value). + +#define RFCORE_XREG_DACTEST1_DAC_I_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_DACTEST2 register. +// +//***************************************************************************** +#define RFCORE_XREG_DACTEST2_DAC_DEM_EN \ + 0x00000020 // Enable and disable dynamic + // element matching Drives + // RFR_DAC_DEM_EN + +#define RFCORE_XREG_DACTEST2_DAC_DEM_EN_M \ + 0x00000020 +#define RFCORE_XREG_DACTEST2_DAC_DEM_EN_S 5 +#define RFCORE_XREG_DACTEST2_DAC_CASC_CTRL_M \ + 0x00000018 // Adjustment of output stage + // Drives RFR_DAC_CASC_CTRL + +#define RFCORE_XREG_DACTEST2_DAC_CASC_CTRL_S 3 +#define RFCORE_XREG_DACTEST2_DAC_SRC_M \ + 0x00000007 // The TX DACs data source is + // selected by DAC_SRC according + // to: 000: Normal operation (from + // modulator) 001: The DAC_I_O and + // DAC_Q_O override values 010: ADC + // data after decimation, magnitude + // controlled by DAC_I_O and + // DAC_Q_O 011: I/Q after + // decimation, channel and DC + // filtering, magnitude controlled + // by DAC_I_O and DAC_Q_O 100: + // CORDIC magnitude output and + // front-end gain is output, + // magnitude controlled by DAC_I_O + // and DAC_Q_O 101: RSSI I output + // on the I DAC 111: Reserved + +#define RFCORE_XREG_DACTEST2_DAC_SRC_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_ATEST register. +// +//***************************************************************************** +#define RFCORE_XREG_ATEST_ATEST_CTRL_M \ + 0x0000003F // Controls the analog test mode: + // 00 0000: Disabled 00 0001: + // Enables the temperature sensor + // (see also the CCTEST_TR0 + // register description). Other + // values reserved. + +#define RFCORE_XREG_ATEST_ATEST_CTRL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_PTEST0 register. +// +//***************************************************************************** +#define RFCORE_XREG_PTEST0_PRE_PD \ + 0x00000080 // Prescaler power-down signal + // When PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST0_PRE_PD_M \ + 0x00000080 +#define RFCORE_XREG_PTEST0_PRE_PD_S 7 +#define RFCORE_XREG_PTEST0_CHP_PD \ + 0x00000040 // Charge pump power-down signal + // When PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST0_CHP_PD_M \ + 0x00000040 +#define RFCORE_XREG_PTEST0_CHP_PD_S 6 +#define RFCORE_XREG_PTEST0_ADC_PD \ + 0x00000020 // ADC power-down signal When + // PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST0_ADC_PD_M \ + 0x00000020 +#define RFCORE_XREG_PTEST0_ADC_PD_S 5 +#define RFCORE_XREG_PTEST0_DAC_PD \ + 0x00000010 // DAC power-down signal When + // PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST0_DAC_PD_M \ + 0x00000010 +#define RFCORE_XREG_PTEST0_DAC_PD_S 4 +#define RFCORE_XREG_PTEST0_LNA_PD_M \ + 0x0000000C // Low-noise amplifier power-down + // signal Defines LNA/mixer + // power-down modes: 00: Power up + // 01: LNA off, mixer/regulator on + // 10: LNA/mixer off, regulator on + // 11: PD When PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST0_LNA_PD_S 2 +#define RFCORE_XREG_PTEST0_TXMIX_PD \ + 0x00000002 // Transmit mixer power-down + // signal When PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST0_TXMIX_PD_M \ + 0x00000002 +#define RFCORE_XREG_PTEST0_TXMIX_PD_S 1 +#define RFCORE_XREG_PTEST0_AAF_PD \ + 0x00000001 // Antialiasing filter power-down + // signal When PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST0_AAF_PD_M \ + 0x00000001 +#define RFCORE_XREG_PTEST0_AAF_PD_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_PTEST1 register. +// +//***************************************************************************** +#define RFCORE_XREG_PTEST1_PD_OVERRIDE \ + 0x00000008 // Override enabling and disabling + // of various modules (for debug + // and testing only) It is + // impossible to override + // hard-coded BIAS_PD[1:0] + // depenancy. + +#define RFCORE_XREG_PTEST1_PD_OVERRIDE_M \ + 0x00000008 +#define RFCORE_XREG_PTEST1_PD_OVERRIDE_S 3 +#define RFCORE_XREG_PTEST1_PA_PD \ + 0x00000004 // Power amplifier power-down + // signal When PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST1_PA_PD_M \ + 0x00000004 +#define RFCORE_XREG_PTEST1_PA_PD_S 2 +#define RFCORE_XREG_PTEST1_VCO_PD \ + 0x00000002 // VCO power-down signal When + // PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST1_VCO_PD_M \ + 0x00000002 +#define RFCORE_XREG_PTEST1_VCO_PD_S 1 +#define RFCORE_XREG_PTEST1_LODIV_PD \ + 0x00000001 // LO power-down signal When + // PD_OVERRIDE = 1 + +#define RFCORE_XREG_PTEST1_LODIV_PD_M \ + 0x00000001 +#define RFCORE_XREG_PTEST1_LODIV_PD_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG0 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG0_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG0_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG1 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG1_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG1_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG2 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG2_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG2_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG3 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG3_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG3_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG4 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG4_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG4_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG5 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG5_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG5_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG6 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG6_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG6_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG7 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG7_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG7_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG8 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG8_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG8_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG9 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG9_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG9_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG10 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG10_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG10_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG11 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG11_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG11_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG12 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG12_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG12_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG13 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG13_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG13_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG14 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG14_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG14_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG15 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG15_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG15_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG16 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG16_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG16_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG17 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG17_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG17_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG18 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG18_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG18_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG19 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG19_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG19_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG20 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG20_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG20_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG21 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG21_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG21_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG22 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG22_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG22_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPPROG23 register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPPROG23_CSP_INSTR_M \ + 0x000000FF // Byte N of the CSP program + // memory + +#define RFCORE_XREG_CSPPROG23_CSP_INSTR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPCTRL register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPCTRL_MCU_CTRL \ + 0x00000001 // CSP MCU control input + +#define RFCORE_XREG_CSPCTRL_MCU_CTRL_M \ + 0x00000001 +#define RFCORE_XREG_CSPCTRL_MCU_CTRL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPSTAT register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPSTAT_CSP_RUNNING \ + 0x00000020 // 1: CSP is running. 0: CSP is + // idle. + +#define RFCORE_XREG_CSPSTAT_CSP_RUNNING_M \ + 0x00000020 +#define RFCORE_XREG_CSPSTAT_CSP_RUNNING_S 5 +#define RFCORE_XREG_CSPSTAT_CSP_PC_M \ + 0x0000001F // CSP program counter + +#define RFCORE_XREG_CSPSTAT_CSP_PC_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPX register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPX_CSPX_M 0x000000FF // Used by CSP instructions WAITX, + // RANDXY, INCX, DECX, and + // conditional instructions. +#define RFCORE_XREG_CSPX_CSPX_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPY register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPY_CSPY_M 0x000000FF // Used by CSP instructions + // RANDXY, INCY, DECY, and + // conditional instructions. +#define RFCORE_XREG_CSPY_CSPY_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPZ register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPZ_CSPZ_M 0x000000FF // Used by CSP instructions INCZ, + // DECZ, and conditional + // instructions. +#define RFCORE_XREG_CSPZ_CSPZ_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_CSPT register. +// +//***************************************************************************** +#define RFCORE_XREG_CSPT_CSPT_M 0x000000FF // Content is decremented each + // time the MAC Timer overflows + // while the CSP program is + // running. The SCP program stops + // when decremented to 0. Setting + // CSPT = 0xFF prevents the + // register from being decremented. +#define RFCORE_XREG_CSPT_CSPT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RFC_OBS_CTRL0 register. +// +//***************************************************************************** +#define RFCORE_XREG_RFC_OBS_CTRL0_RFC_OBS_POL0 \ + 0x00000040 // The signal chosen by + // RFC_OBS_MUX0 is XORed with this + // bit. + +#define RFCORE_XREG_RFC_OBS_CTRL0_RFC_OBS_POL0_M \ + 0x00000040 +#define RFCORE_XREG_RFC_OBS_CTRL0_RFC_OBS_POL0_S 6 +#define RFCORE_XREG_RFC_OBS_CTRL0_RFC_OBS_MUX0_M \ + 0x0000003F // Controls which observable + // signal from RF Core is to be + // muxed out to rfc_obs_sigs[0]. 00 + // 0000: 0 - Constant value 00 + // 0001: 1 - Constant value 00 + // 1000: rfc_sniff_data - Data from + // packet sniffer. Sample data on + // rising edges of sniff_clk. 00 + // 1001: rfc_sniff_clk - 250kHz + // clock for packet sniffer data. + // 00 1100: rssi_valid - Pin is + // high when the RSSI value has + // been updated at least once since + // RX was started. Cleared when + // leaving RX. 00 1101: demod_cca - + // Clear channel assessment. See + // FSMSTAT1 register for details on + // how to configure the behavior of + // this signal. 00 1110: + // sampled_cca - A sampled version + // of the CCA bit from demodulator. + // The value is updated whenever a + // SSAMPLECCA or STXONCCA strobe is + // issued. 00 1111: sfd_sync - Pin + // is high when a SFD has been + // received or transmitted. Cleared + // when leaving RX/TX respectively. + // Not to be confused with the SFD + // exception. 01 0000: tx_active - + // Indicates that FFCTRL is in one + // of the TX states. Active-high. + // Note: This signal might have + // glitches, because it has no + // output flip-flop and is based on + // the current state register of + // the FFCTRL FSM. 01 0001: + // rx_active - Indicates that + // FFCTRL is in one of the RX + // states. Active-high. Note: This + // signal might have glitches, + // because it has no output + // flip-flop and is based on the + // current state register of the + // FFCTRL FSM. 01 0010: ffctrl_fifo + // - Pin is high when one or more + // bytes are in the RXFIFO. Low + // during RXFIFO overflow. 01 0011: + // ffctrl_fifop - Pin is high when + // the number of bytes in the + // RXFIFO exceeds the programmable + // threshold or at least one + // complete frame is in the RXFIFO. + // Also high during RXFIFO + // overflow. Not to be confused + // with the FIFOP exception. 01 + // 0100: packet_done - A complete + // frame has been received. I.e., + // the number of bytes set by the + // frame-length field has been + // received. 01 0110: + // rfc_xor_rand_i_q - XOR between I + // and Q random outputs. Updated at + // 8 MHz. 01 0111: rfc_rand_q - + // Random data output from the Q + // channel of the receiver. Updated + // at 8 MHz. 01 1000: rfc_rand_i - + // Random data output from the I + // channel of the receiver. Updated + // at 8 MHz 01 1001: lock_status - + // 1 when PLL is in lock, otherwise + // 0 10 1000: pa_pd - Power + // amplifier power-down signal 10 + // 1010: lna_pd - LNA power-down + // signal Others: Reserved + +#define RFCORE_XREG_RFC_OBS_CTRL0_RFC_OBS_MUX0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RFC_OBS_CTRL1 register. +// +//***************************************************************************** +#define RFCORE_XREG_RFC_OBS_CTRL1_RFC_OBS_POL1 \ + 0x00000040 // The signal chosen by + // RFC_OBS_MUX1 is XORed with this + // bit. + +#define RFCORE_XREG_RFC_OBS_CTRL1_RFC_OBS_POL1_M \ + 0x00000040 +#define RFCORE_XREG_RFC_OBS_CTRL1_RFC_OBS_POL1_S 6 +#define RFCORE_XREG_RFC_OBS_CTRL1_RFC_OBS_MUX1_M \ + 0x0000003F // Controls which observable + // signal from RF Core is to be + // muxed out to rfc_obs_sigs[1]. + // See description of RFC_OBS_CTRL0 + // for details. + +#define RFCORE_XREG_RFC_OBS_CTRL1_RFC_OBS_MUX1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_RFC_OBS_CTRL2 register. +// +//***************************************************************************** +#define RFCORE_XREG_RFC_OBS_CTRL2_RFC_OBS_POL2 \ + 0x00000040 // The signal chosen by + // RFC_OBS_MUX2 is XORed with this + // bit. + +#define RFCORE_XREG_RFC_OBS_CTRL2_RFC_OBS_POL2_M \ + 0x00000040 +#define RFCORE_XREG_RFC_OBS_CTRL2_RFC_OBS_POL2_S 6 +#define RFCORE_XREG_RFC_OBS_CTRL2_RFC_OBS_MUX2_M \ + 0x0000003F // Controls which observable + // signal from RF Core is to be + // muxed out to rfc_obs_sigs[2]. + // See description of RFC_OBS_CTRL0 + // for details. + +#define RFCORE_XREG_RFC_OBS_CTRL2_RFC_OBS_MUX2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// RFCORE_XREG_TXFILTCFG register. +// +//***************************************************************************** +#define RFCORE_XREG_TXFILTCFG_FC_M \ + 0x0000000F // Drives signal rfr_txfilt_fc + +#define RFCORE_XREG_TXFILTCFG_FC_S 0 + + +#endif // __HW_RFCORE_XREG_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_smwdthrosc.h b/bsp/boards/mimsy2-cc2538/headers/hw_smwdthrosc.h new file mode 100644 index 0000000000..7a2db333c0 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_smwdthrosc.h @@ -0,0 +1,264 @@ +/****************************************************************************** +* Filename: hw_smwdthrosc.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_SMWDTHROSC_H__ +#define __HW_SMWDTHROSC_H__ + +//***************************************************************************** +// +// The following are defines for the SMWDTHROSC register offsets. +// +//***************************************************************************** +#define SMWDTHROSC_WDCTL 0x400D5000 // Watchdog Timer Control +#define SMWDTHROSC_ST0 0x400D5040 // Sleep Timer 0 count and compare +#define SMWDTHROSC_ST1 0x400D5044 // Sleep Timer 1 count and compare +#define SMWDTHROSC_ST2 0x400D5048 // Sleep Timer 2 count and compare +#define SMWDTHROSC_ST3 0x400D504C // Sleep Timer 3 count and compare +#define SMWDTHROSC_STLOAD 0x400D5050 // Sleep Timer load status +#define SMWDTHROSC_STCC 0x400D5054 // Sleep Timer Capture control +#define SMWDTHROSC_STCS 0x400D5058 // Sleep Timer Capture status +#define SMWDTHROSC_STCV0 0x400D505C // Sleep Timer Capture value byte + // 0 +#define SMWDTHROSC_STCV1 0x400D5060 // Sleep Timer Capture value byte + // 1 +#define SMWDTHROSC_STCV2 0x400D5064 // Sleep Timer Capture value byte + // 2 +#define SMWDTHROSC_STCV3 0x400D5068 // Sleep Timer Capture value byte + // 3 + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_WDCTL register. +// +//***************************************************************************** +#define SMWDTHROSC_WDCTL_CLR_M 0x000000F0 // Clear timer When 0xA followed + // by 0x5 is written to these bits, + // the timer is loaded with 0x0000. + // Note that 0x5 must be written + // within one watchdog clock period + // Twdt after 0xA was written for + // the clearing to take effect + // (ensured). If 0x5 is written + // between Twdt and 2Twdt after 0xA + // was written, the clearing may + // take effect, but there is no + // guarantee. If 0x5 is written > + // 2Twdt after 0xA was written, the + // timer will not be cleared. If a + // value other than 0x5 is written + // after 0xA has been written, the + // clear sequence is aborted. If + // 0xA is written, this starts a + // new clear sequence. Writing to + // these bits when EN = 0 has no + // effect. +#define SMWDTHROSC_WDCTL_CLR_S 4 +#define SMWDTHROSC_WDCTL_EN 0x00000008 // Enable timer When 1 is written + // to this bit the timer is enabled + // and starts incrementing. The + // interval setting specified by + // INT[1:0] is used. Writing 0 to + // this bit have no effect. +#define SMWDTHROSC_WDCTL_EN_M 0x00000008 +#define SMWDTHROSC_WDCTL_EN_S 3 +#define SMWDTHROSC_WDCTL_INT_M 0x00000003 // Timer interval select These + // bits select the timer interval + // as follows: 00: Twdt x 32768 01: + // Twdt x 8192 10: Twdt x 512 11: + // Twdt x 64 Writing these bits + // when EN = 1 has no effect. +#define SMWDTHROSC_WDCTL_INT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_ST0 register. +// +//***************************************************************************** +#define SMWDTHROSC_ST0_ST0_M 0x000000FF // Sleep Timer count and compare + // value. When read, this register + // returns the low bits [7:0] of + // the Sleep Timer count. When + // writing this register sets the + // low bits [7:0] of the compare + // value. +#define SMWDTHROSC_ST0_ST0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_ST1 register. +// +//***************************************************************************** +#define SMWDTHROSC_ST1_ST1_M 0x000000FF // Sleep Timer count and compare + // value When read, this register + // returns the middle bits [15:8] + // of the Sleep Timer count. When + // writing this register sets the + // middle bits [15:8] of the + // compare value. The value read is + // latched at the time of reading + // register ST0. The value written + // is latched when ST0 is written. +#define SMWDTHROSC_ST1_ST1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_ST2 register. +// +//***************************************************************************** +#define SMWDTHROSC_ST2_ST2_M 0x000000FF // Sleep Timer count and compare + // value When read, this register + // returns the high bits [23:16] of + // the Sleep Timer count. When + // writing this register sets the + // high bits [23:16] of the compare + // value. The value read is latched + // at the time of reading register + // ST0. The value written is + // latched when ST0 is written. +#define SMWDTHROSC_ST2_ST2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_ST3 register. +// +//***************************************************************************** +#define SMWDTHROSC_ST3_ST3_M 0x000000FF // Sleep Timer count and compare + // value When read, this register + // returns the high bits [31:24] of + // the Sleep Timer count. When + // writing this register sets the + // high bits [31:24] of the compare + // value. The value read is latched + // at the time of reading register + // ST0. The value written is + // latched when ST0 is written. +#define SMWDTHROSC_ST3_ST3_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_STLOAD register. +// +//***************************************************************************** +#define SMWDTHROSC_STLOAD_STLOAD \ + 0x00000001 // Status signal for when STx + // registers have been uploaded to + // 32-kHz counter. 1: Load is + // complete 0: Load is busy and STx + // regs are blocked for writing + +#define SMWDTHROSC_STLOAD_STLOAD_M \ + 0x00000001 +#define SMWDTHROSC_STLOAD_STLOAD_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_STCC register. +// +//***************************************************************************** +#define SMWDTHROSC_STCC_PORT_M 0x00000038 // Port select Valid settings are + // 0-3, all others inhibit any + // capture from occurring 000: Port + // A selected 001: Port B selected + // 010: Port C selected 011: Port D + // selected +#define SMWDTHROSC_STCC_PORT_S 3 +#define SMWDTHROSC_STCC_PIN_M 0x00000007 // Pin select Valid settings are + // 1-7 when either port A, B, C, or + // D is selected. +#define SMWDTHROSC_STCC_PIN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_STCS register. +// +//***************************************************************************** +#define SMWDTHROSC_STCS_VALID 0x00000001 // Capture valid flag Set to 1 + // when capture value in STCV has + // been updated Clear explicitly to + // allow new capture +#define SMWDTHROSC_STCS_VALID_M 0x00000001 +#define SMWDTHROSC_STCS_VALID_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_STCV0 register. +// +//***************************************************************************** +#define SMWDTHROSC_STCV0_STCV0_M \ + 0x000000FF // Bits [7:0] of Sleep Timer + // capture value + +#define SMWDTHROSC_STCV0_STCV0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_STCV1 register. +// +//***************************************************************************** +#define SMWDTHROSC_STCV1_STCV1_M \ + 0x000000FF // Bits [15:8] of Sleep Timer + // capture value + +#define SMWDTHROSC_STCV1_STCV1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_STCV2 register. +// +//***************************************************************************** +#define SMWDTHROSC_STCV2_STCV2_M \ + 0x000000FF // Bits [23:16] of Sleep Timer + // capture value + +#define SMWDTHROSC_STCV2_STCV2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SMWDTHROSC_STCV3 register. +// +//***************************************************************************** +#define SMWDTHROSC_STCV3_STCV3_M \ + 0x000000FF // Bits [32:24] of Sleep Timer + // capture value + +#define SMWDTHROSC_STCV3_STCV3_S 0 + + +#endif // __HW_SMWDTHROSC_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_soc_adc.h b/bsp/boards/mimsy2-cc2538/headers/hw_soc_adc.h new file mode 100644 index 0000000000..9ec071c4f5 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_soc_adc.h @@ -0,0 +1,267 @@ +/****************************************************************************** +* Filename: hw_soc_adc.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_SOC_ADC_H__ +#define __HW_SOC_ADC_H__ + +//***************************************************************************** +// +// The following are defines for the SOC_ADC register offsets. +// +//***************************************************************************** +#define SOC_ADC_ADCCON1 0x400D7000 // This register controls the ADC. +#define SOC_ADC_ADCCON2 0x400D7004 // This register controls the ADC. +#define SOC_ADC_ADCCON3 0x400D7008 // This register controls the ADC. +#define SOC_ADC_ADCL 0x400D700C // This register contains the + // least-significant part of ADC + // conversion result. +#define SOC_ADC_ADCH 0x400D7010 // This register contains the + // most-significant part of ADC + // conversion result. +#define SOC_ADC_RNDL 0x400D7014 // This registers contains + // random-number-generator data; + // low byte. +#define SOC_ADC_RNDH 0x400D7018 // This register contains + // random-number-generator data; + // high byte. +#define SOC_ADC_CMPCTL 0x400D7024 // Analog comparator control and + // status register. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SOC_ADC_ADCCON1 register. +// +//***************************************************************************** +#define SOC_ADC_ADCCON1_EOC 0x00000080 // End of conversion. Cleared when + // ADCH has been read. If a new + // conversion is completed before + // the previous data has been read, + // the EOC bit remains high. 0: + // Conversion not complete 1: + // Conversion completed +#define SOC_ADC_ADCCON1_EOC_M 0x00000080 +#define SOC_ADC_ADCCON1_EOC_S 7 +#define SOC_ADC_ADCCON1_ST 0x00000040 // Start conversion Read as 1 + // until conversion completes 0: No + // conversion in progress. 1: Start + // a conversion sequence if + // ADCCON1.STSEL = 11 and no + // sequence is running. +#define SOC_ADC_ADCCON1_ST_M 0x00000040 +#define SOC_ADC_ADCCON1_ST_S 6 +#define SOC_ADC_ADCCON1_STSEL_M 0x00000030 // Start select Selects the event + // that starts a new conversion + // sequence 00: Not implemented 01: + // Full speed. Do not wait for + // triggers 10: Timer 1 channel 0 + // compare event 11: ADCCON1.ST = 1 +#define SOC_ADC_ADCCON1_STSEL_S 4 +#define SOC_ADC_ADCCON1_RCTRL_M 0x0000000C // Controls the 16-bit + // random-number generator (see + // User Guide Chapter 16) When 01 + // is written, the setting + // automatically returns to 00 when + // the operation completes. 00: + // Normal operation (13x unrolling) + // 01: Clock the LFSR once (13x + // unrolling) 10: Reserved 11: + // Stopped. The random-number + // generator is turned off. +#define SOC_ADC_ADCCON1_RCTRL_S 2 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SOC_ADC_ADCCON2 register. +// +//***************************************************************************** +#define SOC_ADC_ADCCON2_SREF_M 0x000000C0 // Selects reference voltage used + // for the sequence of conversions + // 00: Internal reference 01: + // External reference on AIN7 pin + // 10: AVDD5 pin 11: External + // reference on AIN6-AIN7 + // differential input +#define SOC_ADC_ADCCON2_SREF_S 6 +#define SOC_ADC_ADCCON2_SDIV_M 0x00000030 // Sets the decimation rate for + // channels included in the + // sequence of conversions. The + // decimation rate also determines + // the resolution and time required + // to complete a conversion. 00: 64 + // decimation rate (7 bits ENOB + // setting) 01: 128 decimation rate + // (9 bits ENOB setting) 10: 256 + // decimation rate (10 bits ENOB + // setting) 11: 512 decimation rate + // (12 bits ENOB setting) +#define SOC_ADC_ADCCON2_SDIV_S 4 +#define SOC_ADC_ADCCON2_SCH_M 0x0000000F // Sequence channel select Selects + // the end of the sequence A + // sequence can either be from AIN0 + // to AIN7 (SCH <= 7) or from + // differential input AIN0-AIN1 to + // AIN6-AIN7 (8 <= SCH <= 11). For + // other settings, only one + // conversions is performed. When + // read, these bits indicate the + // channel number on which a + // conversion is ongoing: 0000: + // AIN0 0001: AIN1 0010: AIN2 0011: + // AIN3 0100: AIN4 0101: AIN5 0110: + // AIN6 0111: AIN7 1000: AIN0-AIN1 + // 1001: AIN2-AIN3 1010: AIN4-AIN5 + // 1011: AIN6-AIN7 1100: GND 1101: + // Reserved 1110: Temperature + // sensor 1111: VDD/3 +#define SOC_ADC_ADCCON2_SCH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SOC_ADC_ADCCON3 register. +// +//***************************************************************************** +#define SOC_ADC_ADCCON3_EREF_M 0x000000C0 // Selects reference voltage used + // for the extra conversion 00: + // Internal reference 01: External + // reference on AIN7 pin 10: AVDD5 + // pin 11: External reference on + // AIN6-AIN7 differential input +#define SOC_ADC_ADCCON3_EREF_S 6 +#define SOC_ADC_ADCCON3_EDIV_M 0x00000030 // Sets the decimation rate used + // for the extra conversion The + // decimation rate also determines + // the resolution and the time + // required to complete the + // conversion. 00: 64 decimation + // rate (7 bits ENOB) 01: 128 + // decimation rate (9 bits ENOB) + // 10: 256 decimation rate (10 bits + // ENOB) 11: 512 decimation rate + // (12 bits ENOB) +#define SOC_ADC_ADCCON3_EDIV_S 4 +#define SOC_ADC_ADCCON3_ECH_M 0x0000000F // Single channel select. Selects + // the channel number of the single + // conversion that is triggered by + // writing to ADCCON3. 0000: AIN0 + // 0001: AIN1 0010: AIN2 0011: AIN3 + // 0100: AIN4 0101: AIN5 0110: AIN6 + // 0111: AIN7 1000: AIN0-AIN1 1001: + // AIN2-AIN3 1010: AIN4-AIN5 1011: + // AIN6-AIN7 1100: GND 1101: + // Reserved 1110: Temperature + // sensor 1111: VDD/3 +#define SOC_ADC_ADCCON3_ECH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SOC_ADC_ADCL register. +// +//***************************************************************************** +#define SOC_ADC_ADCL_ADC_M 0x000000FC // Least-significant part of ADC + // conversion result +#define SOC_ADC_ADCL_ADC_S 2 +//***************************************************************************** +// +// The following are defines for the bit fields in the SOC_ADC_ADCH register. +// +//***************************************************************************** +#define SOC_ADC_ADCH_ADC_M 0x000000FF // Most-significant part of ADC + // conversion result +#define SOC_ADC_ADCH_ADC_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SOC_ADC_RNDL register. +// +//***************************************************************************** +#define SOC_ADC_RNDL_RNDL_M 0x000000FF // Random value/seed or CRC + // result, low byte When used for + // random-number generation, + // writing to this register twice + // seeds the random-number + // generator. Writing to this + // register copies the 8 LSBs of + // the LFSR to the 8 MSBs and + // replaces the 8 LSBs with the + // data value written. The value + // returned when reading from this + // register is the 8 LSBs of the + // LFSR. When used for + // random-number generation, + // reading this register returns + // the 8 LSBs of the random number. + // When used for CRC calculations, + // reading this register returns + // the 8 LSBs of the CRC result. +#define SOC_ADC_RNDL_RNDL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SOC_ADC_RNDH register. +// +//***************************************************************************** +#define SOC_ADC_RNDH_RNDH_M 0x000000FF // Random value or CRC + // result/input data, high byte + // When written, a CRC16 + // calculation is triggered, and + // the data value written is + // processed starting with the MSB. + // The value returned when reading + // from this register is the 8 MSBs + // of the LFSR. When used for + // random-number generation, + // reading this register returns + // the 8 MSBs of the random number. + // When used for CRC calculations, + // reading this register returns + // the 8 MSBs of the CRC result. +#define SOC_ADC_RNDH_RNDH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SOC_ADC_CMPCTL register. +// +//***************************************************************************** +#define SOC_ADC_CMPCTL_EN 0x00000002 // Comparator enable +#define SOC_ADC_CMPCTL_EN_M 0x00000002 +#define SOC_ADC_CMPCTL_EN_S 1 +#define SOC_ADC_CMPCTL_OUTPUT 0x00000001 // Comparator output +#define SOC_ADC_CMPCTL_OUTPUT_M 0x00000001 +#define SOC_ADC_CMPCTL_OUTPUT_S 0 + + +#endif // __HW_SOC_ADC_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_ssi.h b/bsp/boards/mimsy2-cc2538/headers/hw_ssi.h new file mode 100644 index 0000000000..e2b97763c9 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_ssi.h @@ -0,0 +1,491 @@ +/****************************************************************************** +* Filename: hw_ssi.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_SSI_H__ +#define __HW_SSI_H__ + +//***************************************************************************** +// +// The following are defines for the SSI register offsets. +// +//***************************************************************************** +#define SSI_O_CR0 0x00000000 // The CR0 register contains bit + // fields that control various + // functions within the SSI module. + // Functionality such as protocol + // mode, clock rate, and data size + // are configured in this register. +#define SSI_O_CR1 0x00000004 // The CR1 register contains bit + // fields that control various + // functions within the SSI module. + // Master and slave mode + // functionality is controlled by + // this register. +#define SSI_O_DR 0x00000008 // The DR register is 16 bits + // wide. When the SSIDR register is + // read, the entry in the receive + // FIFO that is pointed to by the + // current FIFO read pointer is + // accessed. When a data value is + // removed by the SSI receive logic + // from the incoming data frame, it + // is placed into the entry in the + // receive FIFO pointed to by the + // current FIFO write pointer. When + // the DR register is written to, + // the entry in the transmit FIFO + // that is pointed to by the write + // pointer is written to. Data + // values are removed from the + // transmit FIFO one value at a + // time by the transmit logic. Each + // data value is loaded into the + // transmit serial shifter, then + // serially shifted out onto the + // SSITx pin at the programmed bit + // rate. When a data size of less + // than 16 bits is selected, the + // user must right-justify data + // written to the transmit FIFO. + // The transmit logic ignores the + // unused bits. Received data less + // than 16 bits is automatically + // right-justified in the receive + // buffer. When the SSI is + // programmed for MICROWIRE frame + // format, the default size for + // transmit data is eight bits (the + // most significant byte is + // ignored). The receive data size + // is controlled by the programmer. + // The transmit FIFO and the + // receive FIFO are not cleared + // even when the SSE bit in the + // SSICR1 register is cleared, + // allowing the software to fill + // the transmit FIFO before + // enabling the SSI. +#define SSI_O_SR 0x0000000C // The SR register contains bits + // that indicate the FIFO fill + // status and the SSI busy status. +#define SSI_O_CPSR 0x00000010 // The CPSR register specifies the + // division factor which is used to + // derive the SSIClk from the + // system clock. The clock is + // further divided by a value from + // 1 to 256, which is 1 + SCR. SCR + // is programmed in the SSICR0 + // register. The frequency of the + // SSIClk is defined by: SSIClk = + // SysClk / (CPSDVSR x (1 + SCR)) + // The value programmed into this + // register must be an even number + // between 2 and 254. The + // least-significant bit of the + // programmed number is hard-coded + // to zero. If an odd number is + // written to this register, data + // read back from this register has + // the least-significant bit as + // zero. +#define SSI_O_IM 0x00000014 // The IM register is the + // interrupt mask set or clear + // register. It is a read/write + // register and all bits are + // cleared on reset. On a read, + // this register gives the current + // value of the mask on the + // corresponding interrupt. Setting + // a bit sets the mask, preventing + // the interrupt from being + // signaled to the interrupt + // controller. Clearing a bit + // clears the corresponding mask, + // enabling the interrupt to be + // sent to the interrupt + // controller. +#define SSI_O_RIS 0x00000018 // The RIS register is the raw + // interrupt status register. On a + // read, this register gives the + // current raw status value of the + // corresponding interrupt before + // masking. A write has no effect. +#define SSI_O_MIS 0x0000001C // The MIS register is the masked + // interrupt status register. On a + // read, this register gives the + // current masked status value of + // the corresponding interrupt. A + // write has no effect. +#define SSI_O_ICR 0x00000020 // The ICR register is the + // interrupt clear register. On a + // write of 1, the corresponding + // interrupt is cleared. A write of + // 0 has no effect. +#define SSI_O_DMACTL 0x00000024 // The DMACTL register is the uDMA + // control register. +#define SSI_O_CC 0x00000FC8 // SSI clock configuration The CC + // register controls the baud clock + // and system clocks sources for + // the SSI module. Note: If the + // PIOSC is used for the SSI baud + // clock, the system clock + // frequency must be at least 16 + // MHz in run mode. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_CR0 register. +// +//***************************************************************************** +#define SSI_CR0_SCR_M 0x0000FF00 // SSI serial clock rate (R/W) + // Reset value: 0x0 The value SCR + // is used to generate the transmit + // and receive bit rate of the SSI. + // Where the bit rate is: BR = + // FSSICLK/(CPSDVR * (1 + SCR)) + // where CPSDVR is an even value + // from 2-254, programmed in the + // SSICPSR register and SCR is a + // value from 0-255. +#define SSI_CR0_SCR_S 8 +#define SSI_CR0_SPH 0x00000080 // SSI serial clock phase (R/W) + // Reset value: 0x0 This bit is + // only applicable to the Motorola + // SPI Format. +#define SSI_CR0_SPH_M 0x00000080 +#define SSI_CR0_SPH_S 7 +#define SSI_CR0_SPO 0x00000040 // SSI serial clock phase (R/W) + // Reset value: 0x0 This bit is + // only applicable to the Motorola + // SPI Format. +#define SSI_CR0_SPO_M 0x00000040 +#define SSI_CR0_SPO_S 6 +#define SSI_CR0_FRF_M 0x00000030 // SSI frame format select (R/W) + // Reset value: 0x0 00: Motorola + // SPI frame format 01: TI + // synchronous serial frame format + // 10: National Microwire frame + // format 11: Reserved +#define SSI_CR0_FRF_S 4 +#define SSI_CR0_DSS_M 0x0000000F // SSI data size select (R/W) + // Reset value: 0x0 0000-0010: + // Reserved 0011: 4-bit data 0100: + // 5-bit data 0101: 6-bit data + // 0110: 7-bit data 0111: 8-bit + // data 1000: 9-bit data 1001: + // 10-bit data 1010: 11-bit data + // 1011: 12-bit data 1100: 13-bit + // data 1101: 14-bit data 1110: + // 15-bit data 1111: 16-bit data +#define SSI_CR0_DSS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_CR1 register. +// +//***************************************************************************** +#define SSI_CR1_SOD 0x00000008 // SSI slave mode output disable + // (R/W) Reset value: 0x0 This bit + // is relevant only in the slave + // mode (MS = 1). In multiple-slave + // systems, it is possible for the + // SSI master to broadcast a + // message to all slaves in the + // system while ensuring that only + // one slave drives data onto the + // serial output line. In such + // systems, the RXD lines from + // multiple slaves could be tied + // together. To operate in such a + // system, the SOD bit can be set + // if the SSI slave is not suppose + // to drive the SSITXD line. 0: SSI + // can drive SSITXD in slave output + // mode 1: SSI must not drive the + // SSITXD output in slave mode +#define SSI_CR1_SOD_M 0x00000008 +#define SSI_CR1_SOD_S 3 +#define SSI_CR1_MS 0x00000004 // SSI master and slave select + // (R/W) Reset value: 0x0 This bit + // can be modified only when the + // SSI is disabled (SSE = 0). 0: + // Device configured as a master + // (default) 1: Device configured + // as a slave +#define SSI_CR1_MS_M 0x00000004 +#define SSI_CR1_MS_S 2 +#define SSI_CR1_SSE 0x00000002 // SSI synchronous serial port + // enable (R/W) Reset value: 0x0 0: + // SSI operation is disabled. 1: + // SSI operation is enabled. +#define SSI_CR1_SSE_M 0x00000002 +#define SSI_CR1_SSE_S 1 +#define SSI_CR1_LBM 0x00000001 // SSI loop-back mode (R/W) Reset + // value: 0x0 0: Normal serial port + // operation is enabled. 1: The + // output of the transmit serial + // shifter is connected to the + // input of the receive serial + // shift register internally. +#define SSI_CR1_LBM_M 0x00000001 +#define SSI_CR1_LBM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_DR register. +// +//***************************************************************************** +#define SSI_DR_DATA_M 0x0000FFFF // SSI receive/transmit data + // register (R/W) Reset value: + // 0xXXXX A read operation reads + // the receive FIFO. A write + // operation writes the transmit + // FIFO. Software must + // right-justify data when the SSI + // is programmed for a data size + // that is less than 16 bits. + // Unused bits at the top are + // ignored by the transmit logic. + // The receive logic automatically + // right-justified the data. +#define SSI_DR_DATA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_SR register. +// +//***************************************************************************** +#define SSI_SR_BSY 0x00000010 // SSI busy bit (RO) Reset value: + // 0x0 0: SSI is idle. 1: SSI is + // currently transmitting and/or + // receiving a frame or the + // transmit FIFO is not empty. +#define SSI_SR_BSY_M 0x00000010 +#define SSI_SR_BSY_S 4 +#define SSI_SR_RFF 0x00000008 // SSI receive FIFO full (RO) + // Reset value: 0x0 0: Receive FIFO + // is not full. 1: Receive FIFO is + // full. +#define SSI_SR_RFF_M 0x00000008 +#define SSI_SR_RFF_S 3 +#define SSI_SR_RNE 0x00000004 // SSI receive FIFO not empty (RO) + // Reset value: 0x0 0: Receive FIFO + // is empty. 1: Receive FIFO is not + // empty. +#define SSI_SR_RNE_M 0x00000004 +#define SSI_SR_RNE_S 2 +#define SSI_SR_TNF 0x00000002 // SSI transmit FIFO not full (RO) + // Reset value: 0x1 0: Transmit + // FIFO is full. 1: Transmit FIFO + // is not full. +#define SSI_SR_TNF_M 0x00000002 +#define SSI_SR_TNF_S 1 +#define SSI_SR_TFE 0x00000001 // SSI transmit FIFO empty (RO) + // Reset value: 0x1 0: Transmit + // FIFO is not empty. 1: Transmit + // FIFO is empty. +#define SSI_SR_TFE_M 0x00000001 +#define SSI_SR_TFE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_CPSR register. +// +//***************************************************************************** +#define SSI_CPSR_CPSDVSR_M 0x000000FF // SSI clock prescale divisor + // (R/W) Reset value: 0x0 This + // value must be an even number + // from 2 to 254, depending on the + // frequency of SSICLK. The LSB + // always returns zero on reads. +#define SSI_CPSR_CPSDVSR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_IM register. +// +//***************************************************************************** +#define SSI_IM_TXIM 0x00000008 // SSI transmit FIFO interrupt + // mask (R/W) Reset value: 0x0 0: + // TX FIFO half empty or condition + // interrupt is masked. 1: TX FIFO + // half empty or less condition + // interrupt is not masked. +#define SSI_IM_TXIM_M 0x00000008 +#define SSI_IM_TXIM_S 3 +#define SSI_IM_RXIM 0x00000004 // SSI receive FIFO interrupt mask + // (R/W) Reset value: 0x0 0: RX + // FIFO half empty or condition + // interrupt is masked. 1: RX FIFO + // half empty or less condition + // interrupt is not masked. +#define SSI_IM_RXIM_M 0x00000004 +#define SSI_IM_RXIM_S 2 +#define SSI_IM_RTIM 0x00000002 // SSI receive time-out interrupt + // mask (R/W) Reset value: 0x0 0: + // RX FIFO time-out interrupt is + // masked. 1: RX FIFO time-out + // interrupt is not masked +#define SSI_IM_RTIM_M 0x00000002 +#define SSI_IM_RTIM_S 1 +#define SSI_IM_RORIM 0x00000001 // SSI receive overrun interrupt + // mask (R/W) Reset value: 0x0 0: + // RX FIFO Overrun interrupt is + // masked. 1: RX FIFO Overrun + // interrupt is not masked +#define SSI_IM_RORIM_M 0x00000001 +#define SSI_IM_RORIM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_RIS register. +// +//***************************************************************************** +#define SSI_RIS_TXRIS 0x00000008 // SSI SSITXINTR raw state (RO) + // Reset value: 0x1 Gives the raw + // interrupt state (before masking) + // of SSITXINTR +#define SSI_RIS_TXRIS_M 0x00000008 +#define SSI_RIS_TXRIS_S 3 +#define SSI_RIS_RXRIS 0x00000004 // SSI SSIRXINTR raw state (RO) + // Reset value: 0x0 Gives the raw + // interrupt state (before masking) + // of SSIRXINTR +#define SSI_RIS_RXRIS_M 0x00000004 +#define SSI_RIS_RXRIS_S 2 +#define SSI_RIS_RTRIS 0x00000002 // SSI SSIRTINTR raw state (RO) + // Reset value: 0x0 Gives the raw + // interrupt state (before masking) + // of SSIRTINTR +#define SSI_RIS_RTRIS_M 0x00000002 +#define SSI_RIS_RTRIS_S 1 +#define SSI_RIS_RORRIS 0x00000001 // SSI SSIRORINTR raw state (RO) + // Reset value: 0x0 Gives the raw + // interrupt state (before masking) + // of SSIRORINTR +#define SSI_RIS_RORRIS_M 0x00000001 +#define SSI_RIS_RORRIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_MIS register. +// +//***************************************************************************** +#define SSI_MIS_TXMIS 0x00000008 // SSI SSITXINTR masked state (RO) + // Reset value: 0x0 Gives the + // interrupt state (after masking) + // of SSITXINTR +#define SSI_MIS_TXMIS_M 0x00000008 +#define SSI_MIS_TXMIS_S 3 +#define SSI_MIS_RXMIS 0x00000004 // SSI SSIRXINTR masked state (RO) + // Reset value: 0x0 Gives the + // interrupt state (after masking) + // of SSIRXINTR +#define SSI_MIS_RXMIS_M 0x00000004 +#define SSI_MIS_RXMIS_S 2 +#define SSI_MIS_RTMIS 0x00000002 // SSI SSIRTINTR masked state (RO) + // Reset value: 0x0 Gives the + // interrupt state (after masking) + // of SSIRTINTR +#define SSI_MIS_RTMIS_M 0x00000002 +#define SSI_MIS_RTMIS_S 1 +#define SSI_MIS_RORMIS 0x00000001 // SSI SSIRORINTR masked state + // (RO) Reset value: 0x0 Gives the + // interrupt state (after masking) + // of SSIRORINTR +#define SSI_MIS_RORMIS_M 0x00000001 +#define SSI_MIS_RORMIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_ICR register. +// +//***************************************************************************** +#define SSI_ICR_RTIC 0x00000002 // SSI receive time-out interrupt + // clear (W1C) Reset value: 0x0 0: + // No effect on interrupt 1: Clears + // interrupt +#define SSI_ICR_RTIC_M 0x00000002 +#define SSI_ICR_RTIC_S 1 +#define SSI_ICR_RORIC 0x00000001 // SSI receive overrun interrupt + // clear (W1C) Reset value: 0x0 0: + // No effect on interrupt 1: Clears + // interrupt +#define SSI_ICR_RORIC_M 0x00000001 +#define SSI_ICR_RORIC_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_DMACTL register. +// +//***************************************************************************** +#define SSI_DMACTL_TXDMAE 0x00000002 // Transmit DMA enable 0: uDMA for + // the transmit FIFO is disabled. + // 1: uDMA for the transmit FIFO is + // enabled. +#define SSI_DMACTL_TXDMAE_M 0x00000002 +#define SSI_DMACTL_TXDMAE_S 1 +#define SSI_DMACTL_RXDMAE 0x00000001 // Receive DMA enable 0: uDMA for + // the receive FIFO is disabled. 1: + // uDMA for the receive FIFO is + // enabled. +#define SSI_DMACTL_RXDMAE_M 0x00000001 +#define SSI_DMACTL_RXDMAE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SSI_O_CC register. +// +//***************************************************************************** +#define SSI_CC_CS_M 0x00000007 // SSI baud and system clock + // source The following bits + // determine the clock source that + // generates the baud and system + // clocks for the SSI. bit0 + // (PIOSC): 1: The SSI baud clock + // is determined by the IO DIV + // setting in the system + // controller. 0: The SSI baud + // clock is determined by the SYS + // DIV setting in the system + // controller. bit1: Unused bit2: + // (DSEN) Only meaningful when the + // system is in deep sleep mode. + // This bit is a don't care when + // not in sleep mode. 1: The SSI + // system clock is running on the + // same clock as the baud clock, as + // per PIOSC setting above. 0: The + // SSI system clock is determined + // by the SYS DIV setting in the + // system controller. +#define SSI_CC_CS_S 0 + + +#endif // __HW_SSI_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_sys_ctrl.h b/bsp/boards/mimsy2-cc2538/headers/hw_sys_ctrl.h new file mode 100644 index 0000000000..bec267a98d --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_sys_ctrl.h @@ -0,0 +1,961 @@ +/****************************************************************************** +* Filename: hw_sys_ctrl.h +* Revised: $Date: 2013-04-12 15:10:54 +0200 (Fri, 12 Apr 2013) $ +* Revision: $Revision: 9735 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_SYS_CTRL_H__ +#define __HW_SYS_CTRL_H__ + +//***************************************************************************** +// +// The following are defines for the SYS_CTRL register offsets. +// +//***************************************************************************** +#define SYS_CTRL_CLOCK_CTRL 0x400D2000 // The clock control register + // handels clock settings in the + // CC2538. The settings in + // CLOCK_CTRL do not always reflect + // the current chip status which is + // found in CLOCK_STA register. +#define SYS_CTRL_CLOCK_STA 0x400D2004 // Clock status register This + // register reflects the current + // chip status. +#define SYS_CTRL_RCGCGPT 0x400D2008 // This register defines the + // module clocks for GPT[3:0] when + // the CPU is in active (run) mode. + // This register setting is don't + // care for PM1-3, because the + // system clock is powered down in + // these modes. +#define SYS_CTRL_SCGCGPT 0x400D200C // This register defines the + // module clocks for GPT[3:0] when + // the CPU is in sleep mode. This + // register setting is don't care + // for PM1-3, because the system + // clock is powered down in these + // modes. +#define SYS_CTRL_DCGCGPT 0x400D2010 // This register defines the + // module clocks for GPT[3:0] when + // the CPU is in PM0. This register + // setting is don't care for PM1-3, + // because the system clock is + // powered down in these modes. +#define SYS_CTRL_SRGPT 0x400D2014 // This register controls the + // reset for GPT[3:0]. +#define SYS_CTRL_RCGCSSI 0x400D2018 // This register defines the + // module clocks for SSI[1:0] when + // the CPU is in active (run) mode. + // This register setting is don't + // care for PM1-3, because the + // system clock is powered down in + // these modes. +#define SYS_CTRL_SCGCSSI 0x400D201C // This register defines the + // module clocks for SSI[1:0] when + // the CPU is insSleep mode. This + // register setting is don't care + // for PM1-3, because the system + // clock is powered down in these + // modes. +#define SYS_CTRL_DCGCSSI 0x400D2020 // This register defines the + // module clocks for SSI[1:0] when + // the CPU is in PM0. This register + // setting is don't care for PM1-3, + // because the system clock is + // powered down in these modes. +#define SYS_CTRL_SRSSI 0x400D2024 // This register controls the + // reset for SSI[1:0]. +#define SYS_CTRL_RCGCUART 0x400D2028 // This register defines the + // module clocks for UART[1:0] when + // the CPU is in active (run) mode. + // This register setting is don't + // care for PM1-3, because the + // system clock is powered down in + // these modes. +#define SYS_CTRL_SCGCUART 0x400D202C // This register defines the + // module clocks for UART[1:0] when + // the CPU is in sleep mode. This + // register setting is don't care + // for PM1-3, because the system + // clock is powered down in these + // modes. +#define SYS_CTRL_DCGCUART 0x400D2030 // This register defines the + // module clocks for UART[1:0] when + // the CPU is in PM0. This register + // setting is don't care for PM1-3, + // because the system clock is + // powered down in these modes. +#define SYS_CTRL_SRUART 0x400D2034 // This register controls the + // reset for UART[1:0]. +#define SYS_CTRL_RCGCI2C 0x400D2038 // This register defines the + // module clocks for I2C when the + // CPU is in active (run) mode. + // This register setting is don't + // care for PM1-3, because the + // system clock is powered down in + // these modes. +#define SYS_CTRL_SCGCI2C 0x400D203C // This register defines the + // module clocks for I2C when the + // CPU is in sleep mode. This + // register setting is don't care + // for PM1-3, because the system + // clock is powered down in these + // modes. +#define SYS_CTRL_DCGCI2C 0x400D2040 // This register defines the + // module clocks for I2C when the + // CPU is in PM0. This register + // setting is don't care for PM1-3, + // because the system clock is + // powered down in these modes. +#define SYS_CTRL_SRI2C 0x400D2044 // This register controls the + // reset for I2C. +#define SYS_CTRL_RCGCSEC 0x400D2048 // This register defines the + // module clocks for the security + // module when the CPU is in active + // (run) mode. This register + // setting is don't care for PM1-3, + // because the system clock is + // powered down in these modes. +#define SYS_CTRL_SCGCSEC 0x400D204C // This register defines the + // module clocks for the security + // module when the CPU is in sleep + // mode. This register setting is + // don't care for PM1-3, because + // the system clock is powered down + // in these modes. +#define SYS_CTRL_DCGCSEC 0x400D2050 // This register defines the + // module clocks for the security + // module when the CPU is in PM0. + // This register setting is don't + // care for PM1-3, because the + // system clock is powered down in + // these modes. +#define SYS_CTRL_SRSEC 0x400D2054 // This register controls the + // reset for the security module. +#define SYS_CTRL_PMCTL 0x400D2058 // This register controls the + // power mode. Note: The + // Corresponding PM is not entered + // before the WFI instruction is + // asserted. To enter PM1-3 the + // DEEPSLEEP bit in SYSCTRL must be + // 1. +#define SYS_CTRL_SRCRC 0x400D205C // This register controls CRC on + // state retention. +#define SYS_CTRL_PWRDBG 0x400D2074 // Power debug register +#define SYS_CTRL_CLD 0x400D2080 // This register controls the + // clock loss detection feature. +#define SYS_CTRL_IWE 0x400D2094 // This register controls + // interrupt wake-up. +#define SYS_CTRL_I_MAP 0x400D2098 // This register selects which + // interrupt map to be used. +#define SYS_CTRL_RCGCRFC 0x400D20A8 // This register defines the + // module clocks for RF CORE when + // the CPU is in active (run) mode. + // This register setting is don't + // care for PM1-3, because the + // system clock is powered down in + // these modes. +#define SYS_CTRL_SCGCRFC 0x400D20AC // This register defines the + // module clocks for RF CORE when + // the CPU is in sleep mode. This + // register setting is don't care + // for PM1-3, because the system + // clock is powered down in these + // modes. +#define SYS_CTRL_DCGCRFC 0x400D20B0 // This register defines the + // module clocks for RF CORE when + // the CPU is in PM0. This register + // setting is don't care for PM1-3, + // because the system clock is + // powered down in these modes. +#define SYS_CTRL_EMUOVR 0x400D20B4 // This register defines the + // emulator override controls for + // power mode and peripheral clock + // gate. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_CLOCK_CTRL register. +// +//***************************************************************************** +#define SYS_CTRL_CLOCK_CTRL_OSC32K_CALDIS \ + 0x02000000 // Disable calibration 32-kHz RC + // oscillator. 0: Enable + // calibration 1: Disable + // calibration + +#define SYS_CTRL_CLOCK_CTRL_OSC32K_CALDIS_M \ + 0x02000000 +#define SYS_CTRL_CLOCK_CTRL_OSC32K_CALDIS_S 25 +#define SYS_CTRL_CLOCK_CTRL_OSC32K \ + 0x01000000 // 32-kHz clock oscillator + // selection 0: 32-kHz crystal + // oscillator 1: 32-kHz RC + // oscillator + +#define SYS_CTRL_CLOCK_CTRL_OSC32K_M \ + 0x01000000 +#define SYS_CTRL_CLOCK_CTRL_OSC32K_S 24 +#define SYS_CTRL_CLOCK_CTRL_AMP_DET \ + 0x00200000 // Amplitude detector of XOSC + // during power up 0: No action 1: + // Delay qualification of XOSC + // until amplitude is greater than + // the threshold. + +#define SYS_CTRL_CLOCK_CTRL_AMP_DET_M \ + 0x00200000 +#define SYS_CTRL_CLOCK_CTRL_AMP_DET_S 21 +#define SYS_CTRL_CLOCK_CTRL_OSC_PD \ + 0x00020000 // 0: Power up both oscillators 1: + // Power down oscillator not + // selected by OSC bit + // (hardware-controlled when + // selected). + +#define SYS_CTRL_CLOCK_CTRL_OSC_PD_M \ + 0x00020000 +#define SYS_CTRL_CLOCK_CTRL_OSC_PD_S 17 +#define SYS_CTRL_CLOCK_CTRL_OSC 0x00010000 // System clock oscillator + // selection 0: 32-MHz crystal + // oscillator 1: 16-MHz HF-RC + // oscillator +#define SYS_CTRL_CLOCK_CTRL_OSC_M \ + 0x00010000 +#define SYS_CTRL_CLOCK_CTRL_OSC_S 16 +#define SYS_CTRL_CLOCK_CTRL_IO_DIV_M \ + 0x00000700 // I/O clock rate setting Cannot + // be higher than OSC setting 000: + // 32 MHz 001: 16 MHz 010: 8 MHz + // 011: 4 MHz 100: 2 MHz 101: 1 MHz + // 110: 0.5 MHz 111: 0.25 MHz + +#define SYS_CTRL_CLOCK_CTRL_IO_DIV_S 8 +#define SYS_CTRL_CLOCK_CTRL_SYS_DIV_M \ + 0x00000007 // System clock rate setting + // Cannot be higher than OSC + // setting 000: 32 MHz 001: 16 MHz + // 010: 8 MHz 011: 4 MHz 100: 2 MHz + // 101: 1 MHz 110: 0.5 MHz 111: + // 0.25 MHz + +#define SYS_CTRL_CLOCK_CTRL_SYS_DIV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_CLOCK_STA register. +// +//***************************************************************************** +#define SYS_CTRL_CLOCK_STA_SYNC_32K \ + 0x04000000 // 32-kHz clock source synced to + // undivided system clock (16 or 32 + // MHz). + +#define SYS_CTRL_CLOCK_STA_SYNC_32K_M \ + 0x04000000 +#define SYS_CTRL_CLOCK_STA_SYNC_32K_S 26 +#define SYS_CTRL_CLOCK_STA_OSC32K_CALDIS \ + 0x02000000 // Disable calibration 32-kHz RC + // oscillator. 0: Calibration + // enabled 1: Calibration disabled + +#define SYS_CTRL_CLOCK_STA_OSC32K_CALDIS_M \ + 0x02000000 +#define SYS_CTRL_CLOCK_STA_OSC32K_CALDIS_S 25 +#define SYS_CTRL_CLOCK_STA_OSC32K \ + 0x01000000 // Current 32-kHz clock oscillator + // selected. 0: 32-kHz crystal + // oscillator 1: 32-kHz RC + // oscillator + +#define SYS_CTRL_CLOCK_STA_OSC32K_M \ + 0x01000000 +#define SYS_CTRL_CLOCK_STA_OSC32K_S 24 +#define SYS_CTRL_CLOCK_STA_RST_M \ + 0x00C00000 // Returns last source of reset + // 00: POR 01: External reset 10: + // WDT 11: CLD or software reset + +#define SYS_CTRL_CLOCK_STA_RST_S 22 +#define SYS_CTRL_CLOCK_STA_SOURCE_CHANGE \ + 0x00100000 // 0: System clock is not + // requested to change. 1: A change + // of system clock source has been + // initiated and is not finished. + // Same as when OSC bit in + // CLOCK_STA and CLOCK_CTRL + // register are not equal + +#define SYS_CTRL_CLOCK_STA_SOURCE_CHANGE_M \ + 0x00100000 +#define SYS_CTRL_CLOCK_STA_SOURCE_CHANGE_S 20 +#define SYS_CTRL_CLOCK_STA_XOSC_STB \ + 0x00080000 // XOSC stable status 0: XOSC is + // not powered up or not yet + // stable. 1: XOSC is powered up + // and stable. + +#define SYS_CTRL_CLOCK_STA_XOSC_STB_M \ + 0x00080000 +#define SYS_CTRL_CLOCK_STA_XOSC_STB_S 19 +#define SYS_CTRL_CLOCK_STA_HSOSC_STB \ + 0x00040000 // HSOSC stable status 0: HSOSC is + // not powered up or not yet + // stable. 1: HSOSC is powered up + // and stable. + +#define SYS_CTRL_CLOCK_STA_HSOSC_STB_M \ + 0x00040000 +#define SYS_CTRL_CLOCK_STA_HSOSC_STB_S 18 +#define SYS_CTRL_CLOCK_STA_OSC_PD \ + 0x00020000 // 0: Both oscillators powered up + // and stable and OSC_PD_CMD = 0. + // 1: Oscillator not selected by + // CLOCK_CTRL.OSC bit is powered + // down. + +#define SYS_CTRL_CLOCK_STA_OSC_PD_M \ + 0x00020000 +#define SYS_CTRL_CLOCK_STA_OSC_PD_S 17 +#define SYS_CTRL_CLOCK_STA_OSC 0x00010000 // Current clock source selected + // 0: 32-MHz crystal oscillator 1: + // 16-MHz HF-RC oscillator +#define SYS_CTRL_CLOCK_STA_OSC_M \ + 0x00010000 +#define SYS_CTRL_CLOCK_STA_OSC_S 16 +#define SYS_CTRL_CLOCK_STA_IO_DIV_M \ + 0x00000700 // Returns current functional + // frequency for IO_CLK (may differ + // from setting in the CLOCK_CTRL + // register) 000: 32 MHz 001: 16 + // MHz 010: 8 MHz 011: 4 MHz 100: 2 + // MHz 101: 1 MHz 110: 0.5 MHz 111: + // 0.25 MHz + +#define SYS_CTRL_CLOCK_STA_IO_DIV_S 8 +#define SYS_CTRL_CLOCK_STA_RTCLK_FREQ_M \ + 0x00000018 // Returns current functional + // frequency for real-time clock. + // (may differ from setting in the + // CLOCK_CTRL register) 1x : 8 MHz + // 01: 2 MHz 00: 62.5 kHz + +#define SYS_CTRL_CLOCK_STA_RTCLK_FREQ_S 3 +#define SYS_CTRL_CLOCK_STA_SYS_DIV_M \ + 0x00000007 // Returns current functional + // frequency for system clock (may + // differ from setting in the + // CLOCK_CTRL register) 000: 32 MHz + // 001: 16 MHz 010: 8 MHz 011: 4 + // MHz 100: 2 MHz 101: 1 MHz 110: + // 0.5 MHz 111: 0.25 MHz + +#define SYS_CTRL_CLOCK_STA_SYS_DIV_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_RCGCGPT register. +// +//***************************************************************************** +#define SYS_CTRL_RCGCGPT_GPT3 0x00000008 // 0: Clock for GPT3 is gated. 1: + // Clock for GPT3 is enabled. +#define SYS_CTRL_RCGCGPT_GPT3_M 0x00000008 +#define SYS_CTRL_RCGCGPT_GPT3_S 3 +#define SYS_CTRL_RCGCGPT_GPT2 0x00000004 // 0: Clock for GPT2 is gated. 1: + // Clock for GPT2 is enabled. +#define SYS_CTRL_RCGCGPT_GPT2_M 0x00000004 +#define SYS_CTRL_RCGCGPT_GPT2_S 2 +#define SYS_CTRL_RCGCGPT_GPT1 0x00000002 // 0: Clock for GPT1 is gated. 1: + // Clock for GPT1 is enabled. +#define SYS_CTRL_RCGCGPT_GPT1_M 0x00000002 +#define SYS_CTRL_RCGCGPT_GPT1_S 1 +#define SYS_CTRL_RCGCGPT_GPT0 0x00000001 // 0: Clock for GPT0 is gated. 1: + // Clock for GPT0 is enabled. +#define SYS_CTRL_RCGCGPT_GPT0_M 0x00000001 +#define SYS_CTRL_RCGCGPT_GPT0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SCGCGPT register. +// +//***************************************************************************** +#define SYS_CTRL_SCGCGPT_GPT3 0x00000008 // 0: Clock for GPT3 is gated. 1: + // Clock for GPT3 is enabled. +#define SYS_CTRL_SCGCGPT_GPT3_M 0x00000008 +#define SYS_CTRL_SCGCGPT_GPT3_S 3 +#define SYS_CTRL_SCGCGPT_GPT2 0x00000004 // 0: Clock for GPT2 is gated. 1: + // Clock for GPT2 is enabled. +#define SYS_CTRL_SCGCGPT_GPT2_M 0x00000004 +#define SYS_CTRL_SCGCGPT_GPT2_S 2 +#define SYS_CTRL_SCGCGPT_GPT1 0x00000002 // 0: Clock for GPT1 is gated. 1: + // Clock for GPT1 is enabled. +#define SYS_CTRL_SCGCGPT_GPT1_M 0x00000002 +#define SYS_CTRL_SCGCGPT_GPT1_S 1 +#define SYS_CTRL_SCGCGPT_GPT0 0x00000001 // 0: Clock for GPT0 is gated. 1: + // Clock for GPT0 is enabled. +#define SYS_CTRL_SCGCGPT_GPT0_M 0x00000001 +#define SYS_CTRL_SCGCGPT_GPT0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_DCGCGPT register. +// +//***************************************************************************** +#define SYS_CTRL_DCGCGPT_GPT3 0x00000008 // 0: Clock for GPT3 is gated. 1: + // Clock for GPT3 is enabled. +#define SYS_CTRL_DCGCGPT_GPT3_M 0x00000008 +#define SYS_CTRL_DCGCGPT_GPT3_S 3 +#define SYS_CTRL_DCGCGPT_GPT2 0x00000004 // 0: Clock for GPT2 is gated. 1: + // Clock for GPT2 is enabled. +#define SYS_CTRL_DCGCGPT_GPT2_M 0x00000004 +#define SYS_CTRL_DCGCGPT_GPT2_S 2 +#define SYS_CTRL_DCGCGPT_GPT1 0x00000002 // 0: Clock for GPT1 is gated. 1: + // Clock for GPT1 is enabled. +#define SYS_CTRL_DCGCGPT_GPT1_M 0x00000002 +#define SYS_CTRL_DCGCGPT_GPT1_S 1 +#define SYS_CTRL_DCGCGPT_GPT0 0x00000001 // 0: Clock for GPT0 is gated. 1: + // Clock for GPT0 is enabled. +#define SYS_CTRL_DCGCGPT_GPT0_M 0x00000001 +#define SYS_CTRL_DCGCGPT_GPT0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SRGPT register. +// +//***************************************************************************** +#define SYS_CTRL_SRGPT_GPT3 0x00000008 // 0: GPT3 module is not reset 1: + // GPT3 module is reset +#define SYS_CTRL_SRGPT_GPT3_M 0x00000008 +#define SYS_CTRL_SRGPT_GPT3_S 3 +#define SYS_CTRL_SRGPT_GPT2 0x00000004 // 0: GPT2 module is not reset 1: + // GPT2 module is reset +#define SYS_CTRL_SRGPT_GPT2_M 0x00000004 +#define SYS_CTRL_SRGPT_GPT2_S 2 +#define SYS_CTRL_SRGPT_GPT1 0x00000002 // 0: GPT1 module is not reset 1: + // GPT1 module is reset +#define SYS_CTRL_SRGPT_GPT1_M 0x00000002 +#define SYS_CTRL_SRGPT_GPT1_S 1 +#define SYS_CTRL_SRGPT_GPT0 0x00000001 // 0: GPT0 module is not reset 1: + // GPT0 module is reset +#define SYS_CTRL_SRGPT_GPT0_M 0x00000001 +#define SYS_CTRL_SRGPT_GPT0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_RCGCSSI register. +// +//***************************************************************************** +#define SYS_CTRL_RCGCSSI_SSI1 0x00000002 // 0: Clock for SSI1 is gated. 1: + // Clock for SSI1 is enabled. +#define SYS_CTRL_RCGCSSI_SSI1_M 0x00000002 +#define SYS_CTRL_RCGCSSI_SSI1_S 1 +#define SYS_CTRL_RCGCSSI_SSI0 0x00000001 // 0: Clock for SSI0 is gated. 1: + // Clock for SSI0 is enabled. +#define SYS_CTRL_RCGCSSI_SSI0_M 0x00000001 +#define SYS_CTRL_RCGCSSI_SSI0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SCGCSSI register. +// +//***************************************************************************** +#define SYS_CTRL_SCGCSSI_SSI1 0x00000002 // 0: Clock for SSI1 is gated. 1: + // Clock for SSI1 is enabled. +#define SYS_CTRL_SCGCSSI_SSI1_M 0x00000002 +#define SYS_CTRL_SCGCSSI_SSI1_S 1 +#define SYS_CTRL_SCGCSSI_SSI0 0x00000001 // 0: Clock for SSI0 is gated. 1: + // Clock for SSI0 is enabled. +#define SYS_CTRL_SCGCSSI_SSI0_M 0x00000001 +#define SYS_CTRL_SCGCSSI_SSI0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_DCGCSSI register. +// +//***************************************************************************** +#define SYS_CTRL_DCGCSSI_SSI1 0x00000002 // 0: Clock for SSI1 is gated. 1: + // Clock for SSI1 is enabled. +#define SYS_CTRL_DCGCSSI_SSI1_M 0x00000002 +#define SYS_CTRL_DCGCSSI_SSI1_S 1 +#define SYS_CTRL_DCGCSSI_SSI0 0x00000001 // 0: Clock for SSI0 is gated. 1: + // Clock for SSI0 is enabled. +#define SYS_CTRL_DCGCSSI_SSI0_M 0x00000001 +#define SYS_CTRL_DCGCSSI_SSI0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SRSSI register. +// +//***************************************************************************** +#define SYS_CTRL_SRSSI_SSI1 0x00000002 // 0: SSI1 module is not reset 1: + // SSI1 module is reset +#define SYS_CTRL_SRSSI_SSI1_M 0x00000002 +#define SYS_CTRL_SRSSI_SSI1_S 1 +#define SYS_CTRL_SRSSI_SSI0 0x00000001 // 0: SSI0 module is not reset 1: + // SSI0 module is reset +#define SYS_CTRL_SRSSI_SSI0_M 0x00000001 +#define SYS_CTRL_SRSSI_SSI0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_RCGCUART register. +// +//***************************************************************************** +#define SYS_CTRL_RCGCUART_UART1 0x00000002 // 0: Clock for UART1 is gated. 1: + // Clock for UART1 is enabled. +#define SYS_CTRL_RCGCUART_UART1_M \ + 0x00000002 +#define SYS_CTRL_RCGCUART_UART1_S 1 +#define SYS_CTRL_RCGCUART_UART0 0x00000001 // 0: Clock for UART0 is gated. 1: + // Clock for UART0 is enabled. +#define SYS_CTRL_RCGCUART_UART0_M \ + 0x00000001 +#define SYS_CTRL_RCGCUART_UART0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SCGCUART register. +// +//***************************************************************************** +#define SYS_CTRL_SCGCUART_UART1 0x00000002 // 0: Clock for UART1 is gated. 1: + // Clock for UART1 is enabled. +#define SYS_CTRL_SCGCUART_UART1_M \ + 0x00000002 +#define SYS_CTRL_SCGCUART_UART1_S 1 +#define SYS_CTRL_SCGCUART_UART0 0x00000001 // 0: Clock for UART0 is gated. 1: + // Clock for UART0 is enabled. +#define SYS_CTRL_SCGCUART_UART0_M \ + 0x00000001 +#define SYS_CTRL_SCGCUART_UART0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_DCGCUART register. +// +//***************************************************************************** +#define SYS_CTRL_DCGCUART_UART1 0x00000002 // 0: Clock for UART1 is gated. 1: + // Clock for UART1 is enabled. +#define SYS_CTRL_DCGCUART_UART1_M \ + 0x00000002 +#define SYS_CTRL_DCGCUART_UART1_S 1 +#define SYS_CTRL_DCGCUART_UART0 0x00000001 // 0: Clock for UART0 is gated. 1: + // Clock for UART0 is enabled. +#define SYS_CTRL_DCGCUART_UART0_M \ + 0x00000001 +#define SYS_CTRL_DCGCUART_UART0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SRUART register. +// +//***************************************************************************** +#define SYS_CTRL_SRUART_UART1 0x00000002 // 0: UART1 module is not reset 1: + // UART1 module is reset +#define SYS_CTRL_SRUART_UART1_M 0x00000002 +#define SYS_CTRL_SRUART_UART1_S 1 +#define SYS_CTRL_SRUART_UART0 0x00000001 // 0: UART0 module is not reset 1: + // UART0 module is reset +#define SYS_CTRL_SRUART_UART0_M 0x00000001 +#define SYS_CTRL_SRUART_UART0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_RCGCI2C register. +// +//***************************************************************************** +#define SYS_CTRL_RCGCI2C_I2C0 0x00000001 // 0: Clock for I2C0 is gated. 1: + // Clock for I2C0 is enabled. +#define SYS_CTRL_RCGCI2C_I2C0_M 0x00000001 +#define SYS_CTRL_RCGCI2C_I2C0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SCGCI2C register. +// +//***************************************************************************** +#define SYS_CTRL_SCGCI2C_I2C0 0x00000001 // 0: Clock for I2C0 is gated. 1: + // Clock for I2C0 is enabled. +#define SYS_CTRL_SCGCI2C_I2C0_M 0x00000001 +#define SYS_CTRL_SCGCI2C_I2C0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_DCGCI2C register. +// +//***************************************************************************** +#define SYS_CTRL_DCGCI2C_I2C0 0x00000001 // 0: Clock for I2C0 is gated. 1: + // Clock for I2C0 is enabled. +#define SYS_CTRL_DCGCI2C_I2C0_M 0x00000001 +#define SYS_CTRL_DCGCI2C_I2C0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SRI2C register. +// +//***************************************************************************** +#define SYS_CTRL_SRI2C_I2C0 0x00000001 // 0: I2C0 module is not reset 1: + // I2C0 module is reset +#define SYS_CTRL_SRI2C_I2C0_M 0x00000001 +#define SYS_CTRL_SRI2C_I2C0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_RCGCSEC register. +// +//***************************************************************************** +#define SYS_CTRL_RCGCSEC_AES 0x00000002 // 0: Clock for AES is gated. 1: + // Clock for AES is enabled. +#define SYS_CTRL_RCGCSEC_AES_M 0x00000002 +#define SYS_CTRL_RCGCSEC_AES_S 1 +#define SYS_CTRL_RCGCSEC_PKA 0x00000001 // 0: Clock for PKA is gated. 1: + // Clock for PKA is enabled. +#define SYS_CTRL_RCGCSEC_PKA_M 0x00000001 +#define SYS_CTRL_RCGCSEC_PKA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SCGCSEC register. +// +//***************************************************************************** +#define SYS_CTRL_SCGCSEC_AES 0x00000002 // 0: Clock for AES is gated. 1: + // Clock for AES is enabled. +#define SYS_CTRL_SCGCSEC_AES_M 0x00000002 +#define SYS_CTRL_SCGCSEC_AES_S 1 +#define SYS_CTRL_SCGCSEC_PKA 0x00000001 // 0: Clock for PKA is gated. 1: + // Clock for PKA is enabled. +#define SYS_CTRL_SCGCSEC_PKA_M 0x00000001 +#define SYS_CTRL_SCGCSEC_PKA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_DCGCSEC register. +// +//***************************************************************************** +#define SYS_CTRL_DCGCSEC_AES 0x00000002 // 0: Clock for AES is gated. 1: + // Clock for AES is enabled. +#define SYS_CTRL_DCGCSEC_AES_M 0x00000002 +#define SYS_CTRL_DCGCSEC_AES_S 1 +#define SYS_CTRL_DCGCSEC_PKA 0x00000001 // 0: Clock for PKA is gated. 1: + // Clock for PKA is enabled. +#define SYS_CTRL_DCGCSEC_PKA_M 0x00000001 +#define SYS_CTRL_DCGCSEC_PKA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SRSEC register. +// +//***************************************************************************** +#define SYS_CTRL_SRSEC_AES 0x00000002 // 0: AES module is not reset 1: + // AES module is reset +#define SYS_CTRL_SRSEC_AES_M 0x00000002 +#define SYS_CTRL_SRSEC_AES_S 1 +#define SYS_CTRL_SRSEC_PKA 0x00000001 // 0: PKA module is not reset 1: + // PKA module is reset +#define SYS_CTRL_SRSEC_PKA_M 0x00000001 +#define SYS_CTRL_SRSEC_PKA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_PMCTL register. +// +//***************************************************************************** +#define SYS_CTRL_PMCTL_PM_M 0x00000003 // 00: No action 01: PM1 10: PM2 + // 11: PM3 +#define SYS_CTRL_PMCTL_PM_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SRCRC register. +// +//***************************************************************************** +#define SYS_CTRL_SRCRC_CRC_REN_USB \ + 0x00000100 // 1: Enable reset of chip if CRC + // fails. 0: Disable reset feature + // of chip due to CRC. + +#define SYS_CTRL_SRCRC_CRC_REN_USB_M \ + 0x00000100 +#define SYS_CTRL_SRCRC_CRC_REN_USB_S 8 +#define SYS_CTRL_SRCRC_CRC_REN_RF \ + 0x00000001 // 1: Enable reset of chip if CRC + // fails. 0: Disable reset feature + // of chip due to CRC. + +#define SYS_CTRL_SRCRC_CRC_REN_RF_M \ + 0x00000001 +#define SYS_CTRL_SRCRC_CRC_REN_RF_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_PWRDBG register. +// +//***************************************************************************** +#define SYS_CTRL_PWRDBG_FORCE_WARM_RESET \ + 0x00000008 // 0: No action 1: When written + // high, the chip is reset in the + // same manner as a CLD event and + // is readable from the RST field + // in the CLOCK_STA register. + +#define SYS_CTRL_PWRDBG_FORCE_WARM_RESET_M \ + 0x00000008 +#define SYS_CTRL_PWRDBG_FORCE_WARM_RESET_S 3 +//***************************************************************************** +// +// The following are defines for the bit fields in the SYS_CTRL_CLD register. +// +//***************************************************************************** +#define SYS_CTRL_CLD_VALID 0x00000100 // 0: CLD status in always-on + // domain is not equal to status in + // the EN register. 1: CLD status + // in always-on domain and EN + // register are equal. +#define SYS_CTRL_CLD_VALID_M 0x00000100 +#define SYS_CTRL_CLD_VALID_S 8 +#define SYS_CTRL_CLD_EN 0x00000001 // 0: CLD is disabled. 1: CLD is + // enabled. Writing to this + // register shall be ignored if + // VALID = 0 +#define SYS_CTRL_CLD_EN_M 0x00000001 +#define SYS_CTRL_CLD_EN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the SYS_CTRL_IWE register. +// +//***************************************************************************** +#define SYS_CTRL_IWE_SM_TIMER_IWE \ + 0x00000020 // 1: Enable SM Timer wake-up + // interrupt. 0: Disable SM Timer + // wake-up interrupt. + +#define SYS_CTRL_IWE_SM_TIMER_IWE_M \ + 0x00000020 +#define SYS_CTRL_IWE_SM_TIMER_IWE_S 5 +#define SYS_CTRL_IWE_USB_IWE 0x00000010 // 1: Enable USB wake-up + // interrupt. 0: Disable USB + // wake-up interrupt. +#define SYS_CTRL_IWE_USB_IWE_M 0x00000010 +#define SYS_CTRL_IWE_USB_IWE_S 4 +#define SYS_CTRL_IWE_PORT_D_IWE 0x00000008 // 1: Enable port D wake-up + // interrupt. 0: Disable port D + // wake-up interrupt. +#define SYS_CTRL_IWE_PORT_D_IWE_M \ + 0x00000008 +#define SYS_CTRL_IWE_PORT_D_IWE_S 3 +#define SYS_CTRL_IWE_PORT_C_IWE 0x00000004 // 1: Enable port C wake-up + // interrupt. 0: Disable port C + // wake-up interrupt. +#define SYS_CTRL_IWE_PORT_C_IWE_M \ + 0x00000004 +#define SYS_CTRL_IWE_PORT_C_IWE_S 2 +#define SYS_CTRL_IWE_PORT_B_IWE 0x00000002 // 1: Enable port B wake-up + // interrupt. 0: Disable port B + // wake-up interrupt. +#define SYS_CTRL_IWE_PORT_B_IWE_M \ + 0x00000002 +#define SYS_CTRL_IWE_PORT_B_IWE_S 1 +#define SYS_CTRL_IWE_PORT_A_IWE 0x00000001 // 1: Enable port A wake-up + // interrupt. 0: Disable port A + // wake-up interrupt. +#define SYS_CTRL_IWE_PORT_A_IWE_M \ + 0x00000001 +#define SYS_CTRL_IWE_PORT_A_IWE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_I_MAP register. +// +//***************************************************************************** +#define SYS_CTRL_I_MAP_ALTMAP 0x00000001 // 1: Select alternate interrupt + // map. 0: Select regular interrupt + // map. (See the ASD document for + // details.) +#define SYS_CTRL_I_MAP_ALTMAP_M 0x00000001 +#define SYS_CTRL_I_MAP_ALTMAP_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_RCGCRFC register. +// +//***************************************************************************** +#define SYS_CTRL_RCGCRFC_RFC0 0x00000001 // 0: Clock for RF CORE is gated. + // 1: Clock for RF CORE is enabled. +#define SYS_CTRL_RCGCRFC_RFC0_M 0x00000001 +#define SYS_CTRL_RCGCRFC_RFC0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_SCGCRFC register. +// +//***************************************************************************** +#define SYS_CTRL_SCGCRFC_RFC0 0x00000001 // 0: Clock for RF CORE is gated. + // 1: Clock for RF CORE is enabled. +#define SYS_CTRL_SCGCRFC_RFC0_M 0x00000001 +#define SYS_CTRL_SCGCRFC_RFC0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_DCGCRFC register. +// +//***************************************************************************** +#define SYS_CTRL_DCGCRFC_RFC0 0x00000001 // 0: Clock for RF CORE is gated. + // 1: Clock for RF CORE is enabled. +#define SYS_CTRL_DCGCRFC_RFC0_M 0x00000001 +#define SYS_CTRL_DCGCRFC_RFC0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// SYS_CTRL_EMUOVR register. +// +//***************************************************************************** +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_CLOCK_CG \ + 0x00000080 // ICEPick 'Force Active' clock + // gate override bit. 'Force + // Active' is an ICEPick command. 1 + // --> In non-sleep power mode, + // peripherals clocks are forced to + // follow RCG* register settings. + // It forces CM3 clocks on. 0 --> + // Does not affect the peripheral + // clock settings. + +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_CLOCK_CG_M \ + 0x00000080 +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_CLOCK_CG_S 7 +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_POWER_CG \ + 0x00000040 // ICEPick 'Force Power' clock + // gate override bit. 'Force Power' + // is an ICEPick command. 1 --> In + // non-sleep power mode, + // peripherals clocks are forced to + // follow RCG* register settings. + // It forces CM3 clocks on. 0 --> + // Does not affect the peripheral + // clock settings. + +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_POWER_CG_M \ + 0x00000040 +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_POWER_CG_S 6 +#define SYS_CTRL_EMUOVR_ICEPICK_INHIBIT_SLEEP_CG \ + 0x00000020 // ICEPick 'Inhibit Sleep' clock + // gate override bit. 'Inhibit + // Sleep' is an ICEPick command. 1 + // --> In non-sleep power mode, + // peripherals clocks are forced to + // follow RCG* register settings. + // It forces CM3 clocks on. 0 --> + // Does not affect the peripheral + // clock settings. + +#define SYS_CTRL_EMUOVR_ICEPICK_INHIBIT_SLEEP_CG_M \ + 0x00000020 +#define SYS_CTRL_EMUOVR_ICEPICK_INHIBIT_SLEEP_CG_S 5 +#define SYS_CTRL_EMUOVR_ICEMELTER_WKUP_CG \ + 0x00000010 // ICEMelter 'WAKEUPEMU' clock + // gate override bit. 1 --> In + // non-sleep power mode, + // peripherals clocks are forced to + // follow RCG* register settings. + // It forces CM3 clocks on. 0 --> + // Does not affect the peripheral + // clock settings + +#define SYS_CTRL_EMUOVR_ICEMELTER_WKUP_CG_M \ + 0x00000010 +#define SYS_CTRL_EMUOVR_ICEMELTER_WKUP_CG_S 4 +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_CLOCK_PM \ + 0x00000008 // ICEPick 'Force Active' power + // mode override bit. 'Force + // Active' is an ICEPick command. 1 + // --> Prohibit the system to go + // into any power down modes. Keeps + // the emulator attached. 0 --> + // Does not override any power mode + // settings from SYSREGS and does + // not prohibit system to go into + // any power down modes. + +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_CLOCK_PM_M \ + 0x00000008 +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_CLOCK_PM_S 3 +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_POWER_PM \ + 0x00000004 // ICEPick 'Force Power' power + // mode override bit. 'Force Power' + // is an ICEPick command. 1 --> + // Prohibit the system to go into + // any power down modes. Keeps the + // emulator attached. 0 --> Does + // not override any power mode + // settings from SYSREGS and does + // not prohibit system to go into + // any power down modes. + +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_POWER_PM_M \ + 0x00000004 +#define SYS_CTRL_EMUOVR_ICEPICK_FORCE_POWER_PM_S 2 +#define SYS_CTRL_EMUOVR_ICEPICK_INHIBIT_SLEEP_PM \ + 0x00000002 // ICEPick 'Inhibit Sleep' power + // mode override bit. 'Inhibit + // Sleep' is an ICEPick command. 1 + // --> Prohibit the system to go + // into any power down modes. Keeps + // the emulator attached. 0 --> + // Does not override any power mode + // settings from SYSREGS and does + // not prohibit system to go into + // any power down modes. + +#define SYS_CTRL_EMUOVR_ICEPICK_INHIBIT_SLEEP_PM_M \ + 0x00000002 +#define SYS_CTRL_EMUOVR_ICEPICK_INHIBIT_SLEEP_PM_S 1 +#define SYS_CTRL_EMUOVR_ICEMELTER_WKUP_PM \ + 0x00000001 // ICEMelter 'WAKEUPEMU' power + // mode override bit. 1 --> + // Prohibit the system to go into + // any power down modes. Keeps the + // emulator attached. 0 --> Does + // not override any power mode + // settings from SYSREGS and does + // not prohibit system to go into + // any power down modes. + +#define SYS_CTRL_EMUOVR_ICEMELTER_WKUP_PM_M \ + 0x00000001 +#define SYS_CTRL_EMUOVR_ICEMELTER_WKUP_PM_S 0 + + +#endif // __HW_SYS_CTRL_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_types.h b/bsp/boards/mimsy2-cc2538/headers/hw_types.h new file mode 100644 index 0000000000..af19fa2aec --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_types.h @@ -0,0 +1,84 @@ +/****************************************************************************** +* Filename: hw_types.h +* Revised: $Date: 2013-04-29 09:49:55 +0200 (Mon, 29 Apr 2013) $ +* Revision: $Revision: 9923 $ +* +* Description: Common types and macros. +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + + +#ifndef __HW_TYPES_H__ +#define __HW_TYPES_H__ + +#include +#include + +//***************************************************************************** +// +// Define a boolean type, and values for true and false. +// +//***************************************************************************** +typedef unsigned char tBoolean; + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +//***************************************************************************** +// +// Macros for hardware access, both direct and via the bit-band region. +// +//***************************************************************************** +#define HWREG(x) \ + (*((volatile uint32_t *)(x))) +#define HWREGH(x) \ + (*((volatile uint16_t *)(x))) +#define HWREGB(x) \ + (*((volatile unsigned char *)(x))) +#define HWREGBITW(x, b) \ + HWREG(((uint32_t)(x) & 0xF0000000) | 0x02000000 | \ + (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2)) +#define HWREGBITH(x, b) \ + HWREGH(((uint32_t)(x) & 0xF0000000) | 0x02000000 | \ + (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2)) +#define HWREGBITB(x, b) \ + HWREGB(((uint32_t)(x) & 0xF0000000) | 0x02000000 | \ + (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2)) + + +#endif // __HW_TYPES_H__ diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_uart.h b/bsp/boards/mimsy2-cc2538/headers/hw_uart.h new file mode 100644 index 0000000000..e39b84e39b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_uart.h @@ -0,0 +1,1361 @@ +/****************************************************************************** +* Filename: hw_uart.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_UART_H__ +#define __HW_UART_H__ + +//***************************************************************************** +// +// The following are defines for the UART register offsets. +// +//***************************************************************************** +#define UART_O_DR 0x00000000 // UART data Important: This + // register is read-sensitive. See + // the register description for + // details. This register is the + // data register (the interface to + // the FIFOs). For transmitted + // data, if the FIFO is enabled, + // data written to this location is + // pushed onto the transmit FIFO. + // If the FIFO is disabled, data is + // stored in the transmitter + // holding register (the bottom + // word of the transmit FIFO). A + // write to this register initiates + // a transmission from the UART. + // For received data, if the FIFO + // is enabled, the data byte and + // the 4-bit status (break, frame, + // parity, and overrun) is pushed + // onto the 12-bit wide receive + // FIFO. If the FIFO is disabled, + // the data byte and status are + // stored in the receiving holding + // register (the bottom word of the + // receive FIFO). The received data + // can be retrieved by reading this + // register. +#define UART_O_RSR 0x00000004 // UART receive status and error + // clear The RSR/ECR register is + // the receive status register and + // error clear register. In + // addition to the DR register, + // receive status can also be read + // from the RSR register. If the + // status is read from this + // register, then the status + // information corresponds to the + // entry read from DR before + // reading RSR. The status + // information for overrun is set + // immediately when an overrun + // condition occurs. The RSR + // register cannot be written. + // Read-only status register +#define UART_O_ECR 0x00000004 // UART receive status and error + // clear The RSR/ECR register is + // the receive status + // register/error clear register. A + // write of any value to the ECR + // register clears the framing, + // parity, break, and overrun + // errors. All the bits are cleared + // on reset. Write-only error clear + // register +#define UART_O_FR 0x00000018 // UART flag The FR register is + // the flag register. After reset, + // the TXFF, RXFF, and BUSY bits + // are 0, and TXFE and RXFE bits + // are 1. The CTS bit indicate the + // modem flow control. Note that + // the modem bits are only + // implemented on UART1 and are + // tied inactive on UART0. Due to + // this difference, the reset state + // of the UART0 FR register is + // 0x90, while UART1 FR register + // reset state 0x197 . +#define UART_O_ILPR 0x00000020 // UART IrDA low-power register + // The ILPR register stores the + // 8-bit low-power counter divisor + // value used to derive the + // low-power SIR pulse width clock + // by dividing down the system + // clock (SysClk). All the bits are + // cleared when reset. The internal + // IrLPBaud16 clock is generated by + // dividing down SysClk according + // to the low-power divisor value + // written to ILPR. The duration of + // SIR pulses generated when + // low-power mode is enabled is + // three times the period of the + // IrLPBaud16 clock. The low-power + // divisor value is calculated as + // follows: ILPDVSR = SysClk / + // FIrLPBaud16 where FIrLPBaud16 is + // nominally 1.8432 MHz The divisor + // must be programmed such that + // FIrLPBaud16 is in the range 1.42 + // MHz to 2.12 MHz, resulting in a + // low-power pulse duration of + // 1.41-2.11 us (three times the + // period of IrLPBaud16). The + // minimum frequency of IrLPBaud16 + // ensures that pulses less than + // one period of IrLPBaud16 are + // rejected, but pulses greater + // than 1.4 us are accepted as + // valid pulses. Note: Zero is an + // illegal value. Programming a + // zero value results in no + // IrLPBaud16 pulses being + // generated. +#define UART_O_IBRD 0x00000024 // UART integer baud-rate divisor + // The IBRD register is the integer + // part of the baud-rate divisor + // value. All the bits are cleared + // on reset. The minimum possible + // divide ratio is 1 (when IBRD = + // 0), in which case the FBRD + // register is ignored. When + // changing the IBRD register, the + // new value does not take effect + // until transmission or reception + // of the current character is + // complete. Any changes to the + // baud-rate divisor must be + // followed by a write to the LCRH + // register. +#define UART_O_FBRD 0x00000028 // UART fractional baud-rate + // divisor The FBRD register is the + // fractional part of the baud-rate + // divisor value. All the bits are + // cleared on reset. When changing + // the FBRD register, the new value + // does not take effect until + // transmission or reception of the + // current character is complete. + // Any changes to the baud-rate + // divisor must be followed by a + // write to the LCRH register. +#define UART_O_LCRH 0x0000002C // UART line control The LCRH + // register is the line control + // register. Serial parameters such + // as data length, parity, and stop + // bit selection are implemented in + // this register. When updating the + // baud-rate divisor (IBRD and/or + // IFRD), the LCRH register must + // also be written. The write + // strobe for the baud-rate divisor + // registers is tied to the LCRH + // register. +#define UART_O_CTL 0x00000030 // UART control The CTL register + // is the control register. All the + // bits are cleared on reset except + // for the transmit enable (TXE) + // and receive enable (RXE) bits, + // which are set. To enable the + // UART module, the UARTEN bit must + // be set. If software requires a + // configuration change in the + // module, the UARTEN bit must be + // cleared before the configuration + // changes are written. If the UART + // is disabled during a transmit or + // receive operation, the current + // transaction is completed before + // the UART stopping. Note: The + // UARTCTL register should not be + // changed while the UART is + // enabled or else the results are + // unpredictable. The following + // sequence is recommended for + // making changes to the UARTCTL + // register: 1. Disable the UART. + // 2. Wait for the end of + // transmission or reception of the + // current character. 3. Flush the + // transmit FIFO by clearing bit 4 + // (FEN) in the line control + // register (UARTLCRH). 4. + // Reprogram the control register. + // 5. Enable the UART. +#define UART_O_IFLS 0x00000034 // UART interrupt FIFO level + // select The IFLS register is the + // interrupt FIFO level select + // register. This register can be + // used to define the FIFO level at + // which the TXRIS and RXRIS bits + // in the RIS register are + // triggered. The interrupts are + // generated based on a transition + // through a level rather than + // being based on the level. That + // is, the interrupts are generated + // when the fill level progresses + // through the trigger level. For + // example, if the receive trigger + // level is set to the half-way + // mark, the interrupt is triggered + // as the module is receiving the + // 9th character. Out of reset, the + // TXIFLSEL and RXIFLSEL bits are + // configured so that the FIFOs + // trigger an interrupt at the + // half-way mark. +#define UART_O_IM 0x00000038 // UART interrupt mask The IM + // register is the interrupt mask + // set/clear register. On a read, + // this register gives the current + // value of the mask on the + // relevant interrupt. Setting a + // bit allows the corresponding raw + // interrupt signal to be routed to + // the interrupt controller. + // Clearing a bit prevents the raw + // interrupt signal from being sent + // to the interrupt controller. +#define UART_O_RIS 0x0000003C // UART raw interrupt status The + // RIS register is the raw + // interrupt status register. On a + // read, this register gives the + // current raw status value of the + // corresponding interrupt. A write + // has no effect. Note that the HW + // modem flow control bits are only + // implemented on UART1 and are + // tied inactive on UART0. +#define UART_O_MIS 0x00000040 // UART masked interrupt status + // The MIS register is the masked + // interrupt status register. On a + // read, this register gives the + // current masked status value of + // the corresponding interrupt. A + // write has no effect. +#define UART_O_ICR 0x00000044 // UART interrupt clear The ICR + // register is the interrupt clear + // register. On a write of 1, the + // corresponding interrupt (both + // raw interrupt and masked + // interrupt, if enabled) is + // cleared. A write of 0 has no + // effect. +#define UART_O_DMACTL 0x00000048 // UART DMA control The DMACTL + // register is the DMA control + // register. +#define UART_O_LCTL 0x00000090 // UART LIN control The LCTL + // register is the configures the + // operation of the UART when in + // LIN mode. +#define UART_O_LSS 0x00000094 // LIN snap shot The LSS register + // captures the free-running timer + // value when either the sync edge + // 1 or the sync edge 5 is detected + // in LIN mode. +#define UART_O_LTIM 0x00000098 // UART LIN timer The LTIM + // register contains the current + // timer value for the free-running + // timer that is used to calculate + // the baud rate when in LIN slave + // mode. The value in this register + // is used along with the value in + // the UART LIN snap shot (LSS) + // register to adjust the baud rate + // to match that of the master. +#define UART_O_NINEBITADDR 0x000000A4 // UART 9-bit self address The + // NINEBITADDR register is used to + // write the specific address that + // should be matched with the + // receiving byte when the 9-bit + // address mask (NINEBITAMASK) is + // set to 0xFF. This register is + // used in conjunction with + // NINEBITAMASK to form a match for + // address-byte received. +#define UART_O_NINEBITAMASK 0x000000A8 // UART 9-bit self address mask + // The NINEBITAMASK register is + // used to enable the address mask + // for 9-bit mode. The lower + // address bits are masked to + // create a range of address to be + // matched with the received + // address byte. +#define UART_O_PP 0x00000FC0 // UART peripheral properties The + // PP register provides information + // regarding the properties of the + // UART module. +#define UART_O_CC 0x00000FC8 // UART clock configuration The CC + // register controls the baud and + // system clocks sources for the + // UART module. For more + // information, see the section + // called "Baud-Rate Generation". + // Note: If the PIOSC is used for + // the UART baud clock, the system + // clock frequency must be at least + // 9 MHz in run mode. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_DR register. +// +//***************************************************************************** +#define UART_DR_OE 0x00000800 // UART overrun error 1: New data + // was received when the FIFO was + // full, resulting in data loss. 0: + // No data has been lost due to a + // FIFO overrun. +#define UART_DR_OE_M 0x00000800 +#define UART_DR_OE_S 11 +#define UART_DR_BE 0x00000400 // UART break error 1: A break + // condition has been detected, + // indicating that the receive data + // input was held low for longer + // than a full-word transmission + // time (defined as start, data, + // parity, and stop bits). 0: No + // break condition has occurred. In + // FIFO mode, this error is + // associated with the character at + // the top of the FIFO. When a + // break occurs, only the one 0 + // character is loaded into the + // FIFO. The next character is only + // enabled after the received data + // input goes to a 1 (marking + // state), and the next valid start + // bit is received. +#define UART_DR_BE_M 0x00000400 +#define UART_DR_BE_S 10 +#define UART_DR_PE 0x00000200 // UART parity error 1: The parity + // of the received data character + // does not match the parity + // defined by bits 2 and 7 of the + // UARTLCRH register 0: No parity + // error has occurred. In FIFO + // mode, this error is associated + // with the character at the top of + // the FIFO. +#define UART_DR_PE_M 0x00000200 +#define UART_DR_PE_S 9 +#define UART_DR_FE 0x00000100 // UART framing error 1: The + // received character does not have + // a valid stop bit (a valid stop + // bit is 1). 0: No framing error + // has occurred. +#define UART_DR_FE_M 0x00000100 +#define UART_DR_FE_S 8 +#define UART_DR_DATA_M 0x000000FF // Data transmitted or received + // Data that is to be transmitted + // via the UART is written to this + // field. When read, this field + // contains the data that was + // received by the UART. +#define UART_DR_DATA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_RSR register. +// +//***************************************************************************** +#define UART_RSR_OE 0x00000008 // UART overrun error 1: New data + // was received when the FIFO was + // full, resulting in data loss. 0: + // No data has been lost due to a + // FIFO overrun. This bit is + // cleared by a write to UARTECR. + // The FIFO contents remain valid + // because no further data is + // written when the FIFO is full, + // only the contents of the shift + // register are overwritten. The + // CPU must read the data in order + // to empty the FIFO. +#define UART_RSR_OE_M 0x00000008 +#define UART_RSR_OE_S 3 +#define UART_RSR_BE 0x00000004 // UART break error 1: A break + // condition has been detected, + // indicating that the receive data + // input was held low for longer + // than a full-word transmission + // time (defined as start, data, + // parity, and stop bits). 0: No + // break condition has occurred. + // This bit is cleared to 0 by a + // write to UARTECR. In FIFO mode, + // this error is associated with + // the character at the top of the + // FIFO. When a break occurs, only + // one 0 character is loaded into + // the FIFO. The next character is + // only enabled after the receive + // data input goes to a 1 (marking + // state) and the next valid start + // bit is received. +#define UART_RSR_BE_M 0x00000004 +#define UART_RSR_BE_S 2 +#define UART_RSR_PE 0x00000002 // UART parity error 1: The parity + // of the received data character + // does not match the parity + // defined by bits 2 and 7 of the + // UARTLCRH register. 0: No parity + // error has occurred. This bit is + // cleared to 0 by a write to + // UARTECR. +#define UART_RSR_PE_M 0x00000002 +#define UART_RSR_PE_S 1 +#define UART_RSR_FE 0x00000001 // UART framing error 1: The + // received character does not have + // a valid stop bit (a valid stop + // bit is 1). 0: No framing error + // has occurred. This bit is + // cleared to 0 by a write to + // UARTECR. In FIFO mode, this + // error is associated with the + // character at the top of the + // FIFO. +#define UART_RSR_FE_M 0x00000001 +#define UART_RSR_FE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_ECR register. +// +//***************************************************************************** +#define UART_ECR_DATA_M 0x000000FF // Error clear A write to this + // register of any data clears the + // framing, parity, break, and + // overrun flags. +#define UART_ECR_DATA_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_FR register. +// +//***************************************************************************** +#define UART_FR_TXFE 0x00000080 // UART transmit FIFO empty The + // meaning of this bit depends on + // the state of the FEN bit in the + // UARTLCRH register. 1: If the + // FIFO is disabled (FEN is 0), the + // transmit holding register is + // empty. If the FIFO is enabled + // (FEN is 1), the transmit FIFO is + // empty. 0: The transmitter has + // data to transmit. +#define UART_FR_TXFE_M 0x00000080 +#define UART_FR_TXFE_S 7 +#define UART_FR_RXFF 0x00000040 // UART receive FIFO full The + // meaning of this bit depends on + // the state of the FEN bit in the + // UARTLCRH register. 1: If the + // FIFO is disabled (FEN is 0), the + // receive holding register is + // full. If the FIFO is enabled + // (FEN is 1), the receive FIFO is + // full. 0: The receiver can + // receive data. +#define UART_FR_RXFF_M 0x00000040 +#define UART_FR_RXFF_S 6 +#define UART_FR_TXFF 0x00000020 // UART transmit FIFO full The + // meaning of this bit depends on + // the state of the FEN bit in the + // UARTLCRH register. 1: If the + // FIFO is disabled (FEN is 0), the + // transmit holding register is + // full. If the FIFO is enabled + // (FEN is 1), the transmit FIFO is + // full. 0: The transmitter is not + // full. +#define UART_FR_TXFF_M 0x00000020 +#define UART_FR_TXFF_S 5 +#define UART_FR_RXFE 0x00000010 // UART receive FIFO empty The + // meaning of this bit depends on + // the state of the FEN bit in the + // UARTLCRH register. 1: If the + // FIFO is disabled (FEN is 0), the + // receive holding register is + // empty. If the FIFO is enabled + // (FEN is 1), the receive FIFO is + // empty. 0: The receiver is not + // empty. +#define UART_FR_RXFE_M 0x00000010 +#define UART_FR_RXFE_S 4 +#define UART_FR_BUSY 0x00000008 // UART busy 1: The UART is busy + // transmitting data. This bit + // remains set until the complete + // byte, including all stop bits, + // has been sent from the shift + // register. 0: The UART is not + // busy. This bit is set as soon as + // the transmit FIFO becomes + // non-empty (regardless of whether + // UART is enabled). +#define UART_FR_BUSY_M 0x00000008 +#define UART_FR_BUSY_S 3 +#define UART_FR_CTS 0x00000001 // Clear to send (UART1 only, + // reserved for UART0). 1: The + // U1CTS signal is asserted. 0: The + // U1CTS signal is not asserted. +#define UART_FR_CTS_M 0x00000001 +#define UART_FR_CTS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_ILPR register. +// +//***************************************************************************** +#define UART_ILPR_ILPDVSR_M 0x000000FF // IrDA low-power divisor This + // field contains the 8-bit + // low-power divisor value. +#define UART_ILPR_ILPDVSR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_IBRD register. +// +//***************************************************************************** +#define UART_IBRD_DIVINT_M 0x0000FFFF // Integer baud-rate divisor +#define UART_IBRD_DIVINT_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_FBRD register. +// +//***************************************************************************** +#define UART_FBRD_DIVFRAC_M 0x0000003F // Fractional baud-rate divisor +#define UART_FBRD_DIVFRAC_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_LCRH register. +// +//***************************************************************************** +#define UART_LCRH_SPS 0x00000080 // UART stick parity select When + // bits 1, 2, and 7 of UARTLCRH are + // set, the parity bit is + // transmitted and checked as a 0. + // When bits 1 and 7 are set and 2 + // is cleared, the parity bit is + // transmitted and checked as a 1. + // When this bit is cleared, stick + // parity is disabled. +#define UART_LCRH_SPS_M 0x00000080 +#define UART_LCRH_SPS_S 7 +#define UART_LCRH_WLEN_M 0x00000060 // UART word length The bits + // indicate the number of data bits + // transmitted or received in a + // frame as follows: 0x0: 5 bits + // (default) 0x1: 6 bits 0x2: 7 + // bits 0x3: 8 bits +#define UART_LCRH_WLEN_S 5 +#define UART_LCRH_FEN 0x00000010 // UART enable FIFOs 1: The + // transmit and receive FIFObuffers + // are enabled (FIFOmode). 0: The + // FIFOs are disabled (Character + // mode). The FIFOs become + // 1-byte-deep holding registers. +#define UART_LCRH_FEN_M 0x00000010 +#define UART_LCRH_FEN_S 4 +#define UART_LCRH_STP2 0x00000008 // UART two stop bits select 1: + // Two stop bits are transmitted at + // the end of a frame. The receive + // logic does not check for two + // stop bits being received. 0: One + // stop bit is transmitted at the + // end of a frame. +#define UART_LCRH_STP2_M 0x00000008 +#define UART_LCRH_STP2_S 3 +#define UART_LCRH_EPS 0x00000004 // UART even parity select 1: Even + // parity generation and checking + // is performed during transmission + // and reception, which checks for + // an even number of 1s in data and + // parity bits. 0: Odd parity is + // performed, which checks for an + // odd number of 1s. This bit has + // no effect when parity is + // disabled by the PEN bit. +#define UART_LCRH_EPS_M 0x00000004 +#define UART_LCRH_EPS_S 2 +#define UART_LCRH_PEN 0x00000002 // UART parity enable 1: Parity + // checking and generation is + // enabled. 0: Parity is disabled + // and no parity bit is added to + // the data frame. +#define UART_LCRH_PEN_M 0x00000002 +#define UART_LCRH_PEN_S 1 +#define UART_LCRH_BRK 0x00000001 // UART send break 1: A low level + // is continually output on the + // UnTx signal, after completing + // transmission of the current + // character. For the proper + // execution of the break command, + // software must set this bit for + // at least two frames (character + // periods). 0: Normal use +#define UART_LCRH_BRK_M 0x00000001 +#define UART_LCRH_BRK_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_CTL register. +// +//***************************************************************************** +#define UART_CTL_CTSEN 0x00008000 // U1CTS Hardware Flow control + // enable 1: When U1CTS input is + // asserted, UART1 can transmit + // data. 0: U1CTS does not control + // UART1 data transmission. Note: + // Only used for UART1. This bit is + // reserved RO for UART0. +#define UART_CTL_CTSEN_M 0x00008000 +#define UART_CTL_CTSEN_S 15 +#define UART_CTL_RTSEN 0x00004000 // U1RTS Hardware Flow control + // enable 1: U1RTS indicates the + // state of UART1 receive FIFO. + // U1RTS remains asserted until the + // preprogrammed watermark level is + // reached, indicating that the + // UART1 RXFIFO has no space to + // store additional characters. 0: + // U1RTS does not indicate state of + // UART1 RX FIFO. Note: Only used + // for UART1. This bit is reserved + // RO for UART0. +#define UART_CTL_RTSEN_M 0x00004000 +#define UART_CTL_RTSEN_S 14 +#define UART_CTL_RXE 0x00000200 // UART receive enable 1: The + // receive section of the UART is + // enabled. 0: The receive section + // of the UART is disabled. If the + // UART is disabled in the middle + // of a receive, it completes the + // current character before + // stopping. Note: To enable + // reception, the UARTEN bit must + // also be set. +#define UART_CTL_RXE_M 0x00000200 +#define UART_CTL_RXE_S 9 +#define UART_CTL_TXE 0x00000100 // UART transmit enable 1: The + // transmit section of the UART is + // enabled. 0: The transmit section + // of the UART is disabled. If the + // UART is disabled in the middle + // of a transmission, it completes + // the current character before + // stopping. Note: To enable + // transmission, the UARTEN bit + // must also be set. +#define UART_CTL_TXE_M 0x00000100 +#define UART_CTL_TXE_S 8 +#define UART_CTL_LBE 0x00000080 // UART loop back enable 1: The + // UnTx path is fed through the + // UnRx path. 0: Normal operation +#define UART_CTL_LBE_M 0x00000080 +#define UART_CTL_LBE_S 7 +#define UART_CTL_LIN 0x00000040 // LIN mode enable 1: The UART + // operates in LIN mode. 0: Normal + // operation +#define UART_CTL_LIN_M 0x00000040 +#define UART_CTL_LIN_S 6 +#define UART_CTL_HSE 0x00000020 // High-speed enable 0: The UART + // is clocked using the system + // clock divided by 16. 1: The UART + // is clocked using the system + // clock divided by 8. Note: System + // clock used is also dependent on + // the baud-rate divisor + // configuration (See Universal + // Asynchronous + // Receivers/Transmitters - + // Baud-Rate Generation). +#define UART_CTL_HSE_M 0x00000020 +#define UART_CTL_HSE_S 5 +#define UART_CTL_EOT 0x00000010 // End of transmission This bit + // determines the behavior of the + // TXRIS bit in the UARTRIS + // register. 1: The TXRIS bit is + // set only after all transmitted + // data, including stop bits, have + // cleared the serializer. 0: The + // TXRIS bit is set when the + // transmit FIFO condition + // specified in UARTIFLS is met. +#define UART_CTL_EOT_M 0x00000010 +#define UART_CTL_EOT_S 4 +#define UART_CTL_SIRLP 0x00000004 // UART SIR low-power mode This + // bit selects the IrDA encoding + // mode. 1: The UART operates in + // SIR Low-Power mode. Low-level + // bits are transmitted with a + // pulse width which is 3 times the + // period of the IrLPBaud16 input + // signal, regardless of the + // selected bit rate. 0: Low-level + // bits are transmitted as an + // active high pulse with a width + // of 3/16th of the bit period. + // Setting this bit uses less + // power, but might reduce + // transmission distances. +#define UART_CTL_SIRLP_M 0x00000004 +#define UART_CTL_SIRLP_S 2 +#define UART_CTL_SIREN 0x00000002 // UART SIR enable 1: The IrDA SIR + // block is enabled, and the UART + // transmits and receives data + // using SIR protocol. 0: Normal + // operation. +#define UART_CTL_SIREN_M 0x00000002 +#define UART_CTL_SIREN_S 1 +#define UART_CTL_UARTEN 0x00000001 // UART enable 1: The UART is + // enabled. 0: The UART is + // disabled. If the UART is + // disabled in the middle of + // transmission or reception, it + // completes the current character + // before stopping. +#define UART_CTL_UARTEN_M 0x00000001 +#define UART_CTL_UARTEN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_IFLS register. +// +//***************************************************************************** +#define UART_IFLS_RXIFLSEL_M 0x00000038 // UART receive interrupt FIFO + // level select The trigger points + // for the receive interrupt are as + // follows: 0x0: RX FIFO >= 1/8 + // full 0x1: RX FIFO >= 1/4 full + // 0x2: RX FIFO >= 1/2 full + // (default) 0x3: RX FIFO >= 3/4 + // full 0x4: RX FIFO >= 7/8 full + // 0x5-0x7: Reserved +#define UART_IFLS_RXIFLSEL_S 3 +#define UART_IFLS_TXIFLSEL_M 0x00000007 // UART Transmit Interrupt FIFO + // Level Select The trigger points + // for the transmit interrupt are + // as follows: 0x0: TX FIFO <= 7/8 + // empty 0x1: TX FIFO <= 3/4 empty + // 0x2: TX FIFO <= 1/2 empty + // (default) 0x3: TX FIFO <= 1/4 + // empty 0x4: TX FIFO <= 1/8 empty + // 0x5-0x7: Reserved Note: If the + // EOT bit in UARTCTL is set, the + // transmit interrupt is generated + // once the FIFO is completely + // empty and all data including + // stop bits have left the transmit + // serializer. In this case, the + // setting of TXIFLSEL is ignored. +#define UART_IFLS_TXIFLSEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_IM register. +// +//***************************************************************************** +#define UART_IM_LME5IM 0x00008000 // LIN mode edge 5 interrupt mask + // 1: An interrupt is sent to the + // interrupt controller when the + // LME5RIS bit in the UARTRIS + // register is set. 0: The LME5RIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_LME5IM_M 0x00008000 +#define UART_IM_LME5IM_S 15 +#define UART_IM_LME1IM 0x00004000 // LIN mode edge 1 interrupt mask + // 1: An interrupt is sent to the + // interrupt controller when the + // LME1RIS bit in the UARTRIS + // register is set. 0: The LME1RIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_LME1IM_M 0x00004000 +#define UART_IM_LME1IM_S 14 +#define UART_IM_LMSBIM 0x00002000 // LIN mode sync break interrupt + // mask 1: An interrupt is sent to + // the interrupt controller when + // the LMSBRIS bit in the UARTRIS + // register is set. 0: The LMSBRIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_LMSBIM_M 0x00002000 +#define UART_IM_LMSBIM_S 13 +#define UART_IM_NINEBITIM 0x00001000 // 9-bit mode interrupt mask 1: An + // interrupt is sent to the + // interrupt controller when the + // 9BITRIS bit in the UARTRIS + // register is set. 0: The 9BITRIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_NINEBITIM_M 0x00001000 +#define UART_IM_NINEBITIM_S 12 +#define UART_IM_OEIM 0x00000400 // UART overrun error interrupt + // mask 1: An interrupt is sent to + // the interrupt controller when + // the OERIS bit in the UARTRIS + // register is set. 0: The OERIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_OEIM_M 0x00000400 +#define UART_IM_OEIM_S 10 +#define UART_IM_BEIM 0x00000200 // UART break error interrupt mask + // 1: An interrupt is sent to the + // interrupt controller when the + // BERIS bit in the UARTRIS + // register is set. 0: The BERIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_BEIM_M 0x00000200 +#define UART_IM_BEIM_S 9 +#define UART_IM_PEIM 0x00000100 // UART parity error interrupt + // mask 1: An interrupt is sent to + // the interrupt controller when + // the PERIS bit in the UARTRIS + // register is set. 0: The PERIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_PEIM_M 0x00000100 +#define UART_IM_PEIM_S 8 +#define UART_IM_FEIM 0x00000080 // UART framing error interrupt + // mask 1: An interrupt is sent to + // the interrupt controller when + // the FERIS bit in the UARTRIS + // register is set. 0: The FERIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_FEIM_M 0x00000080 +#define UART_IM_FEIM_S 7 +#define UART_IM_RTIM 0x00000040 // UART receive time-out interrupt + // mask 1: An interrupt is sent to + // the interrupt controller when + // the RTRIS bit in the UARTRIS + // register is set. 0: The RTRIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_RTIM_M 0x00000040 +#define UART_IM_RTIM_S 6 +#define UART_IM_TXIM 0x00000020 // UART transmit interrupt mask 1: + // An interrupt is sent to the + // interrupt controller when the + // TXRIS bit in the UARTRIS + // register is set. 0: The TXRIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_TXIM_M 0x00000020 +#define UART_IM_TXIM_S 5 +#define UART_IM_RXIM 0x00000010 // UART receive interrupt mask 1: + // An interrupt is sent to the + // interrupt controller when the + // RXRIS bit in the UARTRIS + // register is set. 0: The RXRIS + // interrupt is suppressed and not + // sent to the interrupt + // controller. +#define UART_IM_RXIM_M 0x00000010 +#define UART_IM_RXIM_S 4 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_RIS register. +// +//***************************************************************************** +#define UART_RIS_LME5RIS 0x00008000 // LIN mode edge 5 raw interrupt + // status 1: The timer value at the + // 5th falling edge of the LIN sync + // field has been captured. 0: No + // interrupt This bit is cleared by + // writing 1 to the LME5IC bit in + // the UARTICR register. +#define UART_RIS_LME5RIS_M 0x00008000 +#define UART_RIS_LME5RIS_S 15 +#define UART_RIS_LME1RIS 0x00004000 // LIN mode edge 1 raw interrupt + // status 1: The timer value at the + // 1st falling edge of the LIN Sync + // Field has been captured. 0: No + // interrupt This bit is cleared by + // writing 1 to the LME1IC bit in + // the UARTICR register. +#define UART_RIS_LME1RIS_M 0x00004000 +#define UART_RIS_LME1RIS_S 14 +#define UART_RIS_LMSBRIS 0x00002000 // LIN mode sync break raw + // interrupt status 1: A LIN sync + // break has been detected. 0: No + // interrupt This bit is cleared by + // writing 1 to the LMSBIC bit in + // the UARTICR register. +#define UART_RIS_LMSBRIS_M 0x00002000 +#define UART_RIS_LMSBRIS_S 13 +#define UART_RIS_NINEBITRIS 0x00001000 // 9-mit mode raw interrupt status + // 1: A receive address match has + // occurred. 0: No interrupt This + // bit is cleared by writing 1 to + // the 9BITIC bit in the UARTICR + // register. +#define UART_RIS_NINEBITRIS_M 0x00001000 +#define UART_RIS_NINEBITRIS_S 12 +#define UART_RIS_OERIS 0x00000400 // UART overrun error raw + // interrupt status 1: An overrun + // error has occurred. 0: No + // interrupt This bit is cleared by + // writing 1 to the OEIC bit in the + // UARTICR register. +#define UART_RIS_OERIS_M 0x00000400 +#define UART_RIS_OERIS_S 10 +#define UART_RIS_BERIS 0x00000200 // UART break error raw interrupt + // status 1: A break error has + // occurred. 0: No interrupt This + // bit is cleared by writing 1 to + // the BEIC bit in the UARTICR + // register. +#define UART_RIS_BERIS_M 0x00000200 +#define UART_RIS_BERIS_S 9 +#define UART_RIS_PERIS 0x00000100 // UART parity error raw interrupt + // status 1: A parity error has + // occurred. 0: No interrupt This + // bit is cleared by writing 1 to + // the PEIC bit in the UARTICR + // register. +#define UART_RIS_PERIS_M 0x00000100 +#define UART_RIS_PERIS_S 8 +#define UART_RIS_FERIS 0x00000080 // UART framing error raw + // interrupt status 1: A framing + // error has occurred. 0: No + // interrupt This bit is cleared by + // writing 1 to the FEIC bit in the + // UARTICR register. +#define UART_RIS_FERIS_M 0x00000080 +#define UART_RIS_FERIS_S 7 +#define UART_RIS_RTRIS 0x00000040 // UART receive time-out raw + // interrupt status 1: A receive + // time out has occurred. 0: No + // interrupt This bit is cleared by + // writing 1 to the RTIC bit in the + // UARTICR register. +#define UART_RIS_RTRIS_M 0x00000040 +#define UART_RIS_RTRIS_S 6 +#define UART_RIS_TXRIS 0x00000020 // UART transmit raw interrupt + // status 1: If the EOT bit in the + // UARTCTL register is clear, the + // transmit FIFO level has passed + // through the condition defined in + // the UARTIFLS register. If the + // EOT bit is set, the last bit of + // all transmitted data and flags + // has left the serializer. 0: No + // interrupt This bit is cleared by + // writing 1 to the TXIC bit in the + // UARTICR register. +#define UART_RIS_TXRIS_M 0x00000020 +#define UART_RIS_TXRIS_S 5 +#define UART_RIS_RXRIS 0x00000010 // UART receive raw interrupt + // status 1: The receive FIFO level + // has passed through the condition + // defined in the UARTIFLS + // register. 0: No interrupt This + // bit is cleared by writing 1 to + // the RXIC bit in the UARTICR + // register. +#define UART_RIS_RXRIS_M 0x00000010 +#define UART_RIS_RXRIS_S 4 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_MIS register. +// +//***************************************************************************** +#define UART_MIS_LME5MIS 0x00008000 // LIN mode edge 5 masked + // interrupt status 1: An unmasked + // interrupt was signaled due to + // the 5th falling edge of the LIN + // sync field. 0: An interrupt has + // not occurred or is masked. This + // bit is cleared by writing 1 to + // the LME5IC bit in the UARTICR + // register. +#define UART_MIS_LME5MIS_M 0x00008000 +#define UART_MIS_LME5MIS_S 15 +#define UART_MIS_LME1MIS 0x00004000 // LIN mode edge 1 masked + // interrupt status 1: An unmasked + // interrupt was signaled due to + // the 1st falling edge of the LIN + // sync field. 0: An interrupt has + // not occurred or is masked. This + // bit is cleared by writing 1 to + // the LME1IC bit in the UARTICR + // register. +#define UART_MIS_LME1MIS_M 0x00004000 +#define UART_MIS_LME1MIS_S 14 +#define UART_MIS_LMSBMIS 0x00002000 // LIN mode sync break masked + // interrupt status 1: An unmasked + // interrupt was signaled due to + // the receipt of a LIN sync break. + // 0: An interrupt has not occurred + // or is masked. This bit is + // cleared by writing 1 to the + // LMSBIC bit in the UARTICR + // register. +#define UART_MIS_LMSBMIS_M 0x00002000 +#define UART_MIS_LMSBMIS_S 13 +#define UART_MIS_NINEBITMIS 0x00001000 // 9-bit mode masked interrupt + // status 1: An unmasked interrupt + // was signaled due to a receive + // address match. 0: An interrupt + // has not occurred or is masked. + // This bit is cleared by writing 1 + // to the 9BITIC bit in the UARTICR + // register. +#define UART_MIS_NINEBITMIS_M 0x00001000 +#define UART_MIS_NINEBITMIS_S 12 +#define UART_MIS_OEMIS 0x00000400 // UART overrun error masked + // interrupt status 1: An unmasked + // interrupt was signaled due to an + // overrun error. 0: An interrupt + // has not occurred or is masked. + // This bit is cleared by writing 1 + // to the OEIC bit in the UARTICR + // register. +#define UART_MIS_OEMIS_M 0x00000400 +#define UART_MIS_OEMIS_S 10 +#define UART_MIS_BEMIS 0x00000200 // UART break error masked + // interrupt status 1: An unmasked + // interrupt was signaled due to a + // break error. 0: An interrupt has + // not occurred or is masked. This + // bit is cleared by writing 1 to + // the BEIC bit in the UARTICR + // register. +#define UART_MIS_BEMIS_M 0x00000200 +#define UART_MIS_BEMIS_S 9 +#define UART_MIS_PEMIS 0x00000100 // UART parity error masked + // interrupt status 1: An unmasked + // interrupt was signaled due to a + // parity error. 0: An interrupt + // has not occurred or is masked. + // This bit is cleared by writing 1 + // to the PEIC bit in the UARTICR + // register. +#define UART_MIS_PEMIS_M 0x00000100 +#define UART_MIS_PEMIS_S 8 +#define UART_MIS_FEMIS 0x00000080 // UART framing error masked + // interrupt status 1: An unmasked + // interrupt was signaled due to a + // framing error. 0: An interrupt + // has not occurred or is masked. + // This bit is cleared by writing 1 + // to the FEIC bit in the UARTICR + // register. +#define UART_MIS_FEMIS_M 0x00000080 +#define UART_MIS_FEMIS_S 7 +#define UART_MIS_RTMIS 0x00000040 // UART receive time-out masked + // interrupt status 1: An unmasked + // interrupt was signaled due to a + // receive time out. 0: An + // interrupt has not occurred or is + // masked. This bit is cleared by + // writing 1 to the RTIC bit in the + // UARTICR register. +#define UART_MIS_RTMIS_M 0x00000040 +#define UART_MIS_RTMIS_S 6 +#define UART_MIS_TXMIS 0x00000020 // UART transmit masked interrupt + // status 1: An unmasked interrupt + // was signaled due to passing + // through the specified transmit + // FIFO level (if the EOT bit is + // clear) or due to the + // transmission of the last data + // bit (if the EOT bit is set). 0: + // An interrupt has not occurred or + // is masked. This bit is cleared + // by writing 1 to the TXIC bit in + // the UARTICR register. +#define UART_MIS_TXMIS_M 0x00000020 +#define UART_MIS_TXMIS_S 5 +#define UART_MIS_RXMIS 0x00000010 // UART receive masked interrupt + // status 1: An unmasked interrupt + // was signaled due to passing + // through the specified receive + // FIFO level. 0: An interrupt has + // not occurred or is masked. This + // bit is cleared by writing 1 to + // the RXIC bit in the UARTICR + // register. +#define UART_MIS_RXMIS_M 0x00000010 +#define UART_MIS_RXMIS_S 4 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_ICR register. +// +//***************************************************************************** +#define UART_ICR_LME5IC 0x00008000 // LIN mode edge 5 interrupt clear + // Writing 1 to this bit clears the + // LME5RIS bit in the UARTRIS + // register and the LME5MIS bit in + // the UARTMIS register. +#define UART_ICR_LME5IC_M 0x00008000 +#define UART_ICR_LME5IC_S 15 +#define UART_ICR_LME1IC 0x00004000 // LIN mode edge 1 interrupt clear + // Writing 1 to this bit clears the + // LME1RIS bit in the UARTRIS + // register and the LME1MIS bit in + // the UARTMIS register. +#define UART_ICR_LME1IC_M 0x00004000 +#define UART_ICR_LME1IC_S 14 +#define UART_ICR_LMSBIC 0x00002000 // LIN mode sync break interrupt + // clear Writing 1 to this bit + // clears the LMSBRIS bit in the + // UARTRIS register and the LMSBMIS + // bit in the UARTMIS register. +#define UART_ICR_LMSBIC_M 0x00002000 +#define UART_ICR_LMSBIC_S 13 +#define UART_ICR_NINEBITIC 0x00001000 // 9-bit mode interrupt clear + // Writing 1 to this bit clears the + // 9BITRIS bit in the UARTRIS + // register and the 9BITMIS bit in + // the UARTMIS register. +#define UART_ICR_NINEBITIC_M 0x00001000 +#define UART_ICR_NINEBITIC_S 12 +#define UART_ICR_OEIC 0x00000400 // Overrun error interrupt clear + // Writing 1 to this bit clears the + // OERIS bit in the UARTRIS + // register and the OEMIS bit in + // the UARTMIS register. +#define UART_ICR_OEIC_M 0x00000400 +#define UART_ICR_OEIC_S 10 +#define UART_ICR_BEIC 0x00000200 // Break error interrupt clear + // Writing 1 to this bit clears the + // BERIS bit in the UARTRIS + // register and the BEMIS bit in + // the UARTMIS register. +#define UART_ICR_BEIC_M 0x00000200 +#define UART_ICR_BEIC_S 9 +#define UART_ICR_PEIC 0x00000100 // Parity error interrupt clear + // Writing 1 to this bit clears the + // PERIS bit in the UARTRIS + // register and the PEMIS bit in + // the UARTMIS register. +#define UART_ICR_PEIC_M 0x00000100 +#define UART_ICR_PEIC_S 8 +#define UART_ICR_FEIC 0x00000080 // Framing error interrupt clear + // Writing 1 to this bit clears the + // FERIS bit in the UARTRIS + // register and the FEMIS bit in + // the UARTMIS register. +#define UART_ICR_FEIC_M 0x00000080 +#define UART_ICR_FEIC_S 7 +#define UART_ICR_RTIC 0x00000040 // Receive time-out interrupt + // clear Writing 1 to this bit + // clears the RTRIS bit in the + // UARTRIS register and the RTMIS + // bit in the UARTMIS register. +#define UART_ICR_RTIC_M 0x00000040 +#define UART_ICR_RTIC_S 6 +#define UART_ICR_TXIC 0x00000020 // Transmit interrupt clear + // Writing 1 to this bit clears the + // TXRIS bit in the UARTRIS + // register and the TXMIS bit in + // the UARTMIS register. +#define UART_ICR_TXIC_M 0x00000020 +#define UART_ICR_TXIC_S 5 +#define UART_ICR_RXIC 0x00000010 // Receive interrupt clear Writing + // 1 to this bit clears the RXRIS + // bit in the UARTRIS register and + // the RXMIS bit in the UARTMIS + // register. +#define UART_ICR_RXIC_M 0x00000010 +#define UART_ICR_RXIC_S 4 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_DMACTL register. +// +//***************************************************************************** +#define UART_DMACTL_DMAERR 0x00000004 // DMA on error 1: uDMA receive + // requests are automatically + // disabled when a receive error + // occurs. 0: uDMA receive requests + // are unaffected when a receive + // error occurs. +#define UART_DMACTL_DMAERR_M 0x00000004 +#define UART_DMACTL_DMAERR_S 2 +#define UART_DMACTL_TXDMAE 0x00000002 // Transmit DMA enable 1: uDMA for + // the transmit FIFO is enabled. 0: + // uDMA for the transmit FIFO is + // disabled. +#define UART_DMACTL_TXDMAE_M 0x00000002 +#define UART_DMACTL_TXDMAE_S 1 +#define UART_DMACTL_RXDMAE 0x00000001 // Receive DMA enable 1: uDMA for + // the receive FIFO is enabled. 0: + // uDMA for the receive FIFO is + // disabled. +#define UART_DMACTL_RXDMAE_M 0x00000001 +#define UART_DMACTL_RXDMAE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_LCTL register. +// +//***************************************************************************** +#define UART_LCTL_BLEN_M 0x00000030 // Sync break length 0x3: Sync + // break length is 16T bits 0x2: + // Sync break length is 15T bits + // 0x1: Sync break length is 14T + // bits 0x0: Sync break length is + // 13T bits (default) +#define UART_LCTL_BLEN_S 4 +#define UART_LCTL_MASTER 0x00000001 // LIN master enable 1: The UART + // operates as a LIN master. 0: The + // UART operates as a LIN slave. +#define UART_LCTL_MASTER_M 0x00000001 +#define UART_LCTL_MASTER_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_LSS register. +// +//***************************************************************************** +#define UART_LSS_TSS_M 0x0000FFFF // Timer snap shot This field + // contains the value of the + // free-running timer when either + // the sync edge 5 or the sync edge + // 1 was detected. +#define UART_LSS_TSS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_LTIM register. +// +//***************************************************************************** +#define UART_LTIM_TIMER_M 0x0000FFFF // Timer value This field contains + // the value of the free-running + // timer. +#define UART_LTIM_TIMER_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UART_O_NINEBITADDR register. +// +//***************************************************************************** +#define UART_NINEBITADDR_NINEBITEN \ + 0x00008000 // Enable 9-bit mode 1: 9-bit mode + // is enabled. 0: 9-bit mode is + // disabled. + +#define UART_NINEBITADDR_NINEBITEN_M \ + 0x00008000 +#define UART_NINEBITADDR_NINEBITEN_S 15 +#define UART_NINEBITADDR_ADDR_M 0x000000FF // Self address for 9-bit mode + // This field contains the address + // that should be matched when + // UART9BITAMASK is 0xFF. +#define UART_NINEBITADDR_ADDR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UART_O_NINEBITAMASK register. +// +//***************************************************************************** +#define UART_NINEBITAMASK_RANGE_M \ + 0x0000FF00 // Self address range for 9-bit + // mode Writing to the RANGE field + // does not have any effect; + // reading it reflects the ANDed + // output of the ADDR field in the + // UART9BITADDR register and the + // MASK field. + +#define UART_NINEBITAMASK_RANGE_S 8 +#define UART_NINEBITAMASK_MASK_M \ + 0x000000FF // Self Address Mask for 9-Bit + // Mode This field contains the + // address mask that creates a + // range of addresses that should + // be matched. + +#define UART_NINEBITAMASK_MASK_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_PP register. +// +//***************************************************************************** +#define UART_PP_NB 0x00000002 // 9-bit support 1: The UART + // module provides support for the + // transmission of 9-bit data for + // RS-485 support. 0: The UART + // module does not provide support + // for the transmission of 9-bit + // data for RS-485 support. +#define UART_PP_NB_M 0x00000002 +#define UART_PP_NB_S 1 +#define UART_PP_SC 0x00000001 // Smart card support 1: The UART + // module provides smart card + // support. 0: The UART module does + // not provide smart card support. +#define UART_PP_SC_M 0x00000001 +#define UART_PP_SC_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UART_O_CC register. +// +//***************************************************************************** +#define UART_CC_CS_M 0x00000007 // UART baud and system clock + // source The following bits + // determine the clock source that + // generates the baud and system + // clocks for the UART. bit0 + // (PIOSC): 1: The UART baud clock + // is determined by the IO DIV + // setting in the system + // controller. 0: The UART baud + // clock is determined by the SYS + // DIV setting in the system + // controller. bit1: Unused bit2: + // (DSEN) Only meaningful when the + // system is in deep sleep mode. + // This bit is a don't care when + // not in sleep mode. 1: The UART + // system clock is running on the + // same clock as the baud clock, as + // per PIOSC setting above. 0: The + // UART system clock is determined + // by the SYS DIV setting in the + // system controller. +#define UART_CC_CS_S 0 + + +#endif // __HW_UART_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_udma.h b/bsp/boards/mimsy2-cc2538/headers/hw_udma.h new file mode 100644 index 0000000000..0852153072 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_udma.h @@ -0,0 +1,744 @@ +/****************************************************************************** +* Filename: hw_udma.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_UDMA_H__ +#define __HW_UDMA_H__ + +//***************************************************************************** +// +// The following are defines for the UDMA register offsets. +// +//***************************************************************************** +#define UDMA_STAT 0x400FF000 // DMA status The STAT register + // returns the status of the uDMA + // controller. This register cannot + // be read when the uDMA controller + // is in the reset state. +#define UDMA_CFG 0x400FF004 // DMA configuration The CFG + // register controls the + // configuration of the uDMA + // controller. +#define UDMA_CTLBASE 0x400FF008 // DMA channel control base + // pointer The CTLBASE register + // must be configured so that the + // base pointer points to a + // location in system memory. The + // amount of system memory that + // must be assigned to the uDMA + // controller depends on the number + // of uDMA channels used and + // whether the alternate channel + // control data structure is used. + // See Section 10.2.5 for details + // about the Channel Control Table. + // The base address must be aligned + // on a 1024-byte boundary. This + // register cannot be read when the + // uDMA controller is in the reset + // state. +#define UDMA_ALTBASE 0x400FF00C // DMA alternate channel control + // base pointer The ALTBASE + // register returns the base + // address of the alternate channel + // control data. This register + // removes the necessity for + // application software to + // calculate the base address of + // the alternate channel control + // structures. This register cannot + // be read when the uDMA controller + // is in the reset state. +#define UDMA_WAITSTAT 0x400FF010 // DMA channel wait-on-request + // status This read-only register + // indicates that the uDMA channel + // is waiting on a request. A + // peripheral can hold off the uDMA + // from performing a single request + // until the peripheral is ready + // for a burst request to enhance + // the uDMA performance. The use of + // this feature is dependent on the + // design of the peripheral and is + // not controllable by software in + // any way. This register cannot be + // read when the uDMA controller is + // in the reset state. +#define UDMA_SWREQ 0x400FF014 // DMA channel software request + // Each bit of the SWREQ register + // represents the corresponding + // uDMA channel. Setting a bit + // generates a request for the + // specified uDMA channel. +#define UDMA_USEBURSTSET 0x400FF018 // DMA channel useburst set Each + // bit of the USEBURSTSET register + // represents the corresponding + // uDMA channel. Setting a bit + // disables the channel single + // request input from generating + // requests, configuring the + // channel to only accept burst + // requests. Reading the register + // returns the status of USEBURST. + // If the amount of data to + // transfer is a multiple of the + // arbitration (burst) size, the + // corresponding SET[n] bit is + // cleared after completing the + // final transfer. If there are + // fewer items remaining to + // transfer than the arbitration + // (burst) size, the uDMA + // controller automatically clears + // the corresponding SET[n] bit, + // allowing the remaining items to + // transfer using single requests. + // To resume transfers using burst + // requests, the corresponding bit + // must be set again. A bit must + // not be set if the corresponding + // peripheral does not support the + // burst request model. +#define UDMA_USEBURSTCLR 0x400FF01C // DMA channel useburst clear Each + // bit of the USEBURSTCLR register + // represents the corresponding + // uDMA channel. Setting a bit + // clears the corresponding SET[n] + // bit in the USEBURSTSET register. +#define UDMA_REQMASKSET 0x400FF020 // DMA channel request mask set + // Each bit of the REQMASKSET + // register represents the + // corresponding uDMA channel. + // Setting a bit disables uDMA + // requests for the channel. + // Reading the register returns the + // request mask status. When a uDMA + // channel request is masked, that + // means the peripheral can no + // longer request uDMA transfers. + // The channel can then be used for + // software-initiated transfers. +#define UDMA_REQMASKCLR 0x400FF024 // DMA channel request mask clear + // Each bit of the REQMASKCLR + // register represents the + // corresponding uDMA channel. + // Setting a bit clears the + // corresponding SET[n] bit in the + // REQMASKSET register. +#define UDMA_ENASET 0x400FF028 // DMA channel enable set Each bit + // of the ENASET register + // represents the corresponding + // uDMA channel. Setting a bit + // enables the corresponding uDMA + // channel. Reading the register + // returns the enable status of the + // channels. If a channel is + // enabled but the request mask is + // set (REQMASKSET), then the + // channel can be used for + // software-initiated transfers. +#define UDMA_ENACLR 0x400FF02C // DMA channel enable clear Each + // bit of the ENACLR register + // represents the corresponding + // uDMA channel. Setting a bit + // clears the corresponding SET[n] + // bit in the ENASET register. +#define UDMA_ALTSET 0x400FF030 // DMA channel primary alternate + // set Each bit of the ALTSET + // register represents the + // corresponding uDMA channel. + // Setting a bit configures the + // uDMA channel to use the + // alternate control data + // structure. Reading the register + // returns the status of which + // control data structure is in use + // for the corresponding uDMA + // channel. +#define UDMA_ALTCLR 0x400FF034 // DMA channel primary alternate + // clear Each bit of the ALTCLR + // register represents the + // corresponding uDMA channel. + // Setting a bit clears the + // corresponding SET[n] bit in the + // ALTSET register. +#define UDMA_PRIOSET 0x400FF038 // DMA channel priority set Each + // bit of the PRIOSET register + // represents the corresponding + // uDMA channel. Setting a bit + // configures the uDMA channel to + // have a high priority level. + // Reading the register returns the + // status of the channel priority + // mask. +#define UDMA_PRIOCLR 0x400FF03C // DMA channel priority clear Each + // bit of the DMAPRIOCLR register + // represents the corresponding + // uDMA channel. Setting a bit + // clears the corresponding SET[n] + // bit in the PRIOSET register. +#define UDMA_ERRCLR 0x400FF04C // DMA bus error clear The ERRCLR + // register is used to read and + // clear the uDMA bus error status. + // The error status is set if the + // uDMA controller encountered a + // bus error while performing a + // transfer. If a bus error occurs + // on a channel, that channel is + // automatically disabled by the + // uDMA controller. The other + // channels are unaffected. +#define UDMA_CHASGN 0x400FF500 // DMA channel assignment Each bit + // of the CHASGN register + // represents the corresponding + // uDMA channel. Setting a bit + // selects the secondary channel + // assignment as specified in the + // section "Channel Assignments" +#define UDMA_CHIS 0x400FF504 // DMA channel interrupt status + // Each bit of the CHIS register + // represents the corresponding + // uDMA channel. A bit is set when + // that uDMA channel causes a + // completion interrupt. The bits + // are cleared by writing 1. +#define UDMA_CHMAP0 0x400FF510 // DMA channel map select 0 Each + // 4-bit field of the CHMAP0 + // register configures the uDMA + // channel assignment as specified + // in the uDMA channel assignment + // table in the "Channel + // Assignments" section. +#define UDMA_CHMAP1 0x400FF514 // DMA channel map select 1 Each + // 4-bit field of the CHMAP1 + // register configures the uDMA + // channel assignment as specified + // in the uDMA channel assignment + // table in the "Channel + // Assignments" section. +#define UDMA_CHMAP2 0x400FF518 // DMA channel map select 2 Each + // 4-bit field of the CHMAP2 + // register configures the uDMA + // channel assignment as specified + // in the uDMA channel assignment + // table in the "Channel + // Assignments" section. +#define UDMA_CHMAP3 0x400FF51C // DMA channel map select 3 Each + // 4-bit field of the CHMAP3 + // register configures the uDMA + // channel assignment as specified + // in the uDMA channel assignment + // table in the "Channel + // Assignments" section. + + +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_STAT register. +// +//***************************************************************************** +#define UDMA_STAT_DMACHANS_M 0x001F0000 // Available uDMA channels minus 1 + // This field contains a value + // equal to the number of uDMA + // channels the uDMA controller is + // configured to use, minus one. + // The value of 0x1F corresponds to + // 32 uDMA channels. +#define UDMA_STAT_DMACHANS_S 16 +#define UDMA_STAT_STATE_M 0x000000F0 // Control state machine status + // This field shows the current + // status of the control + // state-machine. Status can be one + // of the following: 0x0: Idle 0x1: + // Reading channel controller data + // 0x2: Reading source end pointer + // 0x3: Reading destination end + // pointer 0x4: Reading source data + // 0x5: Writing destination data + // 0x6: Waiting for uDMA request to + // clear 0x7: Writing channel + // controller data 0x8: Stalled + // 0x9: Done 0xA-0xF: Undefined +#define UDMA_STAT_STATE_S 4 +#define UDMA_STAT_MASTEN 0x00000001 // Master enable status 0: The + // uDMA controller is disabled. 1: + // The uDMA controller is enabled. +#define UDMA_STAT_MASTEN_M 0x00000001 +#define UDMA_STAT_MASTEN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_CFG register. +// +//***************************************************************************** +#define UDMA_CFG_MASTEN 0x00000001 // Controller master enable 0: + // Disables the uDMA controller. 1: + // Enables the uDMA controller. +#define UDMA_CFG_MASTEN_M 0x00000001 +#define UDMA_CFG_MASTEN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_CTLBASE register. +// +//***************************************************************************** +#define UDMA_CTLBASE_ADDR_M 0xFFFFFC00 // Channel control base address + // This field contains the pointer + // to the base address of the + // channel control table. The base + // address must be 1024-byte + // alligned. +#define UDMA_CTLBASE_ADDR_S 10 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_ALTBASE register. +// +//***************************************************************************** +#define UDMA_ALTBASE_ADDR_M 0xFFFFFFFF // Alternate channel address + // pointer This field provides the + // base address of the alternate + // channel control structures. +#define UDMA_ALTBASE_ADDR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UDMA_WAITSTAT register. +// +//***************************************************************************** +#define UDMA_WAITSTAT_WAITREQ_M 0xFFFFFFFF // Channel [n] wait status These + // bits provide the tchannel + // wait-on-request status. Bit 0 + // corresponds to channel 0. 1: The + // corresponding channel is waiting + // on a request. 0: The + // corresponding channel is not + // waiting on a request. +#define UDMA_WAITSTAT_WAITREQ_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_SWREQ register. +// +//***************************************************************************** +#define UDMA_SWREQ_SWREQ_M 0xFFFFFFFF // Channel [n] software request + // These bits generate software + // requests. Bit 0 corresponds to + // channel 0. 1: Generate a + // software request for the + // corresponding channel 0: No + // request generated These bits are + // automatically cleared when the + // software request has been + // completed. +#define UDMA_SWREQ_SWREQ_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UDMA_USEBURSTSET register. +// +//***************************************************************************** +#define UDMA_USEBURSTSET_SET_M 0xFFFFFFFF // Channel [n] useburst set 0: + // uDMA channel [n] responds to + // single or burst requests. 1: + // uDMA channel [n] responds only + // to burst requests. Bit 0 + // corresponds to channel 0. This + // bit is automatically cleared as + // described above. A bit can also + // be manually cleared by setting + // the corresponding CLR[n] bit in + // the DMAUSEBURSTCLR register. +#define UDMA_USEBURSTSET_SET_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UDMA_USEBURSTCLR register. +// +//***************************************************************************** +#define UDMA_USEBURSTCLR_CLR_M 0xFFFFFFFF // Channel [n] useburst clear 0: + // No effect 1: Setting a bit + // clears the corresponding SET[n] + // bit in the DMAUSEBURSTSET + // register meaning that uDMA + // channel [n] responds to single + // and burst requests. +#define UDMA_USEBURSTCLR_CLR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UDMA_REQMASKSET register. +// +//***************************************************************************** +#define UDMA_REQMASKSET_SET_M 0xFFFFFFFF // Channel [n] request mask set 0: + // The peripheral associated with + // channel [n] is enabled to + // request uDMA transfers 1: The + // peripheral associated with + // channel [n] is not able to + // request uDMA transfers. Channel + // [n] may be used for + // software-initiated transfers. + // Bit 0 corresponds to channel 0. + // A bit can only be cleared by + // setting the corresponding CLR[n] + // bit in the DMAREQMASKCLR + // register. +#define UDMA_REQMASKSET_SET_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UDMA_REQMASKCLR register. +// +//***************************************************************************** +#define UDMA_REQMASKCLR_CLR_M 0xFFFFFFFF // Channel [n] request mask clear + // 0: No effect 1: Setting a bit + // clears the corresponding SET[n] + // bit in the DMAREQMASKSET + // register meaning that the + // peripheral associated with + // channel [n] is enabled to + // request uDMA transfers. +#define UDMA_REQMASKCLR_CLR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_ENASET register. +// +//***************************************************************************** +#define UDMA_ENASET_SET_M 0xFFFFFFFF // Channel [n] enable set 0: uDMA + // channel [n] is disabled 1: uDMA + // channel [n] is enabled Bit 0 + // corresponds to channel 0. A bit + // can only be cleared by setting + // the corresponding CLR[n] bit in + // the DMAENACLR register. +#define UDMA_ENASET_SET_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_ENACLR register. +// +//***************************************************************************** +#define UDMA_ENACLR_CLR_M 0xFFFFFFFF // Channel [n] enable clear 0: No + // effect 1: Setting a bit clears + // the corresponding SET[n] bit in + // the DMAENASET register meaning + // that channel [n] is disabled for + // uDMA transfers. Note: The + // controller disables a channel + // when it completes the uDMA + // cycle. +#define UDMA_ENACLR_CLR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_ALTSET register. +// +//***************************************************************************** +#define UDMA_ALTSET_SET_M 0xFFFFFFFF // Channel [n] alternate set 0: + // uDMA channel [n] is using the + // primary control structure 1: + // uDMA channel [n] is using the + // alternate control structure Bit + // 0 corresponds to channel 0. A + // bit can only be cleared by + // setting the corresponding CLR[n] + // bit in the DMAALTCLR register. + // Note: For Ping-Pong and + // Scatter-Gather cycle types, the + // uDMA controller automatically + // sets these bits to select the + // alternate channel control data + // structure. +#define UDMA_ALTSET_SET_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_ALTCLR register. +// +//***************************************************************************** +#define UDMA_ALTCLR_CLR_M 0xFFFFFFFF // Channel [n] alternate clear 0: + // No effect 1: Setting a bit + // clears the corresponding SET[n] + // bit in the DMAALTSET register + // meaning that channel [n] is + // using the primary control + // structure. Note: For Ping-Pong + // and Scatter-Gather cycle types, + // the uDMA controller + // automatically sets these bits to + // select the alternate channel + // control data structure. +#define UDMA_ALTCLR_CLR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_PRIOSET register. +// +//***************************************************************************** +#define UDMA_PRIOSET_SET_M 0xFFFFFFFF // Channel [n] priority set 0: + // uDMA channel [n] is using the + // default priority level 1: uDMA + // channel [n] is using a high + // priority level Bit 0 corresponds + // to channel 0. A bit can only be + // cleared by setting the + // corresponding CLR[n] bit in the + // DMAPRIOCLR register. +#define UDMA_PRIOSET_SET_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_PRIOCLR register. +// +//***************************************************************************** +#define UDMA_PRIOCLR_CLR_M 0xFFFFFFFF // Channel [n] priority clear 0: + // No effect 1: Setting a bit + // clears the corresponding SET[n] + // bit in the DMAPRIOSET register + // meaning that channel [n] is + // using the default priority + // level. +#define UDMA_PRIOCLR_CLR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_ERRCLR register. +// +//***************************************************************************** +#define UDMA_ERRCLR_ERRCLR 0x00000001 // uDMA bus error status 0: No bus + // error is pending 1: A bus error + // is pending This bit is cleared + // by writing 1 to it. +#define UDMA_ERRCLR_ERRCLR_M 0x00000001 +#define UDMA_ERRCLR_ERRCLR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_CHASGN register. +// +//***************************************************************************** +#define UDMA_CHASGN_CHASGN_M 0xFFFFFFFF // Channel [n] assignment select + // 0: Use the primary channel + // assignment 1: Use the secondary + // channel assignment +#define UDMA_CHASGN_CHASGN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_CHIS register. +// +//***************************************************************************** +#define UDMA_CHIS_CHIS_M 0xFFFFFFFF // Channel [n] interrupt status 0: + // The corresponding uDMA channel + // has not caused an interrupt. 1: + // The corresponding uDMA channel + // has caused an interrupt. This + // bit is cleared by writing 1 to + // it. +#define UDMA_CHIS_CHIS_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_CHMAP0 register. +// +//***************************************************************************** +#define UDMA_CHMAP0_CH7SEL_M 0xF0000000 // uDMA channel 7 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP0_CH7SEL_S 28 +#define UDMA_CHMAP0_CH6SEL_M 0x0F000000 // uDMA channel 6 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP0_CH6SEL_S 24 +#define UDMA_CHMAP0_CH5SEL_M 0x00F00000 // uDMA channel 5 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP0_CH5SEL_S 20 +#define UDMA_CHMAP0_CH4SEL_M 0x000F0000 // uDMA channel 4 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP0_CH4SEL_S 16 +#define UDMA_CHMAP0_CH3SEL_M 0x0000F000 // uDMA channel 3 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP0_CH3SEL_S 12 +#define UDMA_CHMAP0_CH2SEL_M 0x00000F00 // uDMA channel 2 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP0_CH2SEL_S 8 +#define UDMA_CHMAP0_CH1SEL_M 0x000000F0 // uDMA channel 1 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP0_CH1SEL_S 4 +#define UDMA_CHMAP0_CH0SEL_M 0x0000000F // uDMA channel 0 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP0_CH0SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_CHMAP1 register. +// +//***************************************************************************** +#define UDMA_CHMAP1_CH15SEL_M 0xF0000000 // uDMA channel 15 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP1_CH15SEL_S 28 +#define UDMA_CHMAP1_CH14SEL_M 0x0F000000 // uDMA channel 14 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP1_CH14SEL_S 24 +#define UDMA_CHMAP1_CH13SEL_M 0x00F00000 // uDMA channel 13 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP1_CH13SEL_S 20 +#define UDMA_CHMAP1_CH12SEL_M 0x000F0000 // uDMA channel 12 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP1_CH12SEL_S 16 +#define UDMA_CHMAP1_CH11SEL_M 0x0000F000 // uDMA channel 11 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP1_CH11SEL_S 12 +#define UDMA_CHMAP1_CH10SEL_M 0x00000F00 // uDMA channel 10 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP1_CH10SEL_S 8 +#define UDMA_CHMAP1_CH9SEL_M 0x000000F0 // uDMA channel 9 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP1_CH9SEL_S 4 +#define UDMA_CHMAP1_CH8SEL_M 0x0000000F // uDMA channel 8 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP1_CH8SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_CHMAP2 register. +// +//***************************************************************************** +#define UDMA_CHMAP2_CH23SEL_M 0xF0000000 // uDMA channel 23 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP2_CH23SEL_S 28 +#define UDMA_CHMAP2_CH22SEL_M 0x0F000000 // uDMA channel 22 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP2_CH22SEL_S 24 +#define UDMA_CHMAP2_CH21SEL_M 0x00F00000 // uDMA channel 21 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP2_CH21SEL_S 20 +#define UDMA_CHMAP2_CH20SEL_M 0x000F0000 // uDMA channel 20 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP2_CH20SEL_S 16 +#define UDMA_CHMAP2_CH19SEL_M 0x0000F000 // uDMA channel 19 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP2_CH19SEL_S 12 +#define UDMA_CHMAP2_CH18SEL_M 0x00000F00 // uDMA channel 18 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP2_CH18SEL_S 8 +#define UDMA_CHMAP2_CH17SEL_M 0x000000F0 // uDMA channel 17 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP2_CH17SEL_S 4 +#define UDMA_CHMAP2_CH16SEL_M 0x0000000F // uDMA channel 16 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP2_CH16SEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the UDMA_CHMAP3 register. +// +//***************************************************************************** +#define UDMA_CHMAP3_CH31SEL_M 0xF0000000 // uDMA channel 31 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP3_CH31SEL_S 28 +#define UDMA_CHMAP3_CH30SEL_M 0x0F000000 // uDMA channel 30 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP3_CH30SEL_S 24 +#define UDMA_CHMAP3_CH29SEL_M 0x00F00000 // uDMA channel 29 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP3_CH29SEL_S 20 +#define UDMA_CHMAP3_CH28SEL_M 0x000F0000 // uDMA channel 28 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP3_CH28SEL_S 16 +#define UDMA_CHMAP3_CH27SEL_M 0x0000F000 // uDMA channel 27 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP3_CH27SEL_S 12 +#define UDMA_CHMAP3_CH26SEL_M 0x00000F00 // uDMA channel 26 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP3_CH26SEL_S 8 +#define UDMA_CHMAP3_CH25SEL_M 0x000000F0 // uDMA channel 25 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP3_CH25SEL_S 4 +#define UDMA_CHMAP3_CH24SEL_M 0x0000000F // uDMA channel 24 source select + // See section titled "Channel + // Assignments" in Micro Direct + // Memory Access chapter. +#define UDMA_CHMAP3_CH24SEL_S 0 + + +#endif // __HW_UDMA_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_udmachctl.h b/bsp/boards/mimsy2-cc2538/headers/hw_udmachctl.h new file mode 100644 index 0000000000..361f19c53e --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_udmachctl.h @@ -0,0 +1,243 @@ +/****************************************************************************** +* Filename: hw_udmachctl.h +* Revised: $Date: 2013-04-12 15:10:54 +0200 (Fri, 12 Apr 2013) $ +* Revision: $Revision: 9735 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_UDMACHCTL_H__ +#define __HW_UDMACHCTL_H__ + +//***************************************************************************** +// +// The following are defines for the UDMACHCTL register offsets. +// +//***************************************************************************** +#define UDMACHCTL_O_SRCENDP 0x00000000 +#define UDMACHCTL_O_DSTENDP 0x00000004 +#define UDMACHCTL_O_CHCTL 0x00000008 + + +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UDMACHCTL_O_SRCENDP register. +// +//***************************************************************************** +#define UDMACHCTL_SRCENDP_ADDR_M \ + 0xFFFFFFFF // Source address end pointer This + // field points to the last address + // of the uDMA transfer source + // (inclusive). If the source + // address is not incrementing (the + // SRCINC field in the DMACHCTL + // register is 0x3), then this + // field points at the source + // location itself (such as a + // peripheral control register). + +#define UDMACHCTL_SRCENDP_ADDR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UDMACHCTL_O_DSTENDP register. +// +//***************************************************************************** +#define UDMACHCTL_DSTENDP_ADDR_M \ + 0xFFFFFFFF // Destination address end pointer + // This field points to the last + // address of the uDMA transfer + // destination (inclusive). If the + // destination address is not + // incrementing (the DSTINC field + // in the DMACHCTL register is + // 0x3), then this field points at + // the destination location itself + // (such as a peripheral control + // register). + +#define UDMACHCTL_DSTENDP_ADDR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// UDMACHCTL_O_CHCTL register. +// +//***************************************************************************** +#define UDMACHCTL_CHCTL_DSTINC_M \ + 0xC0000000 // Destination address increment + // This field configures the + // destination address increment. + // The address increment value must + // be equal or greater than the + // value of the destination size + // (DSTSIZE). 0x0: Byte - Increment + // by 8-bit locations 0x1: + // Half-word - Increment by 16-bit + // locations 0x2: Word - Increment + // by 32-bit locations 0x3: No + // increment - Address remains set + // to the value of the Destination + // address end pointer (DMADSTENDP) + // for the channel. + +#define UDMACHCTL_CHCTL_DSTINC_S 30 +#define UDMACHCTL_CHCTL_DSTSIZE_M \ + 0x30000000 // Destination data size This + // field configures the destination + // item data size. Note: DSTSIZE + // must be the same as SRCSIZE. + // 0x0: Byte - 8-bit data size 0x1: + // Half-word - 16-bit data size + // 0x2: Word - 32-bit data size + // 0x3: Reserved + +#define UDMACHCTL_CHCTL_DSTSIZE_S 28 +#define UDMACHCTL_CHCTL_SRCINC_M \ + 0x0C000000 // Source address increment This + // field configures the source + // address increment. The address + // increment value must be equal or + // greater than the value of the + // source size (SRCSIZE). 0x0: Byte + // - Increment by 8-bit locations + // 0x1: Half-word - Increment by + // 16-bit locations 0x2: Word - + // Increment by 32-bit locations + // 0x3: No increment - Address + // remains set to the value of the + // Source address end pointer + // (DMASRCENDP) for the channel. + +#define UDMACHCTL_CHCTL_SRCINC_S 26 +#define UDMACHCTL_CHCTL_SRCSIZE_M \ + 0x03000000 // Source data size This field + // configures the source item data + // size. Note: SRCSIZE must be the + // same as DSTSIZE. 0x0: Byte - + // 8-bit data size 0x1: Half-word - + // 16-bit data size 0x2: Word - + // 32-bit data size 0x3: Reserved + +#define UDMACHCTL_CHCTL_SRCSIZE_S 24 +#define UDMACHCTL_CHCTL_ARBSIZE_M \ + 0x0003C000 // Arbitration size This field + // configures the number of + // transfers that can occur before + // the uDMA controller + // re-arbitrates. The possible + // arbitration rate configurations + // represent powers of 2 and are + // shown below. 0x0: 1 Transfer - + // Arbitrates after each uDMA + // transfer 0x1: 2 Transfers 0x2: 4 + // Transfers 0x3: 8 Transfers 0x4: + // 16 Transfers 0x5: 32 Transfers + // 0x6: 64 Transfers 0x7: 128 + // Transfers 0x8: 256 Transfers + // 0x9: 512 Transfers 0xA-0xF: 1024 + // Transfers - In this + // configuration, no arbitration + // occurs during the uDMA transfer + // because the maximum transfer + // size is 1024. + +#define UDMACHCTL_CHCTL_ARBSIZE_S 14 +#define UDMACHCTL_CHCTL_XFERSIZE_M \ + 0x00003FF0 // Transfer size (minus 1) This + // field configures the total + // number of items to transfer. The + // value of this field is 1 less + // than the number to transfer + // (value 0 means transfer 1 item). + // The maximum value for this + // 10-bit field is 1023which + // represents a transfer size of + // 1024 items. The transfer size is + // the number of items, not the + // number of bytes, If the data + // size is 32 bits, then this value + // is the number of 32-bit words to + // transfer. The uDMA controller + // updates this field immediately + // before entering the arbitration + // process, so it contrains the + // number of outstanding items that + // is necessary to complete the + // uDMA cycle. + +#define UDMACHCTL_CHCTL_XFERSIZE_S 4 +#define UDMACHCTL_CHCTL_NXTUSEBURST \ + 0x00000008 // Next useburst This field + // controls whether the Useburst + // SET[n] bit is automatically set + // for the last transfer of a + // peripheral scatter-gather + // operation. Normally, for the + // last transfer, if the number of + // remaining items to transfer is + // less than the arbitration size, + // the uDMA controller uses single + // transfers to complete the + // transaction. If this bit is set, + // then the controller uses a burst + // transfer to complete the last + // transfer. + +#define UDMACHCTL_CHCTL_NXTUSEBURST_M \ + 0x00000008 +#define UDMACHCTL_CHCTL_NXTUSEBURST_S 3 +#define UDMACHCTL_CHCTL_XFERMODE_M \ + 0x00000007 // uDMA transfer mode This field + // configures the operating mode of + // the uDMA cycle. Refer to "Micro + // Direct Memory Access - Transfer + // Modes" for a detailed + // explanation of transfer modes. + // Because this register is in + // system RAM, it has no reset + // value. Therefore, this field + // should be initialized to 0 + // before the channel is enabled. + // 0x0: Stop 0x1: Basic 0x2: + // Auto-request 0x3: Ping-pong 0x4: + // Memory scatter-gather 0x5: + // Alternate memory scatter-gather + // 0x6: Peripheral scatter-gather + // 0x7: Alternate peripheral + // scatter-gather + +#define UDMACHCTL_CHCTL_XFERMODE_S 0 + + +#endif // __HW_UDMACHCTL_H__ + diff --git a/bsp/boards/mimsy2-cc2538/headers/hw_usb.h b/bsp/boards/mimsy2-cc2538/headers/hw_usb.h new file mode 100644 index 0000000000..44edc676c4 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/headers/hw_usb.h @@ -0,0 +1,802 @@ +/****************************************************************************** +* Filename: hw_usb.h +* Revised: $Date: 2013-04-30 17:13:44 +0200 (Tue, 30 Apr 2013) $ +* Revision: $Revision: 9943 $ +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __HW_USB_H__ +#define __HW_USB_H__ + +//***************************************************************************** +// +// The following are defines for the USB register offsets. +// +//***************************************************************************** +#define USB_ADDR 0x40089000 // Function address +#define USB_POW 0x40089004 // Power management and control + // register +#define USB_IIF 0x40089008 // Interrupt flags for endpoint 0 + // and IN endpoints 1-5 +#define USB_OIF 0x40089010 // Interrupt flags for OUT + // endpoints 1-5 +#define USB_CIF 0x40089018 // Common USB interrupt flags +#define USB_IIE 0x4008901C // Interrupt enable mask for IN + // endpoints 1-5 and endpoint 0 +#define USB_OIE 0x40089024 // Interrupt enable mask for OUT + // endpoints 1-5 +#define USB_CIE 0x4008902C // Common USB interrupt enable + // mask +#define USB_FRML 0x40089030 // Frame number (low byte) +#define USB_FRMH 0x40089034 // Frame number (high byte) +#define USB_INDEX 0x40089038 // Index register for selecting + // the endpoint status and control + // registers +#define USB_CTRL 0x4008903C // USB peripheral control register +#define USB_MAXI 0x40089040 // Indexed register: For USB_INDEX + // = 1-5: Maximum packet size for + // IN endpoint {1-5} +#define USB_CS0_CSIL 0x40089044 // Indexed register: For USB_INDEX + // = 0: Endpoint 0 control and + // status For USB_INDEX = 1-5: IN + // endpoint {1-5} control and + // status (low byte) +#define USB_CSIH 0x40089048 // Indexed register: For USB_INDEX + // = 1-5: IN endpoint {1-5} control + // and status (high byte) +#define USB_MAXO 0x4008904C // Indexed register: For USB_INDEX + // = 1-5: Maximum packet size for + // OUT endpoint {1-5} +#define USB_CSOL 0x40089050 // Indexed register: For USB_INDEX + // = 1-5: OUT endpoint {1-5} + // control and status (low byte) +#define USB_CSOH 0x40089054 // Indexed register: For USB_INDEX + // = 1-5: OUT endpoint {1-5} + // control and status (high byte) +#define USB_CNT0_CNTL 0x40089058 // Indexed register: For USB_INDEX + // = 0: Number of received bytes in + // the endpoint 0 FIFO For + // USB_INDEX = 1-5: Number of + // received bytes in the OUT + // endpoint {1-5} FIFO (low byte) +#define USB_CNTH 0x4008905C // Indexed register: For USB_INDEX + // = 1-5: Number of received in the + // OUT endpoint {1-5} FIFO (high + // byte) +#define USB_F0 0x40089080 // Endpoint 0 FIFO +#define USB_F1 0x40089088 // IN/OUT endpoint 1 FIFO +#define USB_F2 0x40089090 // IN/OUT endpoint 2 FIFO +#define USB_F3 0x40089098 // IN/OUT endpoint 3 FIFO +#define USB_F4 0x400890A0 // IN/OUT endpoint 4 FIFO +#define USB_F5 0x400890A8 // IN/OUT endpoint 5 FIFO + + +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_ADDR register. +// +//***************************************************************************** +#define USB_ADDR_UPDATE 0x00000080 // This bit is set by hardware + // when writing to this register, + // and is cleared by hardware when + // the new address becomes + // effective. +#define USB_ADDR_UPDATE_M 0x00000080 +#define USB_ADDR_UPDATE_S 7 +#define USB_ADDR_USBADDR_M 0x0000007F // Device address. The address + // shall be updated upon successful + // completion of the status stage + // of the SET_ADDRESS request. +#define USB_ADDR_USBADDR_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_POW register. +// +//***************************************************************************** +#define USB_POW_ISOWAITSOF 0x00000080 // For isochronous mode IN + // endpoints: When set, the USB + // controller will wait for an SOF + // token from the time + // USB_CSIL.INPKTRDY is set before + // sending the packet. If an IN + // token is received before an SOF + // token, then a zero length data + // packet will be sent. +#define USB_POW_ISOWAITSOF_M 0x00000080 +#define USB_POW_ISOWAITSOF_S 7 +#define USB_POW_RST 0x00000008 // Indicates that reset signaling + // is present on the bus +#define USB_POW_RST_M 0x00000008 +#define USB_POW_RST_S 3 +#define USB_POW_RESUME 0x00000004 // Drives resume signaling for + // remote wakeup According to the + // USB Specification, the resume + // signal must be held active for + // at least 1 ms and no more than + // 15 ms. It is recommended to keep + // this bit set for approximately + // 10 ms. +#define USB_POW_RESUME_M 0x00000004 +#define USB_POW_RESUME_S 2 +#define USB_POW_SUSPEND 0x00000002 // Indicates entry into suspend + // mode Suspend mode must be + // enabled by setting + // USB_POW.SUSPENDEN Software + // clears this bit by reading the + // USB_CIF register or by asserting + // USB_POW.RESUME +#define USB_POW_SUSPEND_M 0x00000002 +#define USB_POW_SUSPEND_S 1 +#define USB_POW_SUSPENDEN 0x00000001 // Enables detection of and entry + // into suspend mode. +#define USB_POW_SUSPENDEN_M 0x00000001 +#define USB_POW_SUSPENDEN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_IIF register. +// +//***************************************************************************** +#define USB_IIF_INEP5IF 0x00000020 // Interrupt flag for IN endpoint + // 5 Cleared by hardware when read +#define USB_IIF_INEP5IF_M 0x00000020 +#define USB_IIF_INEP5IF_S 5 +#define USB_IIF_INEP4IF 0x00000010 // Interrupt flag for IN endpoint + // 4 Cleared by hardware when read +#define USB_IIF_INEP4IF_M 0x00000010 +#define USB_IIF_INEP4IF_S 4 +#define USB_IIF_INEP3IF 0x00000008 // Interrupt flag for IN endpoint + // 3 Cleared by hardware when read +#define USB_IIF_INEP3IF_M 0x00000008 +#define USB_IIF_INEP3IF_S 3 +#define USB_IIF_INEP2IF 0x00000004 // Interrupt flag for IN endpoint + // 2 Cleared by hardware when read +#define USB_IIF_INEP2IF_M 0x00000004 +#define USB_IIF_INEP2IF_S 2 +#define USB_IIF_INEP1IF 0x00000002 // Interrupt flag for IN endpoint + // 1 Cleared by hardware when read +#define USB_IIF_INEP1IF_M 0x00000002 +#define USB_IIF_INEP1IF_S 1 +#define USB_IIF_EP0IF 0x00000001 // Interrupt flag for endpoint 0 + // Cleared by hardware when read +#define USB_IIF_EP0IF_M 0x00000001 +#define USB_IIF_EP0IF_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_OIF register. +// +//***************************************************************************** +#define USB_OIF_OUTEP5IF 0x00000020 // Interrupt flag for OUT endpoint + // 5 Cleared by hardware when read +#define USB_OIF_OUTEP5IF_M 0x00000020 +#define USB_OIF_OUTEP5IF_S 5 +#define USB_OIF_OUTEP4IF 0x00000010 // Interrupt flag for OUT endpoint + // 4 Cleared by hardware when read +#define USB_OIF_OUTEP4IF_M 0x00000010 +#define USB_OIF_OUTEP4IF_S 4 +#define USB_OIF_OUTEP3IF 0x00000008 // Interrupt flag for OUT endpoint + // 3 Cleared by hardware when read +#define USB_OIF_OUTEP3IF_M 0x00000008 +#define USB_OIF_OUTEP3IF_S 3 +#define USB_OIF_OUTEP2IF 0x00000004 // Interrupt flag for OUT endpoint + // 2 Cleared by hardware when read +#define USB_OIF_OUTEP2IF_M 0x00000004 +#define USB_OIF_OUTEP2IF_S 2 +#define USB_OIF_OUTEP1IF 0x00000002 // Interrupt flag for OUT endpoint + // 1 Cleared by hardware when read +#define USB_OIF_OUTEP1IF_M 0x00000002 +#define USB_OIF_OUTEP1IF_S 1 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_CIF register. +// +//***************************************************************************** +#define USB_CIF_SOFIF 0x00000008 // Start-of-frame interrupt flag + // Cleared by hardware when read +#define USB_CIF_SOFIF_M 0x00000008 +#define USB_CIF_SOFIF_S 3 +#define USB_CIF_RSTIF 0x00000004 // Reset interrupt flag Cleared by + // hardware when read +#define USB_CIF_RSTIF_M 0x00000004 +#define USB_CIF_RSTIF_S 2 +#define USB_CIF_RESUMEIF 0x00000002 // Resume interrupt flag Cleared + // by hardware when read +#define USB_CIF_RESUMEIF_M 0x00000002 +#define USB_CIF_RESUMEIF_S 1 +#define USB_CIF_SUSPENDIF 0x00000001 // Suspend interrupt flag Cleared + // by hardware when read +#define USB_CIF_SUSPENDIF_M 0x00000001 +#define USB_CIF_SUSPENDIF_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_IIE register. +// +//***************************************************************************** +#define USB_IIE_INEP5IE 0x00000020 // Interrupt enable for IN + // endpoint 5 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_IIE_INEP5IE_M 0x00000020 +#define USB_IIE_INEP5IE_S 5 +#define USB_IIE_INEP4IE 0x00000010 // Interrupt enable for IN + // endpoint 4 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_IIE_INEP4IE_M 0x00000010 +#define USB_IIE_INEP4IE_S 4 +#define USB_IIE_INEP3IE 0x00000008 // Interrupt enable for IN + // endpoint 3 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_IIE_INEP3IE_M 0x00000008 +#define USB_IIE_INEP3IE_S 3 +#define USB_IIE_INEP2IE 0x00000004 // Interrupt enable for IN + // endpoint 2 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_IIE_INEP2IE_M 0x00000004 +#define USB_IIE_INEP2IE_S 2 +#define USB_IIE_INEP1IE 0x00000002 // Interrupt enable for IN + // endpoint 1 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_IIE_INEP1IE_M 0x00000002 +#define USB_IIE_INEP1IE_S 1 +#define USB_IIE_EP0IE 0x00000001 // Interrupt enable for endpoint 0 + // 0: Interrupt disabled 1: + // Interrupt enabled +#define USB_IIE_EP0IE_M 0x00000001 +#define USB_IIE_EP0IE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_OIE register. +// +//***************************************************************************** +#define USB_OIE_reserved8_M 0x000000C0 // Reserved +#define USB_OIE_reserved8_S 6 +#define USB_OIE_OUTEP5IE 0x00000020 // Interrupt enable for OUT + // endpoint 5 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_OIE_OUTEP5IE_M 0x00000020 +#define USB_OIE_OUTEP5IE_S 5 +#define USB_OIE_OUTEP4IE 0x00000010 // Interrupt enable for OUT + // endpoint 4 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_OIE_OUTEP4IE_M 0x00000010 +#define USB_OIE_OUTEP4IE_S 4 +#define USB_OIE_OUTEP3IE 0x00000008 // Interrupt enable for OUT + // endpoint 3 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_OIE_OUTEP3IE_M 0x00000008 +#define USB_OIE_OUTEP3IE_S 3 +#define USB_OIE_OUTEP2IE 0x00000004 // Interrupt enable for OUT + // endpoint 2 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_OIE_OUTEP2IE_M 0x00000004 +#define USB_OIE_OUTEP2IE_S 2 +#define USB_OIE_OUTEP1IE 0x00000002 // Interrupt enable for OUT + // endpoint 1 0: Interrupt disabled + // 1: Interrupt enabled +#define USB_OIE_OUTEP1IE_M 0x00000002 +#define USB_OIE_OUTEP1IE_S 1 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_CIE register. +// +//***************************************************************************** +#define USB_CIE_SOFIE 0x00000008 // Start-of-frame interrupt enable + // 0: Interrupt disabled 1: + // Interrupt enabled +#define USB_CIE_SOFIE_M 0x00000008 +#define USB_CIE_SOFIE_S 3 +#define USB_CIE_RSTIE 0x00000004 // Reset interrupt enable 0: + // Interrupt disabled 1: Interrupt + // enabled +#define USB_CIE_RSTIE_M 0x00000004 +#define USB_CIE_RSTIE_S 2 +#define USB_CIE_RESUMEIE 0x00000002 // Resume interrupt enable 0: + // Interrupt disabled 1: Interrupt + // enabled +#define USB_CIE_RESUMEIE_M 0x00000002 +#define USB_CIE_RESUMEIE_S 1 +#define USB_CIE_SUSPENDIE 0x00000001 // Suspend interrupt enable 0: + // Interrupt disabled 1: Interrupt + // enabled +#define USB_CIE_SUSPENDIE_M 0x00000001 +#define USB_CIE_SUSPENDIE_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_FRML register. +// +//***************************************************************************** +#define USB_FRML_FRAMEL_M 0x000000FF // Bits 7:0 of the 11-bit frame + // number The frame number is only + // updated upon successful + // reception of SOF tokens +#define USB_FRML_FRAMEL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_FRMH register. +// +//***************************************************************************** +#define USB_FRMH_FRAMEH_M 0x00000007 // Bits 10:8 of the 11-bit frame + // number The frame number is only + // updated upon successful + // reception of SOF tokens +#define USB_FRMH_FRAMEH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_INDEX register. +// +//***************************************************************************** +#define USB_INDEX_USBINDEX_M 0x0000000F // Index of the currently selected + // endpoint The index is set to 0 + // to enable access to endpoint 0 + // control and status registers The + // index is set to 1, 2, 3, 4 or 5 + // to enable access to IN/OUT + // endpoint 1, 2, 3, 4 or 5 control + // and status registers, + // respectively +#define USB_INDEX_USBINDEX_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_CTRL register. +// +//***************************************************************************** +#define USB_CTRL_PLLLOCKED 0x00000080 // PLL lock status. The PLL is + // locked when USB_CTRL.PLLLOCKED + // is 1. +#define USB_CTRL_PLLLOCKED_M 0x00000080 +#define USB_CTRL_PLLLOCKED_S 7 +#define USB_CTRL_PLLEN 0x00000002 // 48 MHz USB PLL enable When this + // bit is set, the 48 MHz PLL is + // started. Software must avoid + // access to other USB registers + // before the PLL has locked; that + // is, USB_CTRL.PLLLOCKED is 1. + // This bit can be set only when + // USB_CTRL.USBEN is 1. The PLL + // must be disabled before entering + // PM1 when suspended, and must be + // re-enabled when resuming + // operation. +#define USB_CTRL_PLLEN_M 0x00000002 +#define USB_CTRL_PLLEN_S 1 +#define USB_CTRL_USBEN 0x00000001 // USB enable The USB controller + // is reset when this bit is + // cleared +#define USB_CTRL_USBEN_M 0x00000001 +#define USB_CTRL_USBEN_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_MAXI register. +// +//***************************************************************************** +#define USB_MAXI_USBMAXI_M 0x000000FF // Maximum packet size, in units + // of 8 bytes, for the selected IN + // endpoint The value of this + // register should match the + // wMaxPacketSize field in the + // standard endpoint descriptor for + // the endpoint. The value must not + // exceed the available memory. +#define USB_MAXI_USBMAXI_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_CS0_CSIL register. +// +//***************************************************************************** +#define USB_CS0_CSIL_CLROUTPKTRDY_or_CLRDATATOG \ + 0x00000040 // USB_CS0.CLROUTPKTRDY [RW]: + // Software sets this bit to clear + // the USB_CS0.OUTPKTRDY bit. It is + // cleared automatically. + // USB_CSIL.CLRDATATOG [RW]: + // Software sets this bit to reset + // the IN endpoint data toggle to + // 0. + +#define USB_CS0_CSIL_CLROUTPKTRDY_or_CLRDATATOG_M \ + 0x00000040 +#define USB_CS0_CSIL_CLROUTPKTRDY_or_CLRDATATOG_S 6 +#define USB_CS0_CSIL_SENDSTALL_or_SENTSTALL \ + 0x00000020 // USB_CS0.SENDSTALL [RW]: + // Software sets this bit to + // terminate the current + // transaction with a STALL + // handshake. The bit is cleared + // automatically when the STALL + // handshake has been transmitted. + // USB_CSIL.SENTSTALL [RW]: For + // bulk/interrupt mode IN + // endpoints: This bit is set when + // a STALL handshake is + // transmitted. The FIFO is flushed + // and the USB_CSIL.INPKTRDY bit + // cleared. Software should clear + // this bit. + +#define USB_CS0_CSIL_SENDSTALL_or_SENTSTALL_M \ + 0x00000020 +#define USB_CS0_CSIL_SENDSTALL_or_SENTSTALL_S 5 +#define USB_CS0_CSIL_SETUPEND_or_SENDSTALL \ + 0x00000010 // USB_CS0.SETUPEND [RO]: This bit + // is set when a control + // transaction ends before the + // USB_CS0.DATAEND bit has been + // set. An interrupt is generated + // and the FIFO flushed at this + // time. Software clears this bit + // by setting USB_CS0.CLRSETUPEND. + // CSIL.SENDSTALL [RW]: For + // bulk/interrupt mode IN + // endpoints: Software sets this + // bit to issue a STALL handshake. + // Software clears this bit to + // terminate the stall condition. + +#define USB_CS0_CSIL_SETUPEND_or_SENDSTALL_M \ + 0x00000010 +#define USB_CS0_CSIL_SETUPEND_or_SENDSTALL_S 4 +#define USB_CS0_CSIL_DATAEND_or_FLUSHPACKET \ + 0x00000008 // USB_CS0.DATAEND [RW]: This bit + // is used to signal the end of the + // data stage, and must be set: 1. + // When the last data packet is + // loaded and USB_CS0.INPKTRDY is + // set. 2. When the last data + // packet is unloaded and + // USB_CS0.CLROUTPKTRDY is set. 3. + // When USB_CS0.INPKTRDY is set to + // send a zero-length packet. The + // USB controller clears this bit + // automatically. + // USB_CSIL.FLUSHPACKET [RW]: + // Software sets this bit to flush + // the next packet to be + // transmitted from the IN endpoint + // FIFO. The FIFO pointer is reset + // and the USB_CSIL.INPKTRDY bit is + // cleared. Note: If the FIFO + // contains two packets, + // USB_CSIL.FLUSHPACKET will need + // to be set twice to completely + // clear the FIFO. + +#define USB_CS0_CSIL_DATAEND_or_FLUSHPACKET_M \ + 0x00000008 +#define USB_CS0_CSIL_DATAEND_or_FLUSHPACKET_S 3 +#define USB_CS0_CSIL_SENTSTALL_or_UNDERRUN \ + 0x00000004 // USB_CS0.SENTSTALL [RW]: This + // bit is set when a STALL + // handshake is sent. An interrupt + // is generated is generated when + // this bit is set. Software must + // clear this bit. + // USB_CSIL.UNDERRUN [RW]: In + // isochronous mode, this bit is + // set when a zero length data + // packet is sent after receiving + // an IN token with + // USB_CSIL.INPKTRDY not set. In + // bulk/interrupt mode, this bit is + // set when a NAK is returned in + // response to an IN token. + // Software should clear this bit. + +#define USB_CS0_CSIL_SENTSTALL_or_UNDERRUN_M \ + 0x00000004 +#define USB_CS0_CSIL_SENTSTALL_or_UNDERRUN_S 2 +#define USB_CS0_CSIL_INPKTRDY_or_PKTPRESENT \ + 0x00000002 // USB_CS0. INPKTRDY [RW]: + // Software sets this bit after + // loading a data packet into the + // endpoint 0 FIFO. It is cleared + // automatically when the data + // packet has been transmitted. An + // interrupt is generated when the + // bit is cleared. + // USB_CSIL.PKTPRESENT [RO]: This + // bit is set when there is at + // least one packet in the IN + // endpoint FIFO. + +#define USB_CS0_CSIL_INPKTRDY_or_PKTPRESENT_M \ + 0x00000002 +#define USB_CS0_CSIL_INPKTRDY_or_PKTPRESENT_S 1 +#define USB_CS0_CSIL_OUTPKTRDY_or_INPKTRDY \ + 0x00000001 // USB_CS0.OUTPKTRDY [RO]: + // Endpoint 0 data packet received + // An interrupt request (EP0) is + // generated if the interrupt is + // enabled. Software must read the + // endpoint 0 FIFO empty, and clear + // this bit by setting + // USB_CS0.CLROUTPKTRDY + // USB_CSIL.INPKTRDY [RW]: IN + // endpoint {1-5} packet transfer + // pending Software sets this bit + // after loading a data packet into + // the FIFO. It is cleared + // automatically when a data packet + // has been transmitted. An + // interrupt is generated (if + // enabled) when the bit is + // cleared. When using + // double-buffering, the bit is + // cleared immediately if the other + // FIFO is empty. + +#define USB_CS0_CSIL_OUTPKTRDY_or_INPKTRDY_M \ + 0x00000001 +#define USB_CS0_CSIL_OUTPKTRDY_or_INPKTRDY_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_CSIH register. +// +//***************************************************************************** +#define USB_CSIH_AUTISET 0x00000080 // If set by software, the + // USB_CSIL.INPKTRDY bit is + // automatically set when a data + // packet of maximum size + // (specified by USBMAXI) is loaded + // into the IN endpoint FIFO. If a + // packet of less than the maximum + // packet size is loaded, then + // USB_CSIL.INPKTRDY will have to + // be set manually. +#define USB_CSIH_AUTISET_M 0x00000080 +#define USB_CSIH_AUTISET_S 7 +#define USB_CSIH_ISO 0x00000040 // Selects IN endpoint type: 0: + // Bulk/interrupt 1: Isochronous +#define USB_CSIH_ISO_M 0x00000040 +#define USB_CSIH_ISO_S 6 +#define USB_CSIH_FORCEDATATOG 0x00000008 // Software sets this bit to force + // the IN endpoint's data toggle to + // switch after each data packet is + // sent regardless of whether an + // ACK was received. This can be + // used by interrupt IN endpoints + // which are used to communicate + // rate feedback for isochronous + // endpoints. +#define USB_CSIH_FORCEDATATOG_M 0x00000008 +#define USB_CSIH_FORCEDATATOG_S 3 +#define USB_CSIH_INDBLBUF 0x00000001 // IN endpoint FIFO + // double-buffering enable: 0: + // Double buffering disabled 1: + // Double buffering enabled +#define USB_CSIH_INDBLBUF_M 0x00000001 +#define USB_CSIH_INDBLBUF_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_MAXO register. +// +//***************************************************************************** +#define USB_MAXO_USBMAXO_M 0x000000FF // Maximum packet size, in units + // of 8 bytes, for the selected OUT + // endpoint The value of this + // register should match the + // wMaxPacketSize field in the + // standard endpoint descriptor for + // the endpoint. The value must not + // exceed the available memory. +#define USB_MAXO_USBMAXO_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_CSOL register. +// +//***************************************************************************** +#define USB_CSOL_CLRDATATOG 0x00000080 // Software sets this bit to reset + // the endpoint data toggle to 0. +#define USB_CSOL_CLRDATATOG_M 0x00000080 +#define USB_CSOL_CLRDATATOG_S 7 +#define USB_CSOL_SENTSTALL 0x00000040 // This bit is set when a STALL + // handshake is transmitted. An + // interrupt is generated when this + // bit is set. Software should + // clear this bit. +#define USB_CSOL_SENTSTALL_M 0x00000040 +#define USB_CSOL_SENTSTALL_S 6 +#define USB_CSOL_SENDSTALL 0x00000020 // For bulk/interrupt mode OUT + // endpoints: Software sets this + // bit to issue a STALL handshake. + // Software clears this bit to + // terminate the stall condition. +#define USB_CSOL_SENDSTALL_M 0x00000020 +#define USB_CSOL_SENDSTALL_S 5 +#define USB_CSOL_FLUSHPACKET 0x00000010 // Software sets this bit to flush + // the next packet to be read from + // the endpoint OUT FIFO. Note: If + // the FIFO contains two packets, + // USB_CSOL.FLUSHPACKET will need + // to be set twice to completely + // clear the FIFO. +#define USB_CSOL_FLUSHPACKET_M 0x00000010 +#define USB_CSOL_FLUSHPACKET_S 4 +#define USB_CSOL_DATAERROR 0x00000008 // For isochronous mode OUT + // endpoints: This bit is set when + // USB_CSOL.OUTPKTRDY is set if the + // data packet has a CRC or + // bit-stuff error. It is cleared + // automatically when + // USB_CSOL.OUTPKTRDY is cleared. +#define USB_CSOL_DATAERROR_M 0x00000008 +#define USB_CSOL_DATAERROR_S 3 +#define USB_CSOL_OVERRUN 0x00000004 // For isochronous mode OUT + // endpoints: This bit is set when + // an OUT packet cannot be loaded + // into the OUT endpoint FIFO. + // Firmware should clear this bit. +#define USB_CSOL_OVERRUN_M 0x00000004 +#define USB_CSOL_OVERRUN_S 2 +#define USB_CSOL_FIFOFULL 0x00000002 // This bit is set when no more + // packets can be loaded into the + // OUT endpoint FIFO. +#define USB_CSOL_FIFOFULL_M 0x00000002 +#define USB_CSOL_FIFOFULL_S 1 +#define USB_CSOL_OUTPKTRDY 0x00000001 // This bit is set when a data + // packet has been received. + // Software should clear this bit + // when the packet has been + // unloaded from the OUT endpoint + // FIFO. An interrupt is generated + // when the bit is set. +#define USB_CSOL_OUTPKTRDY_M 0x00000001 +#define USB_CSOL_OUTPKTRDY_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_CSOH register. +// +//***************************************************************************** +#define USB_CSOH_AUTOCLEAR 0x00000080 // If software sets this bit, the + // USB_CSOL.OUTPKTRDY bit will be + // automatically cleared when a + // packet of maximum size + // (specified by USB_MAXO) has been + // unloaded from the OUT FIFO. When + // packets of less than the maximum + // packet size are unloaded, + // USB_CSOL.OUTPKTRDY will have to + // be cleared manually. +#define USB_CSOH_AUTOCLEAR_M 0x00000080 +#define USB_CSOH_AUTOCLEAR_S 7 +#define USB_CSOH_ISO 0x00000040 // Selects OUT endpoint type: 0: + // Bulk/interrupt 1: Isochronous +#define USB_CSOH_ISO_M 0x00000040 +#define USB_CSOH_ISO_S 6 +#define USB_CSOH_OUTDBLBUF 0x00000001 // OUT endpoint FIFO + // double-buffering enable: 0: + // Double buffering disabled 1: + // Double buffering enabled +#define USB_CSOH_OUTDBLBUF_M 0x00000001 +#define USB_CSOH_OUTDBLBUF_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the +// USB_CNT0_CNTL register. +// +//***************************************************************************** +#define USB_CNT0_CNTL_FIFOCNT_or_FIFOCNTL_M \ + 0x000000FF // USB_CS0.FIFOCNT (USBINDEX = 0) + // [RO]: Number of bytes received + // in the packet in the endpoint 0 + // FIFO Valid only when + // USB_CS0.OUTPKTRDY is set + // USB_CSIL.FIFOCNTL (USBINDEX = 1 + // to 5) [RW]: Bits 7:0 of the of + // the number of bytes received in + // the packet in the OUT endpoint + // {1-5} FIFO Valid only when + // USB_CSOL.OUTPKTRDY is set + +#define USB_CNT0_CNTL_FIFOCNT_or_FIFOCNTL_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_CNTH register. +// +//***************************************************************************** +#define USB_CNTH_FIFOCNTH_M 0x00000007 // Bits 10:8 of the of the number + // of bytes received in the packet + // in the OUT endpoint {1-5} FIFO + // Valid only when + // USB_CSOL.OUTPKTRDY is set +#define USB_CNTH_FIFOCNTH_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_F0 register. +// +//***************************************************************************** +#define USB_F0_USBF0_M 0x000000FF // Endpoint 0 FIFO Reading this + // register unloads one byte from + // the endpoint 0 FIFO. Writing to + // this register loads one byte + // into the endpoint 0 FIFO. The + // FIFO memory for EP0 is used for + // incoming and outgoing data + // packets. +#define USB_F0_USBF0_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_F1 register. +// +//***************************************************************************** +#define USB_F1_USBF1_M 0x000000FF // Endpoint 1 FIFO register + // Reading this register unloads + // one byte from the EP1 OUT FIFO. + // Writing to this register loads + // one byte into the EP1 IN FIFO. +#define USB_F1_USBF1_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_F2 register. +// +//***************************************************************************** +#define USB_F2_USBF2_M 0x000000FF // Endpoint 2 FIFO register + // Reading this register unloads + // one byte from the EP2 OUT FIFO. + // Writing to this register loads + // one byte into the EP2 IN FIFO. +#define USB_F2_USBF2_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_F3 register. +// +//***************************************************************************** +#define USB_F3_USBF3_M 0x000000FF // Endpoint 3 FIFO register + // Reading this register unloads + // one byte from the EP3 OUT FIFO. + // Writing to this register loads + // one byte into the EP3 IN FIFO. +#define USB_F3_USBF3_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_F4 register. +// +//***************************************************************************** +#define USB_F4_USBF4_M 0x000000FF // Endpoint 4 FIFO register + // Reading this register unloads + // one byte from the EP4 OUT FIFO. + // Writing to this register loads + // one byte into the EP4 IN FIFO. +#define USB_F4_USBF4_S 0 +//***************************************************************************** +// +// The following are defines for the bit fields in the USB_F5 register. +// +//***************************************************************************** +#define USB_F5_USBF5_M 0x000000FF // Endpoint 5 FIFO register + // Reading this register unloads + // one byte from the EP5 OUT FIFO. + // Writing to this register loads + // one byte into the EP5 IN FIFO. +#define USB_F5_USBF5_S 0 + + +#endif // __HW_USB_H__ + diff --git a/bsp/boards/mimsy2-cc2538/heading_from_gyro.h b/bsp/boards/mimsy2-cc2538/heading_from_gyro.h new file mode 100644 index 0000000000..b73993f57e --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/heading_from_gyro.h @@ -0,0 +1,33 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef _HEADING_FROM_GYRO_H_ +#define _HEADING_FROM_GYRO_H_ +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + inv_error_t inv_enable_heading_from_gyro(void); + inv_error_t inv_disable_heading_from_gyro(void); + void inv_init_heading_from_gyro(void); + inv_error_t inv_start_heading_from_gyro(void); + inv_error_t inv_stop_heading_from_gyro(void); + +#ifdef __cplusplus +} +#endif + + +#endif /* _HEADING_FROM_GYRO_H_ */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/i2c.c b/bsp/boards/mimsy2-cc2538/i2c.c new file mode 100644 index 0000000000..b202cfe332 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/i2c.c @@ -0,0 +1,203 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description:CC2538-specific definition of the "i2c" bsp module. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +//=========================== define ========================================== + +#define I2C_PERIPHERAL ( SYS_CTRL_PERIPH_I2C ) +#define I2C_BASE ( GPIO_D_BASE ) +#define I2C_SCL ( GPIO_PIN_4 ) +#define I2C_SDA ( GPIO_PIN_5 ) +#define I2C_BAUDRATE ( 400000 ) +#define I2C_MAX_DELAY_US ( 1000000 ) + + +//=========================== variables ======================================= + + +//=========================== prototypes ====================================== + +extern uint32_t board_timer_get(void); +extern bool board_timer_expired(uint32_t future); + +//=========================== public ========================================== + +void i2c_init(void) { + bool status; + + // Enable peripheral except in deep sleep modes (e.g. LPM1, LPM2, LPM3) + SysCtrlPeripheralEnable(I2C_PERIPHERAL); + SysCtrlPeripheralSleepEnable(I2C_PERIPHERAL); + SysCtrlPeripheralDeepSleepDisable(I2C_PERIPHERAL); + + // Reset peripheral previous to configuring it + SysCtrlPeripheralReset(I2C_PERIPHERAL); + + // Configure the SCL pin + GPIOPinTypeI2C(I2C_BASE, I2C_SCL); + IOCPadConfigSet(I2C_BASE, I2C_SCL,IOC_OVERRIDE_PUE); // enables pins as outputs, necessary for this code to work correctly + + IOCPinConfigPeriphInput(I2C_BASE, I2C_SCL, IOC_I2CMSSCL); + IOCPinConfigPeriphOutput(I2C_BASE, I2C_SCL, IOC_MUX_OUT_SEL_I2C_CMSSCL); + + // Configure the SDA pin + GPIOPinTypeI2C(I2C_BASE, I2C_SDA); + IOCPadConfigSet(I2C_BASE, I2C_SDA,IOC_OVERRIDE_PUE); // enables pins as outputs, necessary for this code to work correctly + IOCPinConfigPeriphInput(I2C_BASE, I2C_SDA, IOC_I2CMSSDA); + IOCPinConfigPeriphOutput(I2C_BASE, I2C_SDA, IOC_MUX_OUT_SEL_I2C_CMSSDA); + + // Configure the I2C clock + status = (I2C_BAUDRATE == 400000 ? true : false); + I2CMasterInitExpClk(SysCtrlClockGet(), status); + + // Enable the I2C module as master + I2CMasterEnable(); +} + +bool i2c_read_byte(uint8_t address, uint8_t* byte) { + uint32_t future = I2C_MAX_DELAY_US; + + // Receive operation + I2CMasterSlaveAddrSet(address, true); + + // Single receive operation + I2CMasterControl(I2C_MASTER_CMD_SINGLE_RECEIVE); + + // Calculate timeout + future += board_timer_get(); + + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Update timeout status and return if expired + if (board_timer_expired(future)) return false; + } + + // Read data from I2C + *byte = I2CMasterDataGet(); + + // Return status + return true; +} + + +uint32_t i2c_read_bytes(uint8_t address, uint8_t* buffer, uint32_t length) { + uint32_t future = I2C_MAX_DELAY_US; + + // Receive operation + I2CMasterSlaveAddrSet(address, true); + + // Multiple receive operation + I2CMasterControl(I2C_MASTER_CMD_BURST_RECEIVE_START); + + // Calculate timeout + future += board_timer_get(); + + // Iterate overall all bytes + while (length) { + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Update timeout status and return if expired + if (board_timer_expired(future)) return length; + } + + // Read data from I2C + *buffer++ = I2CMasterDataGet(); + + + // Check if it's the last byte + if (length == 1) I2CMasterControl(I2C_MASTER_CMD_BURST_RECEIVE_FINISH); + else I2CMasterControl(I2C_MASTER_CMD_BURST_RECEIVE_CONT); + length--; + } + + // Return bytes read + + return length; +} + +bool i2c_write_byte(uint8_t address, uint8_t byte) { + uint32_t future = I2C_MAX_DELAY_US; + + // Transmit operation + I2CMasterSlaveAddrSet(address, false); + + // Write byte to I2C buffer + I2CMasterDataPut(byte); + + // Single transmit operation + I2CMasterControl(I2C_MASTER_CMD_SINGLE_SEND); + + // Calculate timeout + future += board_timer_get(); + + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Check timeout status and return if expired + if (board_timer_expired(future)) return false; + } + + return true; +} + +uint32_t i2c_write_bytes(uint8_t address, uint8_t* buffer, uint32_t length) { + uint32_t future = I2C_MAX_DELAY_US; + + // Transmit operation + I2CMasterSlaveAddrSet(address, false); + + // Write byte to I2C buffer + I2CMasterDataPut(*buffer++); + length--; + + // Multiple transmit operation + I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_START); + + // Calculate timeout + future += board_timer_get(); + + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Check timeout status and return if expired + if (board_timer_expired(future)) return length; + } + + // Iterate overall all bytes + while (length) { + // Write byte to I2C buffer + I2CMasterDataPut(*buffer++); + + // Check if it's the last byte + if (length == 1) I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_FINISH); + else I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_CONT); + + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Check timeout status and return if expired + if (board_timer_expired(future)) return length; + } + + // Update the length + length--; + } + + // Return bytes written + return length; +} + +//=========================== private ========================================= + diff --git a/bsp/boards/mimsy2-cc2538/i2c_mimsy.c b/bsp/boards/mimsy2-cc2538/i2c_mimsy.c new file mode 100644 index 0000000000..f4050f7645 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/i2c_mimsy.c @@ -0,0 +1,155 @@ +/** + * Author: Brian Kilberg (bkilberg@berkeley.edu) + Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: October 2017 + * Description:Mimsy-CC2538-specific definition of the "i2c" bsp module. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//=========================== define ========================================== + +#define I2C_PERIPHERAL ( SYS_CTRL_PERIPH_I2C ) +#define I2C_BASE ( GPIO_D_BASE ) +#define I2C_SCL ( GPIO_PIN_4 ) +#define I2C_SDA ( GPIO_PIN_5 ) +#define I2C_BAUDRATE ( 400000 ) +#define I2C_MAX_DELAY_US ( 1000000 ) + +//=========================== variables ======================================= + + +//=========================== prototypes ====================================== + + uint32_t board_timer_get(void); + bool board_timer_expired(uint32_t future); +bool board_timer_expired(uint32_t future); +//=========================== public ========================================== +/** + * Timer runs at 32 MHz and is 32-bit wide + * The timer is divided by 32, whichs gives a 1 microsecond ticks + */ +/* +void board_timer_init(void) { + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT2); + + // Configure the timer + TimerConfigure(GPTIMER2_BASE, GPTIMER_CFG_PERIODIC_UP); + + // Enable the timer + TimerEnable(GPTIMER2_BASE, GPTIMER_BOTH); +} + +/** + * Returns the current value of the timer + * The timer is divided by 32, whichs gives a 1 microsecond ticks + */ +/* +uint32_t board_timer_get(void) { + uint32_t current; + + current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; + + return current; +} +*/ +/** + * Returns true if the timer has expired + * The timer is divided by 32, whichs gives a 1 microsecond ticks + */ +/* +bool board_timer_expired(uint32_t future) { + uint32_t current; + int32_t remaining; + + current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; + + remaining = (int32_t) (future - current); + + if (remaining > 0) { + return false; + } else { + return true; + } +} +*/ + +extern void delay_ms(uint32_t delay){ + uint32_t current=board_timer_get(); + uint32_t timeout=(current*32+delay*1000*32)/32; + if (timeout>current){ //executes of timeout time is bigger than current time + while(board_timer_get()timeout){ //delay until overflow + + } + while(board_timer_get() +//#include "bsp.h" +//#include "bsp_led.h" +#include "gptimer.h" +#include "sys_ctrl.h" +#include "hw_gptimer.h" +#include "hw_ints.h" +#include "gpio.h" +#include "interrupt.h" +//#include "led.h" +#include "hw_memmap.h" +#include "hw_gpio.h" +#include "ioc.h" +#include "inchworm.h" + +/*GLOBALS +*/ +volatile uint32_t inchwormTimer=0; +volatile uint32_t phaseTimer=0; +volatile uint32_t stepCountList[16]; +volatile bool actuating=false; +volatile uint32_t stepTargetList[16]; +volatile uint32_t timerIntA; +volatile uint32_t timerIntB; +volatile bool activeDriveList[16]; +volatile uint32_t motorsNum=0; +volatile uint32_t startSecondTimer=false; +InchwormMotor motorList[16]; +uint32_t value; +/****************************************************************************** +* DEFINES +*/ +#define GP4 +#define FREQ_CNT SysCtrlClockGet()/frequency +#define OVERLAP_MATCH (100-dutycycle)*SysCtrlClockGet()/frequency/100 + + + +/********************************************************************************* +*STRUCTURES +*/ + + +/****************************************************************************** +* FUNCTIONS +*/ +void +PwmTimerAIntHandler(void) +{ + // + // Clear the timer interrupt flag. + // + TimerIntClear(inchwormTimer, GPTIMER_CAPA_EVENT ); +// mimsyLedToggle(GPIO_PIN_4); + + + //optimize this for loop, it think it will be a bit much + for(uint8_t i=0;i=stepTargetList[i]){ + stepCountList[i]=0; + activeDriveList[i]=false; + inchwormHold(motorList[i]); + } + } + } + +} +void +PwmTimerBIntHandler(void) +{ + // + // Clear the timer interrupt flag. + // + TimerIntClear(inchwormTimer, GPTIMER_CAPB_EVENT); + // mimsyLedToggle(GPIO_PIN_7); + + + + + +} +void +PhaseTimerAIntHandler(void) +{ + TimerIntClear(phaseTimer, GPTIMER_TIMA_TIMEOUT|GPTIMER_TIMB_TIMEOUT); + startSecondTimer=true; +} + +//TODO: rename motor +void inchwormInit(struct InchwormSetup setup){ + uint32_t freqCnt=SysCtrlClockGet()/setup.motorFrequency; + uint32_t match=(100-setup.dutyCycle)*SysCtrlClockGet()/setup.motorFrequency/100 ; + uint32_t pwmTimerClkEnable=5; + uint32_t pwmTimerBase=5; + uint32_t phaseTimerBase=5; + uint32_t phaseTimerClkEnable=5; + uint32_t x=5; + uint32_t ui32Loop=5; + uint32_t phaseIntA=5; + //setup active motors list + motorsNum=setup.numOfMotors; + + for(uint8_t i=0;i10 &&TimerValueGet(phaseTimerBase,GPTIMER_A)!=freqCnt/2){ + + } + TimerEnable(pwmTimerBase,GPTIMER_A); + + +} + +void inchwormRelease(InchwormMotor motor){ + + GPIOPinTypeGPIOOutput(motor.GPIObase1,motor.GPIOpin1); //sets inchworm motor pis to gpio output setting which disables PWM output + GPIOPinTypeGPIOOutput(motor.GPIObase2,motor.GPIOpin2); + + GPIOPinWrite(motor.GPIObase1,motor.GPIOpin1,255); //releases inchworm motor palls + GPIOPinWrite(motor.GPIObase2,motor.GPIOpin2,255); + +} + +void inchwormFreerun(InchwormMotor motor){ + + GPIOPinTypeTimer(motor.GPIObase1,motor.GPIOpin1); //enables hw muxing of pin outputs + GPIOPinTypeTimer(motor.GPIObase2,motor.GPIOpin2); //enables hw muxing of pin outputs + + IOCPadConfigSet(motor.GPIObase1,motor.GPIOpin1,IOC_OVERRIDE_OE|IOC_OVERRIDE_PUE); // enables pins as outputs, necessary for this code to work correctly + IOCPadConfigSet(motor.GPIObase2,motor.GPIOpin2,IOC_OVERRIDE_OE|IOC_OVERRIDE_PUE); // enables pins as outputs, necessary for this code to work correctly + +} + +//holds inchworm motors +void inchwormHold(InchwormMotor motor){ + + GPIOPinTypeGPIOOutput(motor.GPIObase1,motor.GPIOpin1); //sets pins to normal gpio mode; disables pwm output + GPIOPinTypeGPIOOutput(motor.GPIObase2,motor.GPIOpin2); + + GPIOPinWrite(motor.GPIObase1,motor.GPIOpin1,0); //closes inwhorm palls + GPIOPinWrite(motor.GPIObase2,motor.GPIOpin2,0); +} + +//drives inchworms a certain number of steps +void inchwormDriveToPosition(InchwormMotor motor, uint32_t steps){ + activeDriveList[motor.motorID]=true; //tells isr that this inchworm is actively driving + stepTargetList[motor.motorID]=steps; //tells isr what the target number of steps is for this motor + inchwormFreerun(motor); + + +} + diff --git a/bsp/boards/mimsy2-cc2538/inchworm.h b/bsp/boards/mimsy2-cc2538/inchworm.h new file mode 100644 index 0000000000..afad62ba75 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/inchworm.h @@ -0,0 +1,28 @@ + +typedef struct InchwormMotor{ + uint32_t GPIObase1;//feed gpio base for pin 1 + uint32_t GPIObase2; //gpio base for pin 2 + uint8_t GPIOpin1; //bit packed representation for gpio1 + uint8_t GPIOpin2; + uint8_t motorID; +} InchwormMotor; + +typedef struct InchwormSetup{ + InchwormMotor *iwMotors; + uint32_t numOfMotors; + uint32_t motorFrequency; + uint32_t dutyCycle; + uint32_t motorID; //id for motor + uint32_t timer; + uint32_t phaseTimer; +} InchwormSetup; + + +extern void PhaseTimerAIntHandler(void); +extern void PwmTimerAIntHandler(void); +extern void PwmTimerBIntHandler(void); +extern void inchwormInit(struct InchwormSetup setup); +extern void inchwormRelease(InchwormMotor motor); +extern void inchwormFreerun(InchwormMotor motor); +extern void inchwormDriveToPosition(InchwormMotor motor, uint32_t steps); +extern void inchwormHold(InchwormMotor motor); diff --git a/bsp/boards/mimsy2-cc2538/include/log.h b/bsp/boards/mimsy2-cc2538/include/log.h new file mode 100644 index 0000000000..085c58730d --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/include/log.h @@ -0,0 +1,372 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +/* + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * C/C++ logging functions. See the logging documentation for API details. + * + * We'd like these to be available from C code (in case we import some from + * somewhere), so this has a C interface. + * + * The output will be correct when the log file is shared between multiple + * threads and/or multiple processes so long as the operating system + * supports O_APPEND. These calls have mutex-protected data structures + * and so are NOT reentrant. Do not use MPL_LOG in a signal handler. + */ +#ifndef _LIBS_CUTILS_MPL_LOG_H +#define _LIBS_CUTILS_MPL_LOG_H + +#include +#include + +#ifdef ANDROID +#ifdef NDK_BUILD +#include "log_macros.h" +#else +#include /* For the LOG macro */ +#endif +#endif + +#ifdef __KERNEL__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined ANDROID_JELLYBEAN +#define LOG ALOG +#define LOG_ERRROR ANDROID_LOG_ERROR +#endif + +/* --------------------------------------------------------------------- */ + +/* + * Normally we strip MPL_LOGV (VERBOSE messages) from release builds. + * You can modify this (for example with "#define MPL_LOG_NDEBUG 0" + * at the top of your source file) to change that behavior. + */ +#ifndef MPL_LOG_NDEBUG +#ifdef NDEBUG +#define MPL_LOG_NDEBUG 1 +#else +#define MPL_LOG_NDEBUG 0 +#endif +#endif + +#ifdef __KERNEL__ +#define MPL_LOG_UNKNOWN MPL_LOG_VERBOSE +#define MPL_LOG_DEFAULT KERN_DEFAULT +#define MPL_LOG_VERBOSE KERN_CONT +#define MPL_LOG_DEBUG KERN_NOTICE +#define MPL_LOG_INFO KERN_INFO +#define MPL_LOG_WARN KERN_WARNING +#define MPL_LOG_ERROR KERN_ERR +#define MPL_LOG_SILENT MPL_LOG_VERBOSE + +#else + /* Based off the log priorities in android + /system/core/include/android/log.h */ +#define MPL_LOG_UNKNOWN (0) +#define MPL_LOG_DEFAULT (1) +#define MPL_LOG_VERBOSE (2) +#define MPL_LOG_DEBUG (3) +#define MPL_LOG_INFO (4) +#define MPL_LOG_WARN (5) +#define MPL_LOG_ERROR (6) +#define MPL_LOG_SILENT (8) +#endif + + +/* + * This is the local tag used for the following simplified + * logging macros. You can change this preprocessor definition + * before using the other macros to change the tag. + */ +#ifndef MPL_LOG_TAG +#ifdef __KERNEL__ +#define MPL_LOG_TAG +#else +#define MPL_LOG_TAG NULL +#endif +#endif + +/* --------------------------------------------------------------------- */ + +/* + * Simplified macro to send a verbose log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGV +#if MPL_LOG_NDEBUG +#ifdef _WIN32 +#define MPL_LOGV(fmt, ...) \ + do { \ + __pragma (warning(suppress : 4127 )) \ + if (0) \ + MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__);\ + __pragma (warning(suppress : 4127 )) \ + } while (0) +#else +#define MPL_LOGV(fmt, ...) \ + do { \ + if (0) \ + MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__);\ + } while (0) +#endif + +#else +#define MPL_LOGV(fmt, ...) MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif +#endif + +#ifndef CONDITION +#define CONDITION(cond) ((cond) != 0) +#endif + +#ifndef MPL_LOGV_IF +#if MPL_LOG_NDEBUG +#define MPL_LOGV_IF(cond, fmt, ...) \ + do { if (0) MPL_LOG(fmt, ##__VA_ARGS__); } while (0) +#else +#define MPL_LOGV_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif +#endif + +/* + * Simplified macro to send a debug log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGD +#define MPL_LOGD(fmt, ...) MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif + +#ifndef MPL_LOGD_IF +#define MPL_LOGD_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif + +/* + * Simplified macro to send an info log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGI +#ifdef __KERNEL__ +#define MPL_LOGI(fmt, ...) pr_info(KERN_INFO MPL_LOG_TAG fmt, ##__VA_ARGS__) +#else +#define MPL_LOGI(fmt, ...) MPL_LOG(LOG_INFO, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif +#endif + +#ifndef MPL_LOGI_IF +#define MPL_LOGI_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_INFO, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif + +/* + * Simplified macro to send a warning log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGW +#ifdef __KERNEL__ +#define MPL_LOGW(fmt, ...) printk(KERN_WARNING MPL_LOG_TAG fmt, ##__VA_ARGS__) +#else +#define MPL_LOGW(fmt, ...) MPL_LOG(LOG_WARN, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif +#endif + +#ifndef MPL_LOGW_IF +#define MPL_LOGW_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_WARN, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif + +/* + * Simplified macro to send an error log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGE +#ifdef __KERNEL__ +#define MPL_LOGE(fmt, ...) printk(KERN_ERR MPL_LOG_TAG fmt, ##__VA_ARGS__) +#else +#define MPL_LOGE(fmt, ...) MPL_LOG(LOG_ERROR, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif +#endif + +#ifndef MPL_LOGE_IF +#define MPL_LOGE_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_ERROR, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif + +/* --------------------------------------------------------------------- */ + +/* + * Log a fatal error. If the given condition fails, this stops program + * execution like a normal assertion, but also generating the given message. + * It is NOT stripped from release builds. Note that the condition test + * is -inverted- from the normal assert() semantics. + */ +#define MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? ((void)android_printAssert(#cond, MPL_LOG_TAG, \ + fmt, ##__VA_ARGS__)) \ + : (void)0) + +#define MPL_LOG_ALWAYS_FATAL(fmt, ...) \ + (((void)android_printAssert(NULL, MPL_LOG_TAG, fmt, ##__VA_ARGS__))) + +/* + * Versions of MPL_LOG_ALWAYS_FATAL_IF and MPL_LOG_ALWAYS_FATAL that + * are stripped out of release builds. + */ +#if MPL_LOG_NDEBUG +#define MPL_LOG_FATAL_IF(cond, fmt, ...) \ + do { \ + if (0) \ + MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__); \ + } while (0) +#define MPL_LOG_FATAL(fmt, ...) \ + do { \ + if (0) \ + MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__) \ + } while (0) +#else +#define MPL_LOG_FATAL_IF(cond, fmt, ...) \ + MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__) +#define MPL_LOG_FATAL(fmt, ...) \ + MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__) +#endif + +/* + * Assertion that generates a log message when the assertion fails. + * Stripped out of release builds. Uses the current MPL_LOG_TAG. + */ +#define MPL_LOG_ASSERT(cond, fmt, ...) \ + MPL_LOG_FATAL_IF(!(cond), fmt, ##__VA_ARGS__) + +/* --------------------------------------------------------------------- */ + +/* + * Basic log message macro. + * + * Example: + * MPL_LOG(MPL_LOG_WARN, NULL, "Failed with error %d", errno); + * + * The second argument may be NULL or "" to indicate the "global" tag. + */ +#ifndef MPL_LOG +#ifdef REMOVE_LOGGING +#define MPL_LOG(priority, tag, fmt, ...) do {} while (0) +#else +#define MPL_LOG(priority, tag, fmt, ...) \ + MPL_LOG_PRI(priority, tag, fmt, ##__VA_ARGS__) +#endif +#endif + +/* + * Log macro that allows you to specify a number for the priority. + */ +#ifndef MPL_LOG_PRI +#ifdef ANDROID +#define MPL_LOG_PRI(priority, tag, fmt, ...) \ + LOG(priority, tag, fmt, ##__VA_ARGS__) +#elif defined __KERNEL__ +#define MPL_LOG_PRI(priority, tag, fmt, ...) \ + pr_debug(MPL_##priority tag fmt, ##__VA_ARGS__) +#else +#define MPL_LOG_PRI(priority, tag, fmt, ...) \ + _MLPrintLog(MPL_##priority, tag, fmt, ##__VA_ARGS__) +#endif +#endif + +/* + * Log macro that allows you to pass in a varargs ("args" is a va_list). + */ +#ifndef MPL_LOG_PRI_VA +#ifdef ANDROID +#define MPL_LOG_PRI_VA(priority, tag, fmt, args) \ + android_vprintLog(priority, NULL, tag, fmt, args) +#elif defined __KERNEL__ +/* not allowed in the Kernel because there is no dev_dbg that takes a va_list */ +#else +#define MPL_LOG_PRI_VA(priority, tag, fmt, args) \ + _MLPrintVaLog(priority, NULL, tag, fmt, args) +#endif +#endif + +/* --------------------------------------------------------------------- */ + +/* + * =========================================================================== + * + * The stuff in the rest of this file should not be used directly. + */ + +#ifndef ANDROID +int _MLPrintLog(int priority, const char *tag, const char *fmt, ...); +int _MLPrintVaLog(int priority, const char *tag, const char *fmt, va_list args); +/* Final implementation of actual writing to a character device */ +int _MLWriteLog(const char *buf, int buflen); +#endif + +static inline void __print_result_location(int result, + const char *file, + const char *func, int line) +{ + MPL_LOGE("%s|%s|%d returning %d\n", file, func, line, result); +} + +#ifdef _WIN32 +/* The pragma removes warning about expression being constant */ +#define LOG_RESULT_LOCATION(condition) \ + do { \ + __print_result_location((int)(condition), __FILE__, \ + __func__, __LINE__); \ + __pragma (warning(suppress : 4127 )) \ + } while (0) +#else +#define LOG_RESULT_LOCATION(condition) \ + do { \ + __print_result_location((int)(condition), __FILE__, \ + __func__, __LINE__); \ + } while (0) +#endif + + +#define INV_ERROR_CHECK(r_1329) \ + if (r_1329) { \ + LOG_RESULT_LOCATION(r_1329); \ + return r_1329; \ + } + +#ifdef __cplusplus +} +#endif +#endif /* _LIBS_CUTILS_MPL_LOG_H */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/include/mlinclude.h b/bsp/boards/mimsy2-cc2538/include/mlinclude.h new file mode 100644 index 0000000000..2cdac0a7c3 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/include/mlinclude.h @@ -0,0 +1,38 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +#ifndef INV_INCLUDE_H__ +#define INV_INCLUDE_H__ + +#define INVENSENSE_FUNC_START typedef int invensensePutFunctionCallsHere + +#ifdef COVERAGE +#include "utestCommon.h" +#endif +#ifdef PROFILE +#include "profile.h" +#endif + +#ifdef WIN32 +#ifdef COVERAGE + +extern int functionEnterLog(const char *file, const char *func); +extern int functionExitLog(const char *file, const char *func); + +#undef INVENSENSE_FUNC_START +#define INVENSENSE_FUNC_START __pragma(message(__FILE__ "|"__FUNCTION__ )) \ + int dslkQjDsd = functionEnterLog(__FILE__, __FUNCTION__) +#endif // COVERAGE +#endif // WIN32 + +#ifdef PROFILE +#undef INVENSENSE_FUNC_START +#define INVENSENSE_FUNC_START int dslkQjDsd = profileEnter(__FILE__, __FUNCTION__) +#define return if ( profileExit(__FILE__, __FUNCTION__) ) return +#endif // PROFILE + +// #define return if ( functionExitLog(__FILE__, __FUNCTION__) ) return + +#endif //INV_INCLUDE_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/include/mlmath.h b/bsp/boards/mimsy2-cc2538/include/mlmath.h new file mode 100644 index 0000000000..0a70868ea7 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/include/mlmath.h @@ -0,0 +1,95 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +/******************************************************************************* + * + * $Id: mlmath.h 5629 2011-06-11 03:13:08Z mcaramello $ + * + *******************************************************************************/ + +#ifndef _ML_MATH_H_ +#define _ML_MATH_H_ + +#ifndef MLMATH +// This define makes Microsoft pickup things like M_PI +#define _USE_MATH_DEFINES +#include + +#ifdef WIN32 +// Microsoft doesn't follow standards +#define round(x)(((double)((long long)((x)>0?(x)+.5:(x)-.5)))) +#define roundf(x)(((float )((long long)((x)>0?(x)+.5f:(x)-.5f)))) +#endif + +#else // MLMATH + +#ifdef __cplusplus +extern "C" { +#endif +/* MPL needs below functions */ +double ml_asin(double); +double ml_atan(double); +double ml_atan2(double, double); +double ml_log(double); +double ml_sqrt(double); +double ml_ceil(double); +double ml_floor(double); +double ml_cos(double); +double ml_sin(double); +double ml_acos(double); +#ifdef __cplusplus +} // extern "C" +#endif + +/* + * We rename functions here to provide the hook for other + * customized math functions. + */ +#define sqrt(x) ml_sqrt(x) +#define log(x) ml_log(x) +#define asin(x) ml_asin(x) +#define atan(x) ml_atan(x) +#define atan2(x,y) ml_atan2(x,y) +#define ceil(x) ml_ceil(x) +#define floor(x) ml_floor(x) +#define fabs(x) (((x)<0)?-(x):(x)) +#define round(x) (((double)((long long)((x)>0?(x)+.5:(x)-.5)))) +#define roundf(x) (((float )((long long)((x)>0?(x)+.5f:(x)-.5f)))) +#define cos(x) ml_cos(x) +#define sin(x) ml_sin(x) +#define acos(x) ml_acos(x) + +#define pow(x,y) ml_pow(x,y) + +#ifdef LINUX +/* stubs for float version of math functions */ +#define cosf(x) ml_cos(x) +#define sinf(x) ml_sin(x) +#define atan2f(x,y) ml_atan2(x,y) +#define sqrtf(x) ml_sqrt(x) +#endif + + + +#endif // MLMATH + +#ifndef M_PI +#define M_PI 3.14159265358979 +#endif + +#ifndef ABS +#define ABS(x) (((x)>=0)?(x):-(x)) +#endif + +#ifndef MIN +#define MIN(x,y) (((x)<(y))?(x):(y)) +#endif + +#ifndef MAX +#define MAX(x,y) (((x)>(y))?(x):(y)) +#endif + +/*---------------------------*/ +#endif /* !_ML_MATH_H_ */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/include/mlos.h b/bsp/boards/mimsy2-cc2538/include/mlos.h new file mode 100644 index 0000000000..bee573d0e1 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/include/mlos.h @@ -0,0 +1,103 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +#ifndef _MLOS_H +#define _MLOS_H + +#ifndef __KERNEL__ +#include +#endif + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(LINUX) || defined(__KERNEL__) +typedef unsigned int HANDLE; +#endif + + /* ------------ */ + /* - Defines. - */ + /* ------------ */ + + /* - MLOSCreateFile defines. - */ + +#define MLOS_GENERIC_READ ((unsigned int)0x80000000) +#define MLOS_GENERIC_WRITE ((unsigned int)0x40000000) +#define MLOS_FILE_SHARE_READ ((unsigned int)0x00000001) +#define MLOS_FILE_SHARE_WRITE ((unsigned int)0x00000002) +#define MLOS_OPEN_EXISTING ((unsigned int)0x00000003) + + /* ---------- */ + /* - Enums. - */ + /* ---------- */ + + /* --------------- */ + /* - Structures. - */ + /* --------------- */ + + /* --------------------- */ + /* - Function p-types. - */ + /* --------------------- */ + +#ifndef __KERNEL__ +#include + void *inv_malloc(unsigned int numBytes); + inv_error_t inv_free(void *ptr); + inv_error_t inv_create_mutex(HANDLE *mutex); + inv_error_t inv_lock_mutex(HANDLE mutex); + inv_error_t inv_unlock_mutex(HANDLE mutex); + FILE *inv_fopen(char *filename); + void inv_fclose(FILE *fp); + + inv_error_t inv_destroy_mutex(HANDLE handle); + + void inv_sleep(int mSecs); +#ifdef EMPL + inv_error_t inv_get_tick_count(inv_time_t *timestamp); +#else + inv_time_t inv_get_tick_count(void); +#endif + + + /* Kernel implmentations */ +#define GFP_KERNEL (0x70) + static inline void *kmalloc(size_t size, + unsigned int gfp_flags) + { + (void)gfp_flags; + return inv_malloc((unsigned int)size); + } + static inline void *kzalloc(size_t size, unsigned int gfp_flags) + { + void *tmp = inv_malloc((unsigned int)size); + (void)gfp_flags; + if (tmp) + memset(tmp, 0, size); + return tmp; + } + static inline void kfree(void *ptr) + { + inv_free(ptr); + } + static inline void msleep(long msecs) + { + inv_sleep(msecs); + } + static inline void udelay(unsigned long usecs) + { + inv_sleep((usecs + 999) / 1000); + } +#else +#include +#endif + +#ifdef __cplusplus +} +#endif +#endif /* _MLOS_H */ diff --git a/bsp/boards/mimsy2-cc2538/include/mltypes.h b/bsp/boards/mimsy2-cc2538/include/mltypes.h new file mode 100644 index 0000000000..ccb34d4e37 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/include/mltypes.h @@ -0,0 +1,262 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +/** + * @defgroup MLERROR + * @brief Motion Library - Error definitions. + * Definition of the error codes used within the MPL and + * returned to the user. + * Every function tries to return a meaningful error code basing + * on the occuring error condition. The error code is numeric. + * + * The available error codes and their associated values are: + * - (0) INV_SUCCESS + * - (32) INV_ERROR + * - (22 / EINVAL) INV_ERROR_INVALID_PARAMETER + * - (1 / EPERM) INV_ERROR_FEATURE_NOT_ENABLED + * - (36) INV_ERROR_FEATURE_NOT_IMPLEMENTED + * - (38) INV_ERROR_DMP_NOT_STARTED + * - (39) INV_ERROR_DMP_STARTED + * - (40) INV_ERROR_NOT_OPENED + * - (41) INV_ERROR_OPENED + * - (19 / ENODEV) INV_ERROR_INVALID_MODULE + * - (12 / ENOMEM) INV_ERROR_MEMORY_EXAUSTED + * - (44) INV_ERROR_DIVIDE_BY_ZERO + * - (45) INV_ERROR_ASSERTION_FAILURE + * - (46) INV_ERROR_FILE_OPEN + * - (47) INV_ERROR_FILE_READ + * - (48) INV_ERROR_FILE_WRITE + * - (49) INV_ERROR_INVALID_CONFIGURATION + * - (52) INV_ERROR_SERIAL_CLOSED + * - (53) INV_ERROR_SERIAL_OPEN_ERROR + * - (54) INV_ERROR_SERIAL_READ + * - (55) INV_ERROR_SERIAL_WRITE + * - (56) INV_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED + * - (57) INV_ERROR_SM_TRANSITION + * - (58) INV_ERROR_SM_IMPROPER_STATE + * - (62) INV_ERROR_FIFO_OVERFLOW + * - (63) INV_ERROR_FIFO_FOOTER + * - (64) INV_ERROR_FIFO_READ_COUNT + * - (65) INV_ERROR_FIFO_READ_DATA + * - (72) INV_ERROR_MEMORY_SET + * - (82) INV_ERROR_LOG_MEMORY_ERROR + * - (83) INV_ERROR_LOG_OUTPUT_ERROR + * - (92) INV_ERROR_OS_BAD_PTR + * - (93) INV_ERROR_OS_BAD_HANDLE + * - (94) INV_ERROR_OS_CREATE_FAILED + * - (95) INV_ERROR_OS_LOCK_FAILED + * - (102) INV_ERROR_COMPASS_DATA_OVERFLOW + * - (103) INV_ERROR_COMPASS_DATA_UNDERFLOW + * - (104) INV_ERROR_COMPASS_DATA_NOT_READY + * - (105) INV_ERROR_COMPASS_DATA_ERROR + * - (107) INV_ERROR_CALIBRATION_LOAD + * - (108) INV_ERROR_CALIBRATION_STORE + * - (109) INV_ERROR_CALIBRATION_LEN + * - (110) INV_ERROR_CALIBRATION_CHECKSUM + * - (111) INV_ERROR_ACCEL_DATA_OVERFLOW + * - (112) INV_ERROR_ACCEL_DATA_UNDERFLOW + * - (113) INV_ERROR_ACCEL_DATA_NOT_READY + * - (114) INV_ERROR_ACCEL_DATA_ERROR + * + * The available warning codes and their associated values are: + * - (115) INV_WARNING_MOTION_RACE + * - (116) INV_WARNING_QUAT_TRASHED + * + * @{ + * @file mltypes.h + * @} + */ + +#ifndef MLTYPES_H +#define MLTYPES_H + +#ifdef __KERNEL__ +#include +#include +#else +#include "stdint_invensense.h" +#include +#endif +#include + +#ifndef REMOVE_INV_ERROR_T +/*--------------------------- + * ML Types + *--------------------------*/ + +/** + * @struct inv_error_t mltypes.h "mltypes" + * @brief The MPL Error Code return type. + * + * @code + * typedef unsigned char inv_error_t; + * @endcode + */ +//typedef unsigned char inv_error_t; +typedef int inv_error_t; +#endif + +#if defined EMPL +typedef unsigned long inv_time_t; +#else +typedef unsigned long long inv_time_t; +#endif + +#if defined EMPL || (!defined __GNUC__ && !defined __KERNEL__) +typedef int8_t __s8; +typedef int16_t __s16; +typedef int32_t __s32; + +typedef uint8_t __u8; +typedef uint16_t __u16; +typedef uint32_t __u32; + +#ifndef EMPL_NO_64BIT +typedef int64_t __s64; +typedef uint64_t __u64; +#endif +#elif !defined __KERNEL__ +#include +#endif + +#if defined EMPL_TARGET_MSP430 +#include +#endif + +#ifndef __cplusplus +#ifndef __KERNEL__ +#ifndef EMPL_TARGET_UC3L0 +//typedef int_fast8_t bool; +#endif + +#ifndef false +#define false 0 +#endif + +#ifndef true +#define true 1 +#endif + +#endif +#endif + +/*--------------------------- + * ML Defines + *--------------------------*/ + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef __KERNEL__ +#ifndef ARRAY_SIZE +/* Dimension of an array */ +#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0])) +#endif +#endif +/* - ML Errors. - */ +#define ERROR_NAME(x) (#x) +#define ERROR_CHECK_FIRST(first, x) \ + { if (INV_SUCCESS == first) first = x; } + +#define INV_SUCCESS (0) +/* Generic Error code. Proprietary Error Codes only */ +#define INV_ERROR_BASE (0x20) +#define INV_ERROR (INV_ERROR_BASE) + +#ifndef EINVAL +#define EINVAL (22) +#endif + +#ifndef ENOMEM +#define ENOMEM (12) +#endif + +#ifndef EPERM +#define EPERM (1) +#endif + + + +/* Compatibility and other generic error codes */ +#define INV_ERROR_INVALID_PARAMETER (EINVAL) +#define INV_ERROR_FEATURE_NOT_ENABLED (EPERM) +#define INV_ERROR_FEATURE_NOT_IMPLEMENTED (INV_ERROR_BASE + 4) +#define INV_ERROR_DMP_NOT_STARTED (INV_ERROR_BASE + 6) +#define INV_ERROR_DMP_STARTED (INV_ERROR_BASE + 7) +#define INV_ERROR_NOT_OPENED (INV_ERROR_BASE + 8) +#define INV_ERROR_OPENED (INV_ERROR_BASE + 9) +#define INV_ERROR_INVALID_MODULE (ENODEV) +#define INV_ERROR_MEMORY_EXAUSTED (ENOMEM) +#define INV_ERROR_DIVIDE_BY_ZERO (INV_ERROR_BASE + 12) +#define INV_ERROR_ASSERTION_FAILURE (INV_ERROR_BASE + 13) +#define INV_ERROR_FILE_OPEN (INV_ERROR_BASE + 14) +#define INV_ERROR_FILE_READ (INV_ERROR_BASE + 15) +#define INV_ERROR_FILE_WRITE (INV_ERROR_BASE + 16) +#define INV_ERROR_INVALID_CONFIGURATION (INV_ERROR_BASE + 17) +#define INV_ERROR_NOT_AUTHORIZED (INV_ERROR_BASE + 18) + +/* Serial Communication */ +#define INV_ERROR_SERIAL_CLOSED (INV_ERROR_BASE + 20) +#define INV_ERROR_SERIAL_OPEN_ERROR (INV_ERROR_BASE + 21) +#define INV_ERROR_SERIAL_READ (INV_ERROR_BASE + 22) +#define INV_ERROR_SERIAL_WRITE (INV_ERROR_BASE + 23) +#define INV_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED (INV_ERROR_BASE + 24) + +/* SM = State Machine */ +#define INV_ERROR_SM_TRANSITION (INV_ERROR_BASE + 25) +#define INV_ERROR_SM_IMPROPER_STATE (INV_ERROR_BASE + 26) + +/* Fifo */ +#define INV_ERROR_FIFO_OVERFLOW (INV_ERROR_BASE + 30) +#define INV_ERROR_FIFO_FOOTER (INV_ERROR_BASE + 31) +#define INV_ERROR_FIFO_READ_COUNT (INV_ERROR_BASE + 32) +#define INV_ERROR_FIFO_READ_DATA (INV_ERROR_BASE + 33) + +/* Memory & Registers, Set & Get */ +#define INV_ERROR_MEMORY_SET (INV_ERROR_BASE + 40) + +#define INV_ERROR_LOG_MEMORY_ERROR (INV_ERROR_BASE + 50) +#define INV_ERROR_LOG_OUTPUT_ERROR (INV_ERROR_BASE + 51) + +/* OS interface errors */ +#define INV_ERROR_OS_BAD_PTR (INV_ERROR_BASE + 60) +#define INV_ERROR_OS_BAD_HANDLE (INV_ERROR_BASE + 61) +#define INV_ERROR_OS_CREATE_FAILED (INV_ERROR_BASE + 62) +#define INV_ERROR_OS_LOCK_FAILED (INV_ERROR_BASE + 63) + +/* Compass errors */ +#define INV_ERROR_COMPASS_DATA_OVERFLOW (INV_ERROR_BASE + 70) +#define INV_ERROR_COMPASS_DATA_UNDERFLOW (INV_ERROR_BASE + 71) +#define INV_ERROR_COMPASS_DATA_NOT_READY (INV_ERROR_BASE + 72) +#define INV_ERROR_COMPASS_DATA_ERROR (INV_ERROR_BASE + 73) + +/* Load/Store calibration */ +#define INV_ERROR_CALIBRATION_LOAD (INV_ERROR_BASE + 75) +#define INV_ERROR_CALIBRATION_STORE (INV_ERROR_BASE + 76) +#define INV_ERROR_CALIBRATION_LEN (INV_ERROR_BASE + 77) +#define INV_ERROR_CALIBRATION_CHECKSUM (INV_ERROR_BASE + 78) + +/* Accel errors */ +#define INV_ERROR_ACCEL_DATA_OVERFLOW (INV_ERROR_BASE + 79) +#define INV_ERROR_ACCEL_DATA_UNDERFLOW (INV_ERROR_BASE + 80) +#define INV_ERROR_ACCEL_DATA_NOT_READY (INV_ERROR_BASE + 81) +#define INV_ERROR_ACCEL_DATA_ERROR (INV_ERROR_BASE + 82) + +/* No Motion Warning States */ +#define INV_WARNING_MOTION_RACE (INV_ERROR_BASE + 83) +#define INV_WARNING_QUAT_TRASHED (INV_ERROR_BASE + 84) +#define INV_WARNING_GYRO_MAG (INV_ERROR_BASE + 85) + +#define INV_WARNING_SEMAPHORE_TIMEOUT (INV_ERROR_BASE + 86) + + +/* For Linux coding compliance */ +#ifndef __KERNEL__ +#define EXPORT_SYMBOL(x) +#endif + +#endif /* MLTYPES_H */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/include/mpu.h b/bsp/boards/mimsy2-cc2538/include/mpu.h new file mode 100644 index 0000000000..bed5042021 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/include/mpu.h @@ -0,0 +1,386 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +#ifndef __MPU_H_ +#define __MPU_H_ + +#ifdef __KERNEL__ +#include +#include +#elif defined LINUX +#include +#include +#else +#include "mltypes.h" +#define __u32 uint32_t +#define __s32 int32_t +#define __s64 long long +#define __u8 uint8_t +#define __u16 uint16_t +#define __s8 int8_t +#endif + +struct mpu_read_write { + /* Memory address or register address depending on ioctl */ + __u16 address; + __u16 length; + __u8 *data; +}; + +enum mpuirq_data_type { + MPUIRQ_DATA_TYPE_MPU_DATA_READY_IRQ, + MPUIRQ_DATA_TYPE_MPU_FIFO_READY_IRQ, + MPUIRQ_DATA_TYPE_SLAVE_IRQ, + MPUIRQ_DATA_TYPE_PM_EVENT, + MPUIRQ_DATA_TYPE_NUM_TYPES, +}; + +/* User space PM event notification */ +#define MPU_PM_EVENT_SUSPEND_PREPARE (3) +#define MPU_PM_EVENT_POST_SUSPEND (4) + +/** + * struct mpuirq_data - structure to report what and when + * @interruptcount : The number of times this IRQ has occured since open + * @irqtime : monotonic time of the IRQ in ns + * @data_type : The type of this IRQ enum mpuirq_data_type + * @data : Data associated with this IRQ + */ +struct mpuirq_data { + __u32 interruptcount; +#ifdef EMPL_NO_64BIT + __s32 irqtime_ns; +#else + __s64 irqtime_ns; +#endif + __u32 data_type; + __s32 data; +}; + +enum ext_slave_config_key { + /* TODO: Remove these first six. */ + MPU_SLAVE_CONFIG_ODR_SUSPEND, + MPU_SLAVE_CONFIG_ODR_RESUME, + MPU_SLAVE_CONFIG_FSR_SUSPEND, + MPU_SLAVE_CONFIG_FSR_RESUME, + MPU_SLAVE_CONFIG_IRQ_SUSPEND, + MPU_SLAVE_CONFIG_IRQ_RESUME, + MPU_SLAVE_CONFIG_ODR, + MPU_SLAVE_CONFIG_FSR, + MPU_SLAVE_CONFIG_MOT_THS, + MPU_SLAVE_CONFIG_NMOT_THS, + MPU_SLAVE_CONFIG_MOT_DUR, + MPU_SLAVE_CONFIG_NMOT_DUR, + MPU_SLAVE_CONFIG_IRQ, + MPU_SLAVE_WRITE_REGISTERS, + MPU_SLAVE_READ_REGISTERS, + MPU_SLAVE_CONFIG_INTERNAL_REFERENCE, + /* AMI 306 specific config keys */ + MPU_SLAVE_PARAM, + MPU_SLAVE_WINDOW, + MPU_SLAVE_READWINPARAMS, + MPU_SLAVE_SEARCHOFFSET, + /* MPU3050 and MPU6050 Keys */ + MPU_SLAVE_INT_CONFIG, + MPU_SLAVE_EXT_SYNC, + MPU_SLAVE_FULL_SCALE, + MPU_SLAVE_LPF, + MPU_SLAVE_CLK_SRC, + MPU_SLAVE_DIVIDER, + MPU_SLAVE_DMP_ENABLE, + MPU_SLAVE_FIFO_ENABLE, + MPU_SLAVE_DMP_CFG1, + MPU_SLAVE_DMP_CFG2, + MPU_SLAVE_TC, + MPU_SLAVE_GYRO, + MPU_SLAVE_ADDR, + MPU_SLAVE_PRODUCT_REVISION, + MPU_SLAVE_SILICON_REVISION, + MPU_SLAVE_PRODUCT_ID, + MPU_SLAVE_GYRO_SENS_TRIM, + MPU_SLAVE_ACCEL_SENS_TRIM, + MPU_SLAVE_RAM, + /* -------------------------- */ + MPU_SLAVE_CONFIG_NUM_CONFIG_KEYS +}; + +/* For the MPU_SLAVE_CONFIG_IRQ_SUSPEND and MPU_SLAVE_CONFIG_IRQ_RESUME */ +enum ext_slave_config_irq_type { + MPU_SLAVE_IRQ_TYPE_NONE, + MPU_SLAVE_IRQ_TYPE_MOTION, + MPU_SLAVE_IRQ_TYPE_DATA_READY, +}; + +/* Structure for the following IOCTS's + * MPU_CONFIG_GYRO + * MPU_CONFIG_ACCEL + * MPU_CONFIG_COMPASS + * MPU_CONFIG_PRESSURE + * MPU_GET_CONFIG_GYRO + * MPU_GET_CONFIG_ACCEL + * MPU_GET_CONFIG_COMPASS + * MPU_GET_CONFIG_PRESSURE + * + * @key one of enum ext_slave_config_key + * @len length of data pointed to by data + * @apply zero if communication with the chip is not necessary, false otherwise + * This flag can be used to select cached data or to refresh cashed data + * cache data to be pushed later or push immediately. If true and the + * slave is on the secondary bus the MPU will first enger bypass mode + * before calling the slaves .config or .get_config funcion + * @data pointer to the data to confgure or get + */ +struct ext_slave_config { + __u8 key; + __u16 len; + __u8 apply; + void *data; +}; + +enum ext_slave_type { + EXT_SLAVE_TYPE_GYROSCOPE, + EXT_SLAVE_TYPE_ACCEL, + EXT_SLAVE_TYPE_COMPASS, + EXT_SLAVE_TYPE_PRESSURE, + /*EXT_SLAVE_TYPE_TEMPERATURE */ + + EXT_SLAVE_NUM_TYPES +}; + +enum ext_slave_id { + ID_INVALID = 0, + GYRO_ID_MPU3050, + GYRO_ID_MPU6050A2, + GYRO_ID_MPU6050B1, + GYRO_ID_MPU6050B1_NO_ACCEL, + GYRO_ID_ITG3500, + + ACCEL_ID_LIS331, + ACCEL_ID_LSM303DLX, + ACCEL_ID_LIS3DH, + ACCEL_ID_KXSD9, + ACCEL_ID_KXTF9, + ACCEL_ID_BMA150, + ACCEL_ID_BMA222, + ACCEL_ID_BMA250, + ACCEL_ID_ADXL34X, + ACCEL_ID_MMA8450, + ACCEL_ID_MMA845X, + ACCEL_ID_MPU6050, + + COMPASS_ID_AK8975, + COMPASS_ID_AK8972, + COMPASS_ID_AMI30X, + COMPASS_ID_AMI306, + COMPASS_ID_YAS529, + COMPASS_ID_YAS530, + COMPASS_ID_HMC5883, + COMPASS_ID_LSM303DLH, + COMPASS_ID_LSM303DLM, + COMPASS_ID_MMC314X, + COMPASS_ID_HSCDTD002B, + COMPASS_ID_HSCDTD004A, + + PRESSURE_ID_BMA085, +}; + +#define INV_PROD_KEY(ver, rev) (ver * 100 + rev) + +enum ext_slave_endian { + EXT_SLAVE_BIG_ENDIAN, + EXT_SLAVE_LITTLE_ENDIAN, + EXT_SLAVE_FS8_BIG_ENDIAN, + EXT_SLAVE_FS16_BIG_ENDIAN, +}; + +enum ext_slave_bus { + EXT_SLAVE_BUS_INVALID = -1, + EXT_SLAVE_BUS_PRIMARY = 0, + EXT_SLAVE_BUS_SECONDARY = 1 +}; + + +/** + * struct ext_slave_platform_data - Platform data for mpu3050 and mpu6050 + * slave devices + * + * @type: the type of slave device based on the enum ext_slave_type + * definitions. + * @irq: the irq number attached to the slave if any. + * @adapt_num: the I2C adapter number. + * @bus: the bus the slave is attached to: enum ext_slave_bus + * @address: the I2C slave address of the slave device. + * @orientation: the mounting matrix of the device relative to MPU. + * @irq_data: private data for the slave irq handler + * @private_data: additional data, user customizable. Not touched by the MPU + * driver. + * + * The orientation matricies are 3x3 rotation matricies + * that are applied to the data to rotate from the mounting orientation to the + * platform orientation. The values must be one of 0, 1, or -1 and each row and + * column should have exactly 1 non-zero value. + */ +struct ext_slave_platform_data { + __u8 type; + __u32 irq; + __u32 adapt_num; + __s32 bus; + __u8 address; + __s8 orientation[9]; + void *irq_data; + void *private_data; +}; + +struct fix_pnt_range { + __s32 mantissa; + __s32 fraction; +}; + +static inline long range_fixedpoint_to_long_mg(struct fix_pnt_range rng) +{ + return (long)(rng.mantissa * 1000 + rng.fraction / 10); +} + +struct ext_slave_read_trigger { + __u8 reg; + __u8 value; +}; + +/** + * struct ext_slave_descr - Description of the slave device for programming. + * + * @suspend: function pointer to put the device in suspended state + * @resume: function pointer to put the device in running state + * @read: function that reads the device data + * @init: function used to preallocate memory used by the driver + * @exit: function used to free memory allocated for the driver + * @config: function used to configure the device + * @get_config:function used to get the device's configuration + * + * @name: text name of the device + * @type: device type. enum ext_slave_type + * @id: enum ext_slave_id + * @read_reg: starting register address to retrieve data. + * @read_len: length in bytes of the sensor data. Typically 6. + * @endian: byte order of the data. enum ext_slave_endian + * @range: full scale range of the slave ouput: struct fix_pnt_range + * @trigger: If reading data first requires writing a register this is the + * data to write. + * + * Defines the functions and information about the slave the mpu3050 and + * mpu6050 needs to use the slave device. + */ +struct ext_slave_descr { + int (*init) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*exit) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*suspend) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*resume) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*read) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata, + __u8 *data); + int (*config) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata, + struct ext_slave_config *config); + int (*get_config) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata, + struct ext_slave_config *config); + + char *name; + __u8 type; + __u8 id; + __u8 read_reg; + __u8 read_len; + __u8 endian; + struct fix_pnt_range range; + struct ext_slave_read_trigger *trigger; +}; + +/** + * struct mpu_platform_data - Platform data for the mpu driver + * @int_config: Bits [7:3] of the int config register. + * @level_shifter: 0: VLogic, 1: VDD + * @orientation: Orientation matrix of the gyroscope + * + * Contains platform specific information on how to configure the MPU3050 to + * work on this platform. The orientation matricies are 3x3 rotation matricies + * that are applied to the data to rotate from the mounting orientation to the + * platform orientation. The values must be one of 0, 1, or -1 and each row and + * column should have exactly 1 non-zero value. + */ +struct mpu_platform_data { + __u8 int_config; + __u8 level_shifter; + __s8 orientation[9]; +}; + +#if defined __KERNEL__ || defined LINUX +#define MPU_IOCTL (0x81) /* Magic number for MPU Iocts */ +/* IOCTL commands for /dev/mpu */ + +/*-------------------------------------------------------------------------- + * Deprecated, debugging only + */ +#define MPU_SET_MPU_PLATFORM_DATA \ + _IOWR(MPU_IOCTL, 0x01, struct mpu_platform_data) +#define MPU_SET_EXT_SLAVE_PLATFORM_DATA \ + _IOWR(MPU_IOCTL, 0x01, struct ext_slave_platform_data) +/*--------------------------------------------------------------------------*/ +#define MPU_GET_EXT_SLAVE_PLATFORM_DATA \ + _IOWR(MPU_IOCTL, 0x02, struct ext_slave_platform_data) +#define MPU_GET_MPU_PLATFORM_DATA \ + _IOWR(MPU_IOCTL, 0x02, struct mpu_platform_data) +#define MPU_GET_EXT_SLAVE_DESCR \ + _IOWR(MPU_IOCTL, 0x02, struct ext_slave_descr) + +#define MPU_READ _IOWR(MPU_IOCTL, 0x10, struct mpu_read_write) +#define MPU_WRITE _IOW(MPU_IOCTL, 0x10, struct mpu_read_write) +#define MPU_READ_MEM _IOWR(MPU_IOCTL, 0x11, struct mpu_read_write) +#define MPU_WRITE_MEM _IOW(MPU_IOCTL, 0x11, struct mpu_read_write) +#define MPU_READ_FIFO _IOWR(MPU_IOCTL, 0x12, struct mpu_read_write) +#define MPU_WRITE_FIFO _IOW(MPU_IOCTL, 0x12, struct mpu_read_write) + +#define MPU_READ_COMPASS _IOR(MPU_IOCTL, 0x12, __u8) +#define MPU_READ_ACCEL _IOR(MPU_IOCTL, 0x13, __u8) +#define MPU_READ_PRESSURE _IOR(MPU_IOCTL, 0x14, __u8) + +#define MPU_CONFIG_GYRO _IOW(MPU_IOCTL, 0x20, struct ext_slave_config) +#define MPU_CONFIG_ACCEL _IOW(MPU_IOCTL, 0x21, struct ext_slave_config) +#define MPU_CONFIG_COMPASS _IOW(MPU_IOCTL, 0x22, struct ext_slave_config) +#define MPU_CONFIG_PRESSURE _IOW(MPU_IOCTL, 0x23, struct ext_slave_config) + +#define MPU_GET_CONFIG_GYRO _IOWR(MPU_IOCTL, 0x20, struct ext_slave_config) +#define MPU_GET_CONFIG_ACCEL _IOWR(MPU_IOCTL, 0x21, struct ext_slave_config) +#define MPU_GET_CONFIG_COMPASS _IOWR(MPU_IOCTL, 0x22, struct ext_slave_config) +#define MPU_GET_CONFIG_PRESSURE _IOWR(MPU_IOCTL, 0x23, struct ext_slave_config) + +#define MPU_SUSPEND _IOW(MPU_IOCTL, 0x30, __u32) +#define MPU_RESUME _IOW(MPU_IOCTL, 0x31, __u32) +/* Userspace PM Event response */ +#define MPU_PM_EVENT_HANDLED _IO(MPU_IOCTL, 0x32) + +#define MPU_GET_REQUESTED_SENSORS _IOR(MPU_IOCTL, 0x40, __u32) +#define MPU_SET_REQUESTED_SENSORS _IOW(MPU_IOCTL, 0x40, __u32) +#define MPU_GET_IRQ_TO_FIFO_DIVIDER _IOR(MPU_IOCTL, 0x41, __u16) +#define MPU_SET_IRQ_TO_FIFO_DIVIDER _IOW(MPU_IOCTL, 0x41, __u16) +#define MPU_GET_IGNORE_SYSTEM_SUSPEND _IOR(MPU_IOCTL, 0x42, __u8) +#define MPU_SET_IGNORE_SYSTEM_SUSPEND _IOW(MPU_IOCTL, 0x42, __u8) +#define MPU_GET_MLDL_STATUS _IOR(MPU_IOCTL, 0x43, __u8) +#define MPU_GET_I2C_SLAVES_ENABLED _IOR(MPU_IOCTL, 0x44, __u8) + +#endif + +#endif /* __MPU_H_ */ diff --git a/bsp/boards/mimsy2-cc2538/include/stdint_invensense.h b/bsp/boards/mimsy2-cc2538/include/stdint_invensense.h new file mode 100644 index 0000000000..ea39b21511 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/include/stdint_invensense.h @@ -0,0 +1,44 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +#ifndef STDINT_INVENSENSE_H +#define STDINT_INVENSENSE_H + +#ifndef WIN32 + +#if defined __KERNEL__ +#include +#elif defined EMPL +#include +#include +#else +#include +#endif + +#else + +#include + +typedef signed char int8_t; +typedef short int16_t; +typedef long int32_t; +typedef long long int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +typedef unsigned long long uint64_t; + +typedef int int_fast8_t; +typedef int int_fast16_t; +typedef long int_fast32_t; + +typedef unsigned int uint_fast8_t; +typedef unsigned int uint_fast16_t; +typedef unsigned long uint_fast32_t; + +#endif + +#endif // STDINT_INVENSENSE_H \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/inv_math.h b/bsp/boards/mimsy2-cc2538/inv_math.h new file mode 100644 index 0000000000..079c11c9e7 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/inv_math.h @@ -0,0 +1,8 @@ +/* math.h has many functions and defines that are not consistent across +* platforms. This address that */ + +#ifdef _WINDOWS +#define _USE_MATH_DEFINES +#endif + +#include \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/inv_mpu.c b/bsp/boards/mimsy2-cc2538/inv_mpu.c new file mode 100644 index 0000000000..4084421228 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/inv_mpu.c @@ -0,0 +1,3296 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @addtogroup DRIVERS Sensor Driver Layer + * @brief Hardware drivers to communicate with sensors via I2C. + * + * @{ + * @file inv_mpu.c + * @brief An I2C-based driver for Invensense gyroscopes. + * @details This driver currently works for the following devices: + * MPU6050 + * MPU6500 + * MPU9150 (or MPU6050 w/ AK8975 on the auxiliary bus) + * MPU9250 (or MPU6500 w/ AK8963 on the auxiliary bus) + */ +#include +#include +#include +#include +#include +#include "inv_mpu.h" +#include "i2c_mimsy.h" +#include "i2c.h" +#define MPU9250 true +#define MIMSY + +/* The following functions must be defined for this platform: + * i2c_write(unsigned char slave_addr, unsigned char reg_addr, + * unsigned char length, unsigned char const *data) + * i2c_read(unsigned char slave_addr, unsigned char reg_addr, + * unsigned char length, unsigned char *data) + * delay_ms(unsigned long num_ms) + * get_ms(unsigned long *count) + * reg_int_cb(void (*cb)(void), unsigned char port, unsigned char pin) + * labs(long x) + * fabsf(float x) + * min(int a, int b) + */ + +#if defined MIMSY + +#define i2c_write i2c_write_registers +#define i2c_read i2c_read_registers +#define delay_ms delay_ms +#define get_ms get_ms +#define log_i(...) do {} while (0) +#define log_e(...) do {} while (0) +#define min(a,b) ((acb, int_param->pin, int_param->lp_exit, + int_param->active_low); +} +#define log_i(...) do {} while (0) +#define log_e(...) do {} while (0) +/* labs is already defined by TI's toolchain. */ +/* fabs is for doubles. fabsf is for floats. */ +#define fabs fabsf +#define min(a,b) ((acb, int_param->pin, int_param->lp_exit, + int_param->active_low); +} +#define log_i MPL_LOGI +#define log_e MPL_LOGE +/* labs is already defined by TI's toolchain. */ +/* fabs is for doubles. fabsf is for floats. */ +#define fabs fabsf +#define min(a,b) ((apin, int_param->cb, int_param->arg); + return 0; +} +#define log_i MPL_LOGI +#define log_e MPL_LOGE +/* UC3 is a 32-bit processor, so abs and labs are equivalent. */ +#define labs abs +#define fabs(x) (((x)>0)?(x):-(x)) +#else +#error Gyro driver is missing the system layer implementations. +#endif + +#if !defined MPU6050 && !defined MPU9150 && !defined MPU6500 && !defined MPU9250 +#error Which gyro are you using? Define MPUxxxx in your compiler options. +#endif + +/* Time for some messy macro work. =] + * #define MPU9150 + * is equivalent to.. + * #define MPU6050 + * #define AK8975_SECONDARY + * + * #define MPU9250 + * is equivalent to.. + * #define MPU6500 + * #define AK8963_SECONDARY + */ +#if defined MPU9150 +#ifndef MPU6050 +#define MPU6050 +#endif /* #ifndef MPU6050 */ +#if defined AK8963_SECONDARY +#error "MPU9150 and AK8963_SECONDARY cannot both be defined." +#elif !defined AK8975_SECONDARY /* #if defined AK8963_SECONDARY */ +#define AK8975_SECONDARY +#endif /* #if defined AK8963_SECONDARY */ +#elif defined MPU9250 /* #if defined MPU9150 */ +#ifndef MPU6500 +#define MPU6500 +#endif /* #ifndef MPU6500 */ +#if defined AK8975_SECONDARY +#error "MPU9250 and AK8975_SECONDARY cannot both be defined." +#elif !defined AK8963_SECONDARY /* #if defined AK8975_SECONDARY */ +#define AK8963_SECONDARY +#endif /* #if defined AK8975_SECONDARY */ +#endif /* #if defined MPU9150 */ + +#if defined AK8975_SECONDARY || defined AK8963_SECONDARY +#define AK89xx_SECONDARY +#else +/* #warning "No compass = less profit for Invensense. Lame." */ +#endif + +static int set_int_enable(unsigned char enable); + +/* Hardware registers needed by driver. */ +struct gyro_reg_s { + unsigned char who_am_i; + unsigned char rate_div; + unsigned char lpf; + unsigned char prod_id; + unsigned char user_ctrl; + unsigned char fifo_en; + unsigned char gyro_cfg; + unsigned char accel_cfg; + unsigned char accel_cfg2; + unsigned char lp_accel_odr; + unsigned char motion_thr; + unsigned char motion_dur; + unsigned char fifo_count_h; + unsigned char fifo_r_w; + unsigned char raw_gyro; + unsigned char raw_accel; + unsigned char temp; + unsigned char int_enable; + unsigned char dmp_int_status; + unsigned char int_status; + unsigned char accel_intel; + unsigned char pwr_mgmt_1; + unsigned char pwr_mgmt_2; + unsigned char int_pin_cfg; + unsigned char mem_r_w; + unsigned char accel_offs; + unsigned char i2c_mst; + unsigned char bank_sel; + unsigned char mem_start_addr; + unsigned char prgm_start_h; +#if defined AK89xx_SECONDARY + unsigned char s0_addr; + unsigned char s0_reg; + unsigned char s0_ctrl; + unsigned char s1_addr; + unsigned char s1_reg; + unsigned char s1_ctrl; + unsigned char s4_ctrl; + unsigned char s0_do; + unsigned char s1_do; + unsigned char i2c_delay_ctrl; + unsigned char raw_compass; + /* The I2C_MST_VDDIO bit is in this register. */ + unsigned char yg_offs_tc; +#endif +}; + +/* Information specific to a particular device. */ +struct hw_s { + unsigned char addr; + unsigned short max_fifo; + unsigned char num_reg; + unsigned short temp_sens; + short temp_offset; + unsigned short bank_size; +#if defined AK89xx_SECONDARY + unsigned short compass_fsr; +#endif +}; + +/* When entering motion interrupt mode, the driver keeps track of the + * previous state so that it can be restored at a later time. + * TODO: This is tacky. Fix it. + */ +struct motion_int_cache_s { + unsigned short gyro_fsr; + unsigned char accel_fsr; + unsigned short lpf; + unsigned short sample_rate; + unsigned char sensors_on; + unsigned char fifo_sensors; + unsigned char dmp_on; +}; + +/* Cached chip configuration data. + * TODO: A lot of these can be handled with a bitmask. + */ +struct chip_cfg_s { + /* Matches gyro_cfg >> 3 & 0x03 */ + unsigned char gyro_fsr; + /* Matches accel_cfg >> 3 & 0x03 */ + unsigned char accel_fsr; + /* Enabled sensors. Uses same masks as fifo_en, NOT pwr_mgmt_2. */ + unsigned char sensors; + /* Matches config register. */ + unsigned char lpf; + unsigned char clk_src; + /* Sample rate, NOT rate divider. */ + unsigned short sample_rate; + /* Matches fifo_en register. */ + unsigned char fifo_enable; + /* Matches int enable register. */ + unsigned char int_enable; + /* 1 if devices on auxiliary I2C bus appear on the primary. */ + unsigned char bypass_mode; + /* 1 if half-sensitivity. + * NOTE: This doesn't belong here, but everything else in hw_s is const, + * and this allows us to save some precious RAM. + */ + unsigned char accel_half; + /* 1 if device in low-power accel-only mode. */ + unsigned char lp_accel_mode; + /* 1 if interrupts are only triggered on motion events. */ + unsigned char int_motion_only; + struct motion_int_cache_s cache; + /* 1 for active low interrupts. */ + unsigned char active_low_int; + /* 1 for latched interrupts. */ + unsigned char latched_int; + /* 1 if DMP is enabled. */ + unsigned char dmp_on; + /* Ensures that DMP will only be loaded once. */ + unsigned char dmp_loaded; + /* Sampling rate used when DMP is enabled. */ + unsigned short dmp_sample_rate; +#ifdef AK89xx_SECONDARY + /* Compass sample rate. */ + unsigned short compass_sample_rate; + unsigned char compass_addr; + short mag_sens_adj[3]; +#endif +}; + +/* Information for self-test. */ +struct test_s { + unsigned long gyro_sens; + unsigned long accel_sens; + unsigned char reg_rate_div; + unsigned char reg_lpf; + unsigned char reg_gyro_fsr; + unsigned char reg_accel_fsr; + unsigned short wait_ms; + unsigned char packet_thresh; + float min_dps; + float max_dps; + float max_gyro_var; + float min_g; + float max_g; + float max_accel_var; +#ifdef MPU6500 + float max_g_offset; + unsigned short sample_wait_ms; +#endif +}; + +/* Gyro driver state variables. */ +struct gyro_state_s { + const struct gyro_reg_s *reg; + const struct hw_s *hw; + struct chip_cfg_s chip_cfg; + const struct test_s *test; +}; + +/* Filter configurations. */ +enum lpf_e { + INV_FILTER_256HZ_NOLPF2 = 0, + INV_FILTER_188HZ, + INV_FILTER_98HZ, + INV_FILTER_42HZ, + INV_FILTER_20HZ, + INV_FILTER_10HZ, + INV_FILTER_5HZ, + INV_FILTER_2100HZ_NOLPF, + NUM_FILTER +}; + +/* Full scale ranges. */ +enum gyro_fsr_e { + INV_FSR_250DPS = 0, + INV_FSR_500DPS, + INV_FSR_1000DPS, + INV_FSR_2000DPS, + NUM_GYRO_FSR +}; + +/* Full scale ranges. */ +enum accel_fsr_e { + INV_FSR_2G = 0, + INV_FSR_4G, + INV_FSR_8G, + INV_FSR_16G, + NUM_ACCEL_FSR +}; + +/* Clock sources. */ +enum clock_sel_e { + INV_CLK_INTERNAL = 0, + INV_CLK_PLL, + NUM_CLK +}; + +/* Low-power accel wakeup rates. */ +enum lp_accel_rate_e { +#if defined MPU6050 + INV_LPA_1_25HZ, + INV_LPA_5HZ, + INV_LPA_20HZ, + INV_LPA_40HZ +#elif defined MPU6500 + INV_LPA_0_3125HZ, + INV_LPA_0_625HZ, + INV_LPA_1_25HZ, + INV_LPA_2_5HZ, + INV_LPA_5HZ, + INV_LPA_10HZ, + INV_LPA_20HZ, + INV_LPA_40HZ, + INV_LPA_80HZ, + INV_LPA_160HZ, + INV_LPA_320HZ, + INV_LPA_640HZ +#endif +}; + +#define BIT_I2C_MST_VDDIO (0x80) +#define BIT_FIFO_EN (0x40) +#define BIT_DMP_EN (0x80) +#define BIT_FIFO_RST (0x04) +#define BIT_DMP_RST (0x08) +#define BIT_FIFO_OVERFLOW (0x10) +#define BIT_DATA_RDY_EN (0x01) +#define BIT_DMP_INT_EN (0x02) +#define BIT_MOT_INT_EN (0x40) +#define BITS_FSR (0x18) +#define BITS_LPF (0x07) +#define BITS_HPF (0x07) +#define BITS_CLK (0x07) +#define BIT_FIFO_SIZE_1024 (0x40) +#define BIT_FIFO_SIZE_2048 (0x80) +#define BIT_FIFO_SIZE_4096 (0xC0) +#define BIT_RESET (0x80) +#define BIT_SLEEP (0x40) +#define BIT_S0_DELAY_EN (0x01) +#define BIT_S2_DELAY_EN (0x04) +#define BITS_SLAVE_LENGTH (0x0F) +#define BIT_SLAVE_BYTE_SW (0x40) +#define BIT_SLAVE_GROUP (0x10) +#define BIT_SLAVE_EN (0x80) +#define BIT_I2C_READ (0x80) +#define BITS_I2C_MASTER_DLY (0x1F) +#define BIT_AUX_IF_EN (0x20) +#define BIT_ACTL (0x80) +#define BIT_LATCH_EN (0x20) +#define BIT_ANY_RD_CLR (0x10) +#define BIT_BYPASS_EN (0x02) +#define BITS_WOM_EN (0xC0) +#define BIT_LPA_CYCLE (0x20) +#define BIT_STBY_XA (0x20) +#define BIT_STBY_YA (0x10) +#define BIT_STBY_ZA (0x08) +#define BIT_STBY_XG (0x04) +#define BIT_STBY_YG (0x02) +#define BIT_STBY_ZG (0x01) +#define BIT_STBY_XYZA (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA) +#define BIT_STBY_XYZG (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG) + +#if defined AK8975_SECONDARY +#define SUPPORTS_AK89xx_HIGH_SENS (0x00) +#define AK89xx_FSR (9830) +#elif defined AK8963_SECONDARY +#define SUPPORTS_AK89xx_HIGH_SENS (0x10) +#define AK89xx_FSR (4915) +#endif + +#ifdef AK89xx_SECONDARY +#define AKM_REG_WHOAMI (0x00) + +#define AKM_REG_ST1 (0x02) +#define AKM_REG_HXL (0x03) +#define AKM_REG_ST2 (0x09) + +#define AKM_REG_CNTL (0x0A) +#define AKM_REG_ASTC (0x0C) +#define AKM_REG_ASAX (0x10) +#define AKM_REG_ASAY (0x11) +#define AKM_REG_ASAZ (0x12) + +#define AKM_DATA_READY (0x01) +#define AKM_DATA_OVERRUN (0x02) +#define AKM_OVERFLOW (0x80) +#define AKM_DATA_ERROR (0x40) + +#define AKM_BIT_SELF_TEST (0x40) + +#define AKM_POWER_DOWN (0x00 | SUPPORTS_AK89xx_HIGH_SENS) +#define AKM_SINGLE_MEASUREMENT (0x01 | SUPPORTS_AK89xx_HIGH_SENS) +#define AKM_FUSE_ROM_ACCESS (0x0F | SUPPORTS_AK89xx_HIGH_SENS) +#define AKM_MODE_SELF_TEST (0x08 | SUPPORTS_AK89xx_HIGH_SENS) + +#define AKM_WHOAMI (0x48) +#endif + +#if defined MPU6050 +const struct gyro_reg_s reg = { + .who_am_i = 0x75, + .rate_div = 0x19, + .lpf = 0x1A, + .prod_id = 0x0C, + .user_ctrl = 0x6A, + .fifo_en = 0x23, + .gyro_cfg = 0x1B, + .accel_cfg = 0x1C, + .motion_thr = 0x1F, + .motion_dur = 0x20, + .fifo_count_h = 0x72, + .fifo_r_w = 0x74, + .raw_gyro = 0x43, + .raw_accel = 0x3B, + .temp = 0x41, + .int_enable = 0x38, + .dmp_int_status = 0x39, + .int_status = 0x3A, + .pwr_mgmt_1 = 0x6B, + .pwr_mgmt_2 = 0x6C, + .int_pin_cfg = 0x37, + .mem_r_w = 0x6F, + .accel_offs = 0x06, + .i2c_mst = 0x24, + .bank_sel = 0x6D, + .mem_start_addr = 0x6E, + .prgm_start_h = 0x70 +#ifdef AK89xx_SECONDARY + ,.raw_compass = 0x49, + .yg_offs_tc = 0x01, + .s0_addr = 0x25, + .s0_reg = 0x26, + .s0_ctrl = 0x27, + .s1_addr = 0x28, + .s1_reg = 0x29, + .s1_ctrl = 0x2A, + .s4_ctrl = 0x34, + .s0_do = 0x63, + .s1_do = 0x64, + .i2c_delay_ctrl = 0x67 +#endif +}; +const struct hw_s hw = { + .addr = 0x68, + .max_fifo = 1024, + .num_reg = 118, + .temp_sens = 340, + .temp_offset = -521, + .bank_size = 256 +#if defined AK89xx_SECONDARY + ,.compass_fsr = AK89xx_FSR +#endif +}; + +const struct test_s test = { + .gyro_sens = 32768/250, + .accel_sens = 32768/16, + .reg_rate_div = 0, /* 1kHz. */ + .reg_lpf = 1, /* 188Hz. */ + .reg_gyro_fsr = 0, /* 250dps. */ + .reg_accel_fsr = 0x18, /* 16g. */ + .wait_ms = 50, + .packet_thresh = 5, /* 5% */ + .min_dps = 10.f, + .max_dps = 105.f, + .max_gyro_var = 0.14f, + .min_g = 0.3f, + .max_g = 0.95f, + .max_accel_var = 0.14f +}; + +static struct gyro_state_s st = { + .reg = ®, + .hw = &hw, + .test = &test +}; +#elif defined MPU6500 +const struct gyro_reg_s reg = { + .who_am_i = 0x75, + .rate_div = 0x19, + .lpf = 0x1A, + .prod_id = 0x0C, + .user_ctrl = 0x6A, + .fifo_en = 0x23, + .gyro_cfg = 0x1B, + .accel_cfg = 0x1C, + .accel_cfg2 = 0x1D, + .lp_accel_odr = 0x1E, + .motion_thr = 0x1F, + .motion_dur = 0x20, + .fifo_count_h = 0x72, + .fifo_r_w = 0x74, + .raw_gyro = 0x43, + .raw_accel = 0x3B, + .temp = 0x41, + .int_enable = 0x38, + .dmp_int_status = 0x39, + .int_status = 0x3A, + .accel_intel = 0x69, + .pwr_mgmt_1 = 0x6B, + .pwr_mgmt_2 = 0x6C, + .int_pin_cfg = 0x37, + .mem_r_w = 0x6F, + .accel_offs = 0x77, + .i2c_mst = 0x24, + .bank_sel = 0x6D, + .mem_start_addr = 0x6E, + .prgm_start_h = 0x70 +#ifdef AK89xx_SECONDARY + ,.raw_compass = 0x49, + .s0_addr = 0x25, + .s0_reg = 0x26, + .s0_ctrl = 0x27, + .s1_addr = 0x28, + .s1_reg = 0x29, + .s1_ctrl = 0x2A, + .s4_ctrl = 0x34, + .s0_do = 0x63, + .s1_do = 0x64, + .i2c_delay_ctrl = 0x67 +#endif +}; +const struct hw_s hw = { + .addr = 0x69, + .max_fifo = 1024, + .num_reg = 128, + .temp_sens = 321, + .temp_offset = 0, + .bank_size = 256 +#if defined AK89xx_SECONDARY + ,.compass_fsr = AK89xx_FSR +#endif +}; + +const struct test_s test = { + .gyro_sens = 32768/250, + .accel_sens = 32768/2, //FSR = +-2G = 16384 LSB/G + .reg_rate_div = 0, /* 1kHz. */ + .reg_lpf = 2, /* 92Hz low pass filter*/ + .reg_gyro_fsr = 0, /* 250dps. */ + .reg_accel_fsr = 0x0, /* Accel FSR setting = 2g. */ + .wait_ms = 200, //200ms stabilization time + .packet_thresh = 200, /* 200 samples */ + .min_dps = 20.f, //20 dps for Gyro Criteria C + .max_dps = 60.f, //Must exceed 60 dps threshold for Gyro Criteria B + .max_gyro_var = .5f, //Must exceed +50% variation for Gyro Criteria A + .min_g = .225f, //Accel must exceed Min 225 mg for Criteria B + .max_g = .675f, //Accel cannot exceed Max 675 mg for Criteria B + .max_accel_var = .5f, //Accel must be within 50% variation for Criteria A + .max_g_offset = .5f, //500 mg for Accel Criteria C + .sample_wait_ms = 10 //10ms sample time wait +}; + +static struct gyro_state_s st = { + .reg = ®, + .hw = &hw, + .test = &test +}; +#endif + +#define MAX_PACKET_LENGTH (12) +#ifdef MPU6500 +#define HWST_MAX_PACKET_LENGTH (512) +#endif + +#ifdef AK89xx_SECONDARY +static int setup_compass(void); +#define MAX_COMPASS_SAMPLE_RATE (100) +#endif + +/** + * @brief Enable/disable data ready interrupt. + * If the DMP is on, the DMP interrupt is enabled. Otherwise, the data ready + * interrupt is used. + * @param[in] enable 1 to enable interrupt. + * @return 0 if successful. + */ +static int set_int_enable(unsigned char enable) +{ + unsigned char tmp; + + if (st.chip_cfg.dmp_on) { + if (enable) + tmp = BIT_DMP_INT_EN; + else + tmp = 0x00; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) + return -1; + st.chip_cfg.int_enable = tmp; + } else { + if (!st.chip_cfg.sensors) + return -1; + if (enable && st.chip_cfg.int_enable) + return 0; + if (enable) + tmp = BIT_DATA_RDY_EN; + else + tmp = 0x00; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) + return -1; + st.chip_cfg.int_enable = tmp; + } + return 0; +} + +/** + * @brief Register dump for testing. + * @return 0 if successful. + */ +int mpu_reg_dump(void) +{ + unsigned char ii; + unsigned char data; + + for (ii = 0; ii < st.hw->num_reg; ii++) { + if (ii == st.reg->fifo_r_w || ii == st.reg->mem_r_w) + continue; + if (i2c_read(st.hw->addr, ii, 1, &data)) + return -1; + log_i("%#5x: %#5x\r\n", ii, data); + } + return 0; +} + +/** + * @brief Read from a single register. + * NOTE: The memory and FIFO read/write registers cannot be accessed. + * @param[in] reg Register address. + * @param[out] data Register data. + * @return 0 if successful. + */ +int mpu_read_reg(unsigned char reg, unsigned char *data) +{ + if (reg == st.reg->fifo_r_w || reg == st.reg->mem_r_w) + return -1; + if (reg >= st.hw->num_reg) + return -1; + return i2c_read(st.hw->addr, reg, 1, data); +} + +/** + * @brief Initialize hardware. + * Initial configuration:\n + * Gyro FSR: +/- 2000DPS\n + * Accel FSR +/- 2G\n + * DLPF: 42Hz\n + * FIFO rate: 50Hz\n + * Clock source: Gyro PLL\n + * FIFO: Disabled.\n + * Data ready interrupt: Disabled, active low, unlatched. + * @param[in] int_param Platform-specific parameters to interrupt API. + * @return 0 if successful. + */ +int mpu_init(struct int_param_s *int_param) +{ + unsigned char data[6]; + + /* Reset device. */ + data[0] = BIT_RESET; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + return -1; + delay_ms(100); + + /* Wake up chip. */ + data[0] = 0x00; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + return -1; + + st.chip_cfg.accel_half = 0; + +#ifdef MPU6500 + /* MPU6500 shares 4kB of memory between the DMP and the FIFO. Since the + * first 3kB are needed by the DMP, we'll use the last 1kB for the FIFO. + */ + data[0] = BIT_FIFO_SIZE_1024 | 0x8; + if (i2c_write(st.hw->addr, st.reg->accel_cfg2, 1, data)) + return -1; +#endif + + /* Set to invalid values to ensure no I2C writes are skipped. */ + st.chip_cfg.sensors = 0xFF; + st.chip_cfg.gyro_fsr = 0xFF; + st.chip_cfg.accel_fsr = 0xFF; + st.chip_cfg.lpf = 0xFF; + st.chip_cfg.sample_rate = 0xFFFF; + st.chip_cfg.fifo_enable = 0xFF; + st.chip_cfg.bypass_mode = 0xFF; +#ifdef AK89xx_SECONDARY + st.chip_cfg.compass_sample_rate = 0xFFFF; +#endif + /* mpu_set_sensors always preserves this setting. */ + st.chip_cfg.clk_src = INV_CLK_PLL; + /* Handled in next call to mpu_set_bypass. */ + st.chip_cfg.active_low_int = 1; + st.chip_cfg.latched_int = 0; + st.chip_cfg.int_motion_only = 0; + st.chip_cfg.lp_accel_mode = 0; + memset(&st.chip_cfg.cache, 0, sizeof(st.chip_cfg.cache)); + st.chip_cfg.dmp_on = 0; + st.chip_cfg.dmp_loaded = 0; + st.chip_cfg.dmp_sample_rate = 0; + + if (mpu_set_gyro_fsr(2000)) + return -1; + if (mpu_set_accel_fsr(2)) + return -1; + if (mpu_set_lpf(42)) + return -1; + if (mpu_set_sample_rate(50)) + return -1; + if (mpu_configure_fifo(0)) + return -1; + +#ifndef EMPL_TARGET_STM32F4 + if (int_param) + reg_int_cb(int_param); +#endif + +#ifdef AK89xx_SECONDARY + setup_compass(); + if (mpu_set_compass_sample_rate(10)) + return -1; +#else + /* Already disabled by setup_compass. */ + if (mpu_set_bypass(0)) + return -1; +#endif + + mpu_set_sensors(0); + return 0; +} + +/** + * @brief Enter low-power accel-only mode. + * In low-power accel mode, the chip goes to sleep and only wakes up to sample + * the accelerometer at one of the following frequencies: + * \n MPU6050: 1.25Hz, 5Hz, 20Hz, 40Hz + * \n MPU6500: 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz + * \n If the requested rate is not one listed above, the device will be set to + * the next highest rate. Requesting a rate above the maximum supported + * frequency will result in an error. + * \n To select a fractional wake-up frequency, round down the value passed to + * @e rate. + * @param[in] rate Minimum sampling rate, or zero to disable LP + * accel mode. + * @return 0 if successful. + */ +int mpu_lp_accel_mode(unsigned short rate) +{ + unsigned char tmp[2]; + + if (rate > 40) + return -1; + + if (!rate) { + mpu_set_int_latched(0); + tmp[0] = 0; + tmp[1] = BIT_STBY_XYZG; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) + return -1; + st.chip_cfg.lp_accel_mode = 0; + return 0; + } + /* For LP accel, we automatically configure the hardware to produce latched + * interrupts. In LP accel mode, the hardware cycles into sleep mode before + * it gets a chance to deassert the interrupt pin; therefore, we shift this + * responsibility over to the MCU. + * + * Any register read will clear the interrupt. + */ + mpu_set_int_latched(1); +#if defined MPU6050 + tmp[0] = BIT_LPA_CYCLE; + if (rate == 1) { + tmp[1] = INV_LPA_1_25HZ; + mpu_set_lpf(5); + } else if (rate <= 5) { + tmp[1] = INV_LPA_5HZ; + mpu_set_lpf(5); + } else if (rate <= 20) { + tmp[1] = INV_LPA_20HZ; + mpu_set_lpf(10); + } else { + tmp[1] = INV_LPA_40HZ; + mpu_set_lpf(20); + } + tmp[1] = (tmp[1] << 6) | BIT_STBY_XYZG; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) + return -1; +#elif defined MPU6500 + /* Set wake frequency. */ + if (rate == 1) + tmp[0] = INV_LPA_1_25HZ; + else if (rate == 2) + tmp[0] = INV_LPA_2_5HZ; + else if (rate <= 5) + tmp[0] = INV_LPA_5HZ; + else if (rate <= 10) + tmp[0] = INV_LPA_10HZ; + else if (rate <= 20) + tmp[0] = INV_LPA_20HZ; + else if (rate <= 40) + tmp[0] = INV_LPA_40HZ; + else if (rate <= 80) + tmp[0] = INV_LPA_80HZ; + else if (rate <= 160) + tmp[0] = INV_LPA_160HZ; + else if (rate <= 320) + tmp[0] = INV_LPA_320HZ; + else + tmp[0] = INV_LPA_640HZ; + if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, tmp)) + return -1; + tmp[0] = BIT_LPA_CYCLE; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, tmp)) + return -1; +#endif + st.chip_cfg.sensors = INV_XYZ_ACCEL; + st.chip_cfg.clk_src = 0; + st.chip_cfg.lp_accel_mode = 1; + mpu_configure_fifo(0); + + return 0; +} + +/** + * @brief Read raw gyro data directly from the registers. + * @param[out] data Raw data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. Null if not needed. + * @return 0 if successful. + */ +int mpu_get_gyro_reg(short *data, unsigned long *timestamp) +{ + unsigned char tmp[6]; + + if (!(st.chip_cfg.sensors & INV_XYZ_GYRO)) + return -1; + + if (i2c_read(st.hw->addr, st.reg->raw_gyro, 6, tmp)) + return -1; + data[0] = (tmp[0] << 8) | tmp[1]; + data[1] = (tmp[2] << 8) | tmp[3]; + data[2] = (tmp[4] << 8) | tmp[5]; + if (timestamp) + get_ms(timestamp); + return 0; +} + +/** + * @brief Read raw accel data directly from the registers. + * @param[out] data Raw data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. Null if not needed. + * @return 0 if successful. + */ +int mpu_get_accel_reg(short *data, unsigned long *timestamp) +{ + unsigned char tmp[6]; + + if (!(st.chip_cfg.sensors & INV_XYZ_ACCEL)) + return -1; + + if (i2c_read(st.hw->addr, st.reg->raw_accel, 6, tmp)) + return -1; + data[0] = (tmp[0] << 8) | tmp[1]; + data[1] = (tmp[2] << 8) | tmp[3]; + data[2] = (tmp[4] << 8) | tmp[5]; + if (timestamp) + get_ms(timestamp); + return 0; +} + +/** + * @brief Read temperature data directly from the registers. + * @param[out] data Data in q16 format. + * @param[out] timestamp Timestamp in milliseconds. Null if not needed. + * @return 0 if successful. + */ +int mpu_get_temperature(long *data, unsigned long *timestamp) +{ + unsigned char tmp[2]; + short raw; + + if (!(st.chip_cfg.sensors)) + return -1; + + if (i2c_read(st.hw->addr, st.reg->temp, 2, tmp)) + return -1; + raw = (tmp[0] << 8) | tmp[1]; + if (timestamp) + get_ms(timestamp); + + data[0] = (long)((35 + ((raw - (float)st.hw->temp_offset) / st.hw->temp_sens)) * 65536L); + return 0; +} + +/** + * @brief Read biases to the accel bias 6500 registers. + * This function reads from the MPU6500 accel offset cancellations registers. + * The format are G in +-8G format. The register is initialized with OTP + * factory trim values. + * @param[in] accel_bias returned structure with the accel bias + * @return 0 if successful. + */ +int mpu_read_6500_accel_bias(long *accel_bias) { + unsigned char data[6]; + if (i2c_read(st.hw->addr, 0x77, 2, &data[0])) + return -1; + if (i2c_read(st.hw->addr, 0x7A, 2, &data[2])) + return -1; + if (i2c_read(st.hw->addr, 0x7D, 2, &data[4])) + return -1; + accel_bias[0] = ((long)data[0]<<8) | data[1]; + accel_bias[1] = ((long)data[2]<<8) | data[3]; + accel_bias[2] = ((long)data[4]<<8) | data[5]; + return 0; +} + +/** + * @brief Read biases to the accel bias 6050 registers. + * This function reads from the MPU6050 accel offset cancellations registers. + * The format are G in +-8G format. The register is initialized with OTP + * factory trim values. + * @param[in] accel_bias returned structure with the accel bias + * @return 0 if successful. + */ +int mpu_read_6050_accel_bias(long *accel_bias) { + unsigned char data[6]; + if (i2c_read(st.hw->addr, 0x06, 2, &data[0])) + return -1; + if (i2c_read(st.hw->addr, 0x08, 2, &data[2])) + return -1; + if (i2c_read(st.hw->addr, 0x0A, 2, &data[4])) + return -1; + accel_bias[0] = ((long)data[0]<<8) | data[1]; + accel_bias[1] = ((long)data[2]<<8) | data[3]; + accel_bias[2] = ((long)data[4]<<8) | data[5]; + return 0; +} + +int mpu_read_6500_gyro_bias(long *gyro_bias) { + unsigned char data[6]; + if (i2c_read(st.hw->addr, 0x13, 2, &data[0])) + return -1; + if (i2c_read(st.hw->addr, 0x15, 2, &data[2])) + return -1; + if (i2c_read(st.hw->addr, 0x17, 2, &data[4])) + return -1; + gyro_bias[0] = ((long)data[0]<<8) | data[1]; + gyro_bias[1] = ((long)data[2]<<8) | data[3]; + gyro_bias[2] = ((long)data[4]<<8) | data[5]; + return 0; +} + +/** + * @brief Push biases to the gyro bias 6500/6050 registers. + * This function expects biases relative to the current sensor output, and + * these biases will be added to the factory-supplied values. Bias inputs are LSB + * in +-1000dps format. + * @param[in] gyro_bias New biases. + * @return 0 if successful. + */ +int mpu_set_gyro_bias_reg(long *gyro_bias) +{ + unsigned char data[6] = {0, 0, 0, 0, 0, 0}; + int i=0; + for(i=0;i<3;i++) { + gyro_bias[i]= (-gyro_bias[i]); + } + data[0] = (gyro_bias[0] >> 8) & 0xff; + data[1] = (gyro_bias[0]) & 0xff; + data[2] = (gyro_bias[1] >> 8) & 0xff; + data[3] = (gyro_bias[1]) & 0xff; + data[4] = (gyro_bias[2] >> 8) & 0xff; + data[5] = (gyro_bias[2]) & 0xff; + if (i2c_write(st.hw->addr, 0x13, 2, &data[0])) + return -1; + if (i2c_write(st.hw->addr, 0x15, 2, &data[2])) + return -1; + if (i2c_write(st.hw->addr, 0x17, 2, &data[4])) + return -1; + return 0; +} + +/** + * @brief Push biases to the accel bias 6050 registers. + * This function expects biases relative to the current sensor output, and + * these biases will be added to the factory-supplied values. Bias inputs are LSB + * in +-16G format. + * @param[in] accel_bias New biases. + * @return 0 if successful. + */ +int mpu_set_accel_bias_6050_reg(const long *accel_bias) { + unsigned char data[6] = {0, 0, 0, 0, 0, 0}; + long accel_reg_bias[3] = {0, 0, 0}; + + if(mpu_read_6050_accel_bias(accel_reg_bias)) + return -1; + + accel_reg_bias[0] -= (accel_bias[0] & ~1); + accel_reg_bias[1] -= (accel_bias[1] & ~1); + accel_reg_bias[2] -= (accel_bias[2] & ~1); + + data[0] = (accel_reg_bias[0] >> 8) & 0xff; + data[1] = (accel_reg_bias[0]) & 0xff; + data[2] = (accel_reg_bias[1] >> 8) & 0xff; + data[3] = (accel_reg_bias[1]) & 0xff; + data[4] = (accel_reg_bias[2] >> 8) & 0xff; + data[5] = (accel_reg_bias[2]) & 0xff; + + if (i2c_write(st.hw->addr, 0x06, 2, &data[0])) + return -1; + if (i2c_write(st.hw->addr, 0x08, 2, &data[2])) + return -1; + if (i2c_write(st.hw->addr, 0x0A, 2, &data[4])) + return -1; + + return 0; +} + + + +/** + * @brief Push biases to the accel bias 6500 registers. + * This function expects biases relative to the current sensor output, and + * these biases will be added to the factory-supplied values. Bias inputs are LSB + * in +-16G format. + * @param[in] accel_bias New biases. + * @return 0 if successful. + */ +int mpu_set_accel_bias_6500_reg(const long *accel_bias) { + unsigned char data[6] = {0, 0, 0, 0, 0, 0}; + long accel_reg_bias[3] = {0, 0, 0}; + + if(mpu_read_6500_accel_bias(accel_reg_bias)) + return -1; + + // Preserve bit 0 of factory value (for temperature compensation) + accel_reg_bias[0] -= (accel_bias[0] & ~1); + accel_reg_bias[1] -= (accel_bias[1] & ~1); + accel_reg_bias[2] -= (accel_bias[2] & ~1); + + data[0] = (accel_reg_bias[0] >> 8) & 0xff; + data[1] = (accel_reg_bias[0]) & 0xff; + data[2] = (accel_reg_bias[1] >> 8) & 0xff; + data[3] = (accel_reg_bias[1]) & 0xff; + data[4] = (accel_reg_bias[2] >> 8) & 0xff; + data[5] = (accel_reg_bias[2]) & 0xff; + + if (i2c_write(st.hw->addr, 0x77, 2, &data[0])) + return -1; + if (i2c_write(st.hw->addr, 0x7A, 2, &data[2])) + return -1; + if (i2c_write(st.hw->addr, 0x7D, 2, &data[4])) + return -1; + + return 0; +} + + +/** + * @brief Reset FIFO read/write pointers. + * @return 0 if successful. + */ +int mpu_reset_fifo(void) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + data = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + + if (st.chip_cfg.dmp_on) { + data = BIT_FIFO_RST | BIT_DMP_RST; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + delay_ms(50); + data = BIT_DMP_EN | BIT_FIFO_EN; + if (st.chip_cfg.sensors & INV_XYZ_COMPASS) + data |= BIT_AUX_IF_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + if (st.chip_cfg.int_enable) + data = BIT_DMP_INT_EN; + else + data = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) + return -1; + data = 0; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data)) + return -1; + } else { + data = BIT_FIFO_RST; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + if (st.chip_cfg.bypass_mode || !(st.chip_cfg.sensors & INV_XYZ_COMPASS)) + data = BIT_FIFO_EN; + else + data = BIT_FIFO_EN | BIT_AUX_IF_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + delay_ms(50); + if (st.chip_cfg.int_enable) + data = BIT_DATA_RDY_EN; + else + data = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &st.chip_cfg.fifo_enable)) + return -1; + } + return 0; +} + +/** + * @brief Get the gyro full-scale range. + * @param[out] fsr Current full-scale range. + * @return 0 if successful. + */ +int mpu_get_gyro_fsr(unsigned short *fsr) +{ + switch (st.chip_cfg.gyro_fsr) { + case INV_FSR_250DPS: + fsr[0] = 250; + break; + case INV_FSR_500DPS: + fsr[0] = 500; + break; + case INV_FSR_1000DPS: + fsr[0] = 1000; + break; + case INV_FSR_2000DPS: + fsr[0] = 2000; + break; + default: + fsr[0] = 0; + break; + } + return 0; +} + +/** + * @brief Set the gyro full-scale range. + * @param[in] fsr Desired full-scale range. + * @return 0 if successful. + */ +int mpu_set_gyro_fsr(unsigned short fsr) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + switch (fsr) { + case 250: + data = INV_FSR_250DPS << 3; + break; + case 500: + data = INV_FSR_500DPS << 3; + break; + case 1000: + data = INV_FSR_1000DPS << 3; + break; + case 2000: + data = INV_FSR_2000DPS << 3; + break; + default: + return -1; + } + + if (st.chip_cfg.gyro_fsr == (data >> 3)) + return 0; + if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, &data)) + return -1; + st.chip_cfg.gyro_fsr = data >> 3; + return 0; +} + +/** + * @brief Get the accel full-scale range. + * @param[out] fsr Current full-scale range. + * @return 0 if successful. + */ +int mpu_get_accel_fsr(unsigned char *fsr) +{ + switch (st.chip_cfg.accel_fsr) { + case INV_FSR_2G: + fsr[0] = 2; + break; + case INV_FSR_4G: + fsr[0] = 4; + break; + case INV_FSR_8G: + fsr[0] = 8; + break; + case INV_FSR_16G: + fsr[0] = 16; + break; + default: + return -1; + } + if (st.chip_cfg.accel_half) + fsr[0] <<= 1; + return 0; +} + +/** + * @brief Set the accel full-scale range. + * @param[in] fsr Desired full-scale range. + * @return 0 if successful. + */ +int mpu_set_accel_fsr(unsigned char fsr) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + switch (fsr) { + case 2: + data = INV_FSR_2G << 3; + break; + case 4: + data = INV_FSR_4G << 3; + break; + case 8: + data = INV_FSR_8G << 3; + break; + case 16: + data = INV_FSR_16G << 3; + break; + default: + return -1; + } + + if (st.chip_cfg.accel_fsr == (data >> 3)) + return 0; + if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, &data)) + return -1; + st.chip_cfg.accel_fsr = data >> 3; + return 0; +} + +/** + * @brief Get the current DLPF setting. + * @param[out] lpf Current LPF setting. + * 0 if successful. + */ +int mpu_get_lpf(unsigned short *lpf) +{ + switch (st.chip_cfg.lpf) { + case INV_FILTER_188HZ: + lpf[0] = 188; + break; + case INV_FILTER_98HZ: + lpf[0] = 98; + break; + case INV_FILTER_42HZ: + lpf[0] = 42; + break; + case INV_FILTER_20HZ: + lpf[0] = 20; + break; + case INV_FILTER_10HZ: + lpf[0] = 10; + break; + case INV_FILTER_5HZ: + lpf[0] = 5; + break; + case INV_FILTER_256HZ_NOLPF2: + case INV_FILTER_2100HZ_NOLPF: + default: + lpf[0] = 0; + break; + } + return 0; +} + +/** + * @brief Set digital low pass filter. + * The following LPF settings are supported: 188, 98, 42, 20, 10, 5. + * @param[in] lpf Desired LPF setting. + * @return 0 if successful. + */ +int mpu_set_lpf(unsigned short lpf) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + if (lpf >= 188) + data = INV_FILTER_188HZ; + else if (lpf >= 98) + data = INV_FILTER_98HZ; + else if (lpf >= 42) + data = INV_FILTER_42HZ; + else if (lpf >= 20) + data = INV_FILTER_20HZ; + else if (lpf >= 10) + data = INV_FILTER_10HZ; + else + data = INV_FILTER_5HZ; + + if (st.chip_cfg.lpf == data) + return 0; + if (i2c_write(st.hw->addr, st.reg->lpf, 1, &data)) + return -1; + st.chip_cfg.lpf = data; + return 0; +} + +/** + * @brief Get sampling rate. + * @param[out] rate Current sampling rate (Hz). + * @return 0 if successful. + */ +int mpu_get_sample_rate(unsigned short *rate) +{ + if (st.chip_cfg.dmp_on) + return -1; + else + rate[0] = st.chip_cfg.sample_rate; + return 0; +} + +/** + * @brief Set sampling rate. + * Sampling rate must be between 4Hz and 1kHz. + * @param[in] rate Desired sampling rate (Hz). + * @return 0 if successful. + */ +int mpu_set_sample_rate(unsigned short rate) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + if (st.chip_cfg.dmp_on) + return -1; + else { + if (st.chip_cfg.lp_accel_mode) { + if (rate && (rate <= 40)) { + /* Just stay in low-power accel mode. */ + mpu_lp_accel_mode(rate); + return 0; + } + /* Requested rate exceeds the allowed frequencies in LP accel mode, + * switch back to full-power mode. + */ + mpu_lp_accel_mode(0); + } + if (rate < 4) + rate = 4; + else if (rate > 1000) + rate = 1000; + + data = 1000 / rate - 1; + if (i2c_write(st.hw->addr, st.reg->rate_div, 1, &data)) + return -1; + + st.chip_cfg.sample_rate = 1000 / (1 + data); + +#ifdef AK89xx_SECONDARY + mpu_set_compass_sample_rate(min(st.chip_cfg.compass_sample_rate, MAX_COMPASS_SAMPLE_RATE)); +#endif + + /* Automatically set LPF to 1/2 sampling rate. */ + mpu_set_lpf(st.chip_cfg.sample_rate >> 1); + return 0; + } +} + +/** + * @brief Get compass sampling rate. + * @param[out] rate Current compass sampling rate (Hz). + * @return 0 if successful. + */ +int mpu_get_compass_sample_rate(unsigned short *rate) +{ +#ifdef AK89xx_SECONDARY + rate[0] = st.chip_cfg.compass_sample_rate; + return 0; +#else + rate[0] = 0; + return -1; +#endif +} + +/** + * @brief Set compass sampling rate. + * The compass on the auxiliary I2C bus is read by the MPU hardware at a + * maximum of 100Hz. The actual rate can be set to a fraction of the gyro + * sampling rate. + * + * \n WARNING: The new rate may be different than what was requested. Call + * mpu_get_compass_sample_rate to check the actual setting. + * @param[in] rate Desired compass sampling rate (Hz). + * @return 0 if successful. + */ +int mpu_set_compass_sample_rate(unsigned short rate) +{ +#ifdef AK89xx_SECONDARY + unsigned char div; + if (!rate || rate > st.chip_cfg.sample_rate || rate > MAX_COMPASS_SAMPLE_RATE) + return -1; + + div = st.chip_cfg.sample_rate / rate - 1; + if (i2c_write(st.hw->addr, st.reg->s4_ctrl, 1, &div)) + return -1; + st.chip_cfg.compass_sample_rate = st.chip_cfg.sample_rate / (div + 1); + return 0; +#else + return -1; +#endif +} + +/** + * @brief Get gyro sensitivity scale factor. + * @param[out] sens Conversion from hardware units to dps. + * @return 0 if successful. + */ +int mpu_get_gyro_sens(float *sens) +{ + switch (st.chip_cfg.gyro_fsr) { + case INV_FSR_250DPS: + sens[0] = 131.f; + break; + case INV_FSR_500DPS: + sens[0] = 65.5f; + break; + case INV_FSR_1000DPS: + sens[0] = 32.8f; + break; + case INV_FSR_2000DPS: + sens[0] = 16.4f; + break; + default: + return -1; + } + return 0; +} + +/** + * @brief Get accel sensitivity scale factor. + * @param[out] sens Conversion from hardware units to g's. + * @return 0 if successful. + */ +int mpu_get_accel_sens(unsigned short *sens) +{ + switch (st.chip_cfg.accel_fsr) { + case INV_FSR_2G: + sens[0] = 16384; + break; + case INV_FSR_4G: + sens[0] = 8192; + break; + case INV_FSR_8G: + sens[0] = 4096; + break; + case INV_FSR_16G: + sens[0] = 2048; + break; + default: + return -1; + } + if (st.chip_cfg.accel_half) + sens[0] >>= 1; + return 0; +} + +/** + * @brief Get current FIFO configuration. + * @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * @param[out] sensors Mask of sensors in FIFO. + * @return 0 if successful. + */ +int mpu_get_fifo_config(unsigned char *sensors) +{ + sensors[0] = st.chip_cfg.fifo_enable; + return 0; +} + +/** + * @brief Select which sensors are pushed to FIFO. + * @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * @param[in] sensors Mask of sensors to push to FIFO. + * @return 0 if successful. + */ +int mpu_configure_fifo(unsigned char sensors) +{ + unsigned char prev; + int result = 0; + + /* Compass data isn't going into the FIFO. Stop trying. */ + sensors &= ~INV_XYZ_COMPASS; + + if (st.chip_cfg.dmp_on) + return 0; + else { + if (!(st.chip_cfg.sensors)) + return -1; + prev = st.chip_cfg.fifo_enable; + st.chip_cfg.fifo_enable = sensors & st.chip_cfg.sensors; + if (st.chip_cfg.fifo_enable != sensors) + /* You're not getting what you asked for. Some sensors are + * asleep. + */ + result = -1; + else + result = 0; + if (sensors || st.chip_cfg.lp_accel_mode) + set_int_enable(1); + else + set_int_enable(0); + if (sensors) { + if (mpu_reset_fifo()) { + st.chip_cfg.fifo_enable = prev; + return -1; + } + } + } + + return result; +} + +/** + * @brief Get current power state. + * @param[in] power_on 1 if turned on, 0 if suspended. + * @return 0 if successful. + */ +int mpu_get_power_state(unsigned char *power_on) +{ + if (st.chip_cfg.sensors) + power_on[0] = 1; + else + power_on[0] = 0; + return 0; +} + +/** + * @brief Turn specific sensors on/off. + * @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * \n INV_XYZ_COMPASS + * @param[in] sensors Mask of sensors to wake. + * @return 0 if successful. + */ +int mpu_set_sensors(unsigned char sensors) +{ + unsigned char data; +#ifdef AK89xx_SECONDARY + unsigned char user_ctrl; +#endif + + if (sensors & INV_XYZ_GYRO) + data = INV_CLK_PLL; + else if (sensors) + data = 0; + else + data = BIT_SLEEP; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, &data)) { + st.chip_cfg.sensors = 0; + return -1; + } + st.chip_cfg.clk_src = data & ~BIT_SLEEP; + + data = 0; + if (!(sensors & INV_X_GYRO)) + data |= BIT_STBY_XG; + if (!(sensors & INV_Y_GYRO)) + data |= BIT_STBY_YG; + if (!(sensors & INV_Z_GYRO)) + data |= BIT_STBY_ZG; + if (!(sensors & INV_XYZ_ACCEL)) + data |= BIT_STBY_XYZA; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_2, 1, &data)) { + st.chip_cfg.sensors = 0; + return -1; + } + + if (sensors && (sensors != INV_XYZ_ACCEL)) + /* Latched interrupts only used in LP accel mode. */ + mpu_set_int_latched(0); + +#ifdef AK89xx_SECONDARY +#ifdef AK89xx_BYPASS + if (sensors & INV_XYZ_COMPASS) + mpu_set_bypass(1); + else + mpu_set_bypass(0); +#else + if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) + return -1; + /* Handle AKM power management. */ + if (sensors & INV_XYZ_COMPASS) { + data = AKM_SINGLE_MEASUREMENT; + user_ctrl |= BIT_AUX_IF_EN; + } else { + data = AKM_POWER_DOWN; + user_ctrl &= ~BIT_AUX_IF_EN; + } + if (st.chip_cfg.dmp_on) + user_ctrl |= BIT_DMP_EN; + else + user_ctrl &= ~BIT_DMP_EN; + if (i2c_write(st.hw->addr, st.reg->s1_do, 1, &data)) + return -1; + /* Enable/disable I2C master mode. */ + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) + return -1; +#endif +#endif + + st.chip_cfg.sensors = sensors; + st.chip_cfg.lp_accel_mode = 0; + delay_ms(50); + return 0; +} + +/** + * @brief Read the MPU interrupt status registers. + * @param[out] status Mask of interrupt bits. + * @return 0 if successful. + */ +int mpu_get_int_status(short *status) +{ + unsigned char tmp[2]; + if (!st.chip_cfg.sensors) + return -1; + if (i2c_read(st.hw->addr, st.reg->dmp_int_status, 2, tmp)) + return -1; + status[0] = (tmp[0] << 8) | tmp[1]; + return 0; +} + +/** + * @brief Get one packet from the FIFO. + * If @e sensors does not contain a particular sensor, disregard the data + * returned to that pointer. + * \n @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * \n If the FIFO has no new data, @e sensors will be zero. + * \n If the FIFO is disabled, @e sensors will be zero and this function will + * return a non-zero error code. + * @param[out] gyro Gyro data in hardware units. + * @param[out] accel Accel data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. + * @param[out] sensors Mask of sensors read from FIFO. + * @param[out] more Number of remaining packets. + * @return 0 if successful. + */ +int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, + unsigned char *sensors, unsigned char *more) +{ + /* Assumes maximum packet size is gyro (6) + accel (6). */ + unsigned char data[MAX_PACKET_LENGTH]; + unsigned char packet_size = 0; + unsigned short fifo_count, index = 0; + + if (st.chip_cfg.dmp_on) + return -1; + + sensors[0] = 0; + if (!st.chip_cfg.sensors) + return -1; + if (!st.chip_cfg.fifo_enable) + return -1; + + if (st.chip_cfg.fifo_enable & INV_X_GYRO) + packet_size += 2; + if (st.chip_cfg.fifo_enable & INV_Y_GYRO) + packet_size += 2; + if (st.chip_cfg.fifo_enable & INV_Z_GYRO) + packet_size += 2; + if (st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) + packet_size += 6; + + if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) + return -1; + fifo_count = (data[0] << 8) | data[1]; + if (fifo_count < packet_size) + return 0; +// log_i("FIFO count: %hd\n", fifo_count); + if (fifo_count > (st.hw->max_fifo >> 1)) { + /* FIFO is 50% full, better check overflow bit. */ + if (i2c_read(st.hw->addr, st.reg->int_status, 1, data)) + return -1; + if (data[0] & BIT_FIFO_OVERFLOW) { + mpu_reset_fifo(); + return -2; + } + } + get_ms((unsigned long*)timestamp); + + if (i2c_read(st.hw->addr, st.reg->fifo_r_w, packet_size, data)) + return -1; + more[0] = fifo_count / packet_size - 1; + sensors[0] = 0; + + if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) { + accel[0] = (data[index+0] << 8) | data[index+1]; + accel[1] = (data[index+2] << 8) | data[index+3]; + accel[2] = (data[index+4] << 8) | data[index+5]; + sensors[0] |= INV_XYZ_ACCEL; + index += 6; + } + if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_X_GYRO) { + gyro[0] = (data[index+0] << 8) | data[index+1]; + sensors[0] |= INV_X_GYRO; + index += 2; + } + if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Y_GYRO) { + gyro[1] = (data[index+0] << 8) | data[index+1]; + sensors[0] |= INV_Y_GYRO; + index += 2; + } + if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Z_GYRO) { + gyro[2] = (data[index+0] << 8) | data[index+1]; + sensors[0] |= INV_Z_GYRO; + index += 2; + } + + return 0; +} + +/** + * @brief Get one unparsed packet from the FIFO. + * This function should be used if the packet is to be parsed elsewhere. + * @param[in] length Length of one FIFO packet. + * @param[in] data FIFO packet. + * @param[in] more Number of remaining packets. + */ +int mpu_read_fifo_stream(unsigned short length, unsigned char *data, + unsigned char *more) +{ + unsigned char tmp[2]; + unsigned short fifo_count; + if (!st.chip_cfg.dmp_on) + return -1; + if (!st.chip_cfg.sensors) + return -1; + + if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, tmp)) + return -1; + fifo_count = (tmp[0] << 8) | tmp[1]; + if (fifo_count < length) { + more[0] = 0; + return -1; + } + if (fifo_count > (st.hw->max_fifo >> 1)) { + /* FIFO is 50% full, better check overflow bit. */ + if (i2c_read(st.hw->addr, st.reg->int_status, 1, tmp)) + return -1; + if (tmp[0] & BIT_FIFO_OVERFLOW) { + mpu_reset_fifo(); + return -2; + } + } + + if (i2c_read(st.hw->addr, st.reg->fifo_r_w, length, data)) + return -1; + more[0] = fifo_count / length - 1; + return 0; +} + +/** + * @brief Set device to bypass mode. + * @param[in] bypass_on 1 to enable bypass mode. + * @return 0 if successful. + */ +int mpu_set_bypass(unsigned char bypass_on) +{ + unsigned char tmp; + + if (st.chip_cfg.bypass_mode == bypass_on) + return 0; + + if (bypass_on) { + if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) + return -1; + tmp &= ~BIT_AUX_IF_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) + return -1; + delay_ms(3); + tmp = BIT_BYPASS_EN; + if (st.chip_cfg.active_low_int) + tmp |= BIT_ACTL; + if (st.chip_cfg.latched_int) + tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; + if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) + return -1; + } else { + /* Enable I2C master mode if compass is being used. */ + if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) + return -1; + if (st.chip_cfg.sensors & INV_XYZ_COMPASS) + tmp |= BIT_AUX_IF_EN; + else + tmp &= ~BIT_AUX_IF_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) + return -1; + delay_ms(3); + if (st.chip_cfg.active_low_int) + tmp = BIT_ACTL; + else + tmp = 0; + if (st.chip_cfg.latched_int) + tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; + if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) + return -1; + } + st.chip_cfg.bypass_mode = bypass_on; + return 0; +} + +/** + * @brief Set interrupt level. + * @param[in] active_low 1 for active low, 0 for active high. + * @return 0 if successful. + */ +int mpu_set_int_level(unsigned char active_low) +{ + st.chip_cfg.active_low_int = active_low; + return 0; +} + +/** + * @brief Enable latched interrupts. + * Any MPU register will clear the interrupt. + * @param[in] enable 1 to enable, 0 to disable. + * @return 0 if successful. + */ +int mpu_set_int_latched(unsigned char enable) +{ + unsigned char tmp; + if (st.chip_cfg.latched_int == enable) + return 0; + + if (enable) + tmp = BIT_LATCH_EN | BIT_ANY_RD_CLR; + else + tmp = 0; + if (st.chip_cfg.bypass_mode) + tmp |= BIT_BYPASS_EN; + if (st.chip_cfg.active_low_int) + tmp |= BIT_ACTL; + if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) + return -1; + st.chip_cfg.latched_int = enable; + return 0; +} + +#ifdef MPU6050 +static int get_accel_prod_shift(float *st_shift) +{ + unsigned char tmp[4], shift_code[3], ii; + + if (i2c_read(st.hw->addr, 0x0D, 4, tmp)) + return 0x07; + + shift_code[0] = ((tmp[0] & 0xE0) >> 3) | ((tmp[3] & 0x30) >> 4); + shift_code[1] = ((tmp[1] & 0xE0) >> 3) | ((tmp[3] & 0x0C) >> 2); + shift_code[2] = ((tmp[2] & 0xE0) >> 3) | (tmp[3] & 0x03); + for (ii = 0; ii < 3; ii++) { + if (!shift_code[ii]) { + st_shift[ii] = 0.f; + continue; + } + /* Equivalent to.. + * st_shift[ii] = 0.34f * powf(0.92f/0.34f, (shift_code[ii]-1) / 30.f) + */ + st_shift[ii] = 0.34f; + while (--shift_code[ii]) + st_shift[ii] *= 1.034f; + } + return 0; +} + +static int accel_self_test(long *bias_regular, long *bias_st) +{ + int jj, result = 0; + float st_shift[3], st_shift_cust, st_shift_var; + + get_accel_prod_shift(st_shift); + for(jj = 0; jj < 3; jj++) { + st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; + if (st_shift[jj]) { + st_shift_var = st_shift_cust / st_shift[jj] - 1.f; + if (fabs(st_shift_var) > test.max_accel_var) + result |= 1 << jj; + } else if ((st_shift_cust < test.min_g) || + (st_shift_cust > test.max_g)) + result |= 1 << jj; + } + + return result; +} + +static int gyro_self_test(long *bias_regular, long *bias_st) +{ + int jj, result = 0; + unsigned char tmp[3]; + float st_shift, st_shift_cust, st_shift_var; + + if (i2c_read(st.hw->addr, 0x0D, 3, tmp)) + return 0x07; + + tmp[0] &= 0x1F; + tmp[1] &= 0x1F; + tmp[2] &= 0x1F; + + for (jj = 0; jj < 3; jj++) { + st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; + if (tmp[jj]) { + st_shift = 3275.f / test.gyro_sens; + while (--tmp[jj]) + st_shift *= 1.046f; + st_shift_var = st_shift_cust / st_shift - 1.f; + if (fabs(st_shift_var) > test.max_gyro_var) + result |= 1 << jj; + } else if ((st_shift_cust < test.min_dps) || + (st_shift_cust > test.max_dps)) + result |= 1 << jj; + } + return result; +} + +#endif +#ifdef AK89xx_SECONDARY +static int compass_self_test(void) +{ + unsigned char tmp[6]; + unsigned char tries = 10; + int result = 0x07; + short data; + + mpu_set_bypass(1); + + tmp[0] = AKM_POWER_DOWN; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) + return 0x07; + tmp[0] = AKM_BIT_SELF_TEST; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp)) + goto AKM_restore; + tmp[0] = AKM_MODE_SELF_TEST; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) + goto AKM_restore; + + do { + delay_ms(10); + if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 1, tmp)) + goto AKM_restore; + if (tmp[0] & AKM_DATA_READY) + break; + } while (tries--); + if (!(tmp[0] & AKM_DATA_READY)) + goto AKM_restore; + + if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_HXL, 6, tmp)) + goto AKM_restore; + + result = 0; +#if defined MPU9150 + data = (short)(tmp[1] << 8) | tmp[0]; + if ((data > 100) || (data < -100)) + result |= 0x01; + data = (short)(tmp[3] << 8) | tmp[2]; + if ((data > 100) || (data < -100)) + result |= 0x02; + data = (short)(tmp[5] << 8) | tmp[4]; + if ((data > -300) || (data < -1000)) + result |= 0x04; +#elif defined MPU9250 + data = (short)(tmp[1] << 8) | tmp[0]; + if ((data > 200) || (data < -200)) + result |= 0x01; + data = (short)(tmp[3] << 8) | tmp[2]; + if ((data > 200) || (data < -200)) + result |= 0x02; + data = (short)(tmp[5] << 8) | tmp[4]; + if ((data > -800) || (data < -3200)) + result |= 0x04; +#endif +AKM_restore: + tmp[0] = 0 | SUPPORTS_AK89xx_HIGH_SENS; + i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp); + tmp[0] = SUPPORTS_AK89xx_HIGH_SENS; + i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp); + mpu_set_bypass(0); + return result; +} +#endif + +static int get_st_biases(long *gyro, long *accel, unsigned char hw_test) +{ + unsigned char data[MAX_PACKET_LENGTH]; + unsigned char packet_count, ii; + unsigned short fifo_count; + + data[0] = 0x01; + data[1] = 0; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) + return -1; + delay_ms(200); + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + data[0] = BIT_FIFO_RST | BIT_DMP_RST; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + delay_ms(15); + data[0] = st.test->reg_lpf; + if (i2c_write(st.hw->addr, st.reg->lpf, 1, data)) + return -1; + data[0] = st.test->reg_rate_div; + if (i2c_write(st.hw->addr, st.reg->rate_div, 1, data)) + return -1; + if (hw_test) + data[0] = st.test->reg_gyro_fsr | 0xE0; + else + data[0] = st.test->reg_gyro_fsr; + if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, data)) + return -1; + + if (hw_test) + data[0] = st.test->reg_accel_fsr | 0xE0; + else + data[0] = test.reg_accel_fsr; + if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data)) + return -1; + if (hw_test) + delay_ms(200); + + /* Fill FIFO for test.wait_ms milliseconds. */ + data[0] = BIT_FIFO_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + + data[0] = INV_XYZ_GYRO | INV_XYZ_ACCEL; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + delay_ms(test.wait_ms); + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + + if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) + return -1; + + fifo_count = (data[0] << 8) | data[1]; + packet_count = fifo_count / MAX_PACKET_LENGTH; + gyro[0] = gyro[1] = gyro[2] = 0; + accel[0] = accel[1] = accel[2] = 0; + + for (ii = 0; ii < packet_count; ii++) { + short accel_cur[3], gyro_cur[3]; + if (i2c_read(st.hw->addr, st.reg->fifo_r_w, MAX_PACKET_LENGTH, data)) + return -1; + accel_cur[0] = ((short)data[0] << 8) | data[1]; + accel_cur[1] = ((short)data[2] << 8) | data[3]; + accel_cur[2] = ((short)data[4] << 8) | data[5]; + accel[0] += (long)accel_cur[0]; + accel[1] += (long)accel_cur[1]; + accel[2] += (long)accel_cur[2]; + gyro_cur[0] = (((short)data[6] << 8) | data[7]); + gyro_cur[1] = (((short)data[8] << 8) | data[9]); + gyro_cur[2] = (((short)data[10] << 8) | data[11]); + gyro[0] += (long)gyro_cur[0]; + gyro[1] += (long)gyro_cur[1]; + gyro[2] += (long)gyro_cur[2]; + } +#ifdef EMPL_NO_64BIT + gyro[0] = (long)(((float)gyro[0]*65536.f) / test.gyro_sens / packet_count); + gyro[1] = (long)(((float)gyro[1]*65536.f) / test.gyro_sens / packet_count); + gyro[2] = (long)(((float)gyro[2]*65536.f) / test.gyro_sens / packet_count); + if (has_accel) { + accel[0] = (long)(((float)accel[0]*65536.f) / test.accel_sens / + packet_count); + accel[1] = (long)(((float)accel[1]*65536.f) / test.accel_sens / + packet_count); + accel[2] = (long)(((float)accel[2]*65536.f) / test.accel_sens / + packet_count); + /* Don't remove gravity! */ + accel[2] -= 65536L; + } +#else + gyro[0] = (long)(((long long)gyro[0]<<16) / test.gyro_sens / packet_count); + gyro[1] = (long)(((long long)gyro[1]<<16) / test.gyro_sens / packet_count); + gyro[2] = (long)(((long long)gyro[2]<<16) / test.gyro_sens / packet_count); + accel[0] = (long)(((long long)accel[0]<<16) / test.accel_sens / + packet_count); + accel[1] = (long)(((long long)accel[1]<<16) / test.accel_sens / + packet_count); + accel[2] = (long)(((long long)accel[2]<<16) / test.accel_sens / + packet_count); + /* Don't remove gravity! */ + if (accel[2] > 0L) + accel[2] -= 65536L; + else + accel[2] += 65536L; +#endif + + return 0; +} + +#ifdef MPU6500 +#define REG_6500_XG_ST_DATA 0x0 +#define REG_6500_XA_ST_DATA 0xD +static const unsigned short mpu_6500_st_tb[256] = { + 2620,2646,2672,2699,2726,2753,2781,2808, //7 + 2837,2865,2894,2923,2952,2981,3011,3041, //15 + 3072,3102,3133,3165,3196,3228,3261,3293, //23 + 3326,3359,3393,3427,3461,3496,3531,3566, //31 + 3602,3638,3674,3711,3748,3786,3823,3862, //39 + 3900,3939,3979,4019,4059,4099,4140,4182, //47 + 4224,4266,4308,4352,4395,4439,4483,4528, //55 + 4574,4619,4665,4712,4759,4807,4855,4903, //63 + 4953,5002,5052,5103,5154,5205,5257,5310, //71 + 5363,5417,5471,5525,5581,5636,5693,5750, //79 + 5807,5865,5924,5983,6043,6104,6165,6226, //87 + 6289,6351,6415,6479,6544,6609,6675,6742, //95 + 6810,6878,6946,7016,7086,7157,7229,7301, //103 + 7374,7448,7522,7597,7673,7750,7828,7906, //111 + 7985,8065,8145,8227,8309,8392,8476,8561, //119 + 8647,8733,8820,8909,8998,9088,9178,9270, + 9363,9457,9551,9647,9743,9841,9939,10038, + 10139,10240,10343,10446,10550,10656,10763,10870, + 10979,11089,11200,11312,11425,11539,11654,11771, + 11889,12008,12128,12249,12371,12495,12620,12746, + 12874,13002,13132,13264,13396,13530,13666,13802, + 13940,14080,14221,14363,14506,14652,14798,14946, + 15096,15247,15399,15553,15709,15866,16024,16184, + 16346,16510,16675,16842,17010,17180,17352,17526, + 17701,17878,18057,18237,18420,18604,18790,18978, + 19167,19359,19553,19748,19946,20145,20347,20550, + 20756,20963,21173,21385,21598,21814,22033,22253, + 22475,22700,22927,23156,23388,23622,23858,24097, + 24338,24581,24827,25075,25326,25579,25835,26093, + 26354,26618,26884,27153,27424,27699,27976,28255, + 28538,28823,29112,29403,29697,29994,30294,30597, + 30903,31212,31524,31839,32157,32479,32804,33132 +}; +static int accel_6500_self_test(long *bias_regular, long *bias_st, int debug) +{ + int i, result = 0, otp_value_zero = 0; + float accel_st_al_min, accel_st_al_max; + float st_shift_cust[3], st_shift_ratio[3], ct_shift_prod[3], accel_offset_max; + unsigned char regs[3]; + if (i2c_read(st.hw->addr, REG_6500_XA_ST_DATA, 3, regs)) { + if(debug) + log_i("Reading OTP Register Error.\n"); + return 0x07; + } + if(debug) + log_i("Accel OTP:%d, %d, %d\n", regs[0], regs[1], regs[2]); + for (i = 0; i < 3; i++) { + if (regs[i] != 0) { + ct_shift_prod[i] = mpu_6500_st_tb[regs[i] - 1]; + ct_shift_prod[i] *= 65536.f; + ct_shift_prod[i] /= test.accel_sens; + } + else { + ct_shift_prod[i] = 0; + otp_value_zero = 1; + } + } + if(otp_value_zero == 0) { + if(debug) + log_i("ACCEL:CRITERIA A\n"); + for (i = 0; i < 3; i++) { + st_shift_cust[i] = bias_st[i] - bias_regular[i]; + if(debug) { + log_i("Bias_Shift=%7.4f, Bias_Reg=%7.4f, Bias_HWST=%7.4f\r\n", + st_shift_cust[i]/1.f, bias_regular[i]/1.f, + bias_st[i]/1.f); + log_i("OTP value: %7.4f\r\n", ct_shift_prod[i]/1.f); + } + + st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i] - 1.f; + + if(debug) + log_i("ratio=%7.4f, threshold=%7.4f\r\n", st_shift_ratio[i]/1.f, + test.max_accel_var/1.f); + + if (fabs(st_shift_ratio[i]) > test.max_accel_var) { + if(debug) + log_i("ACCEL Fail Axis = %d\n", i); + result |= 1 << i; //Error condition + } + } + } + else { + /* Self Test Pass/Fail Criteria B */ + accel_st_al_min = test.min_g * 65536.f; + accel_st_al_max = test.max_g * 65536.f; + + if(debug) { + log_i("ACCEL:CRITERIA B\r\n"); + log_i("Min MG: %7.4f\r\n", accel_st_al_min/1.f); + log_i("Max MG: %7.4f\r\n", accel_st_al_max/1.f); + } + + for (i = 0; i < 3; i++) { + st_shift_cust[i] = bias_st[i] - bias_regular[i]; + + if(debug) + log_i("Bias_shift=%7.4f, st=%7.4f, reg=%7.4f\n", st_shift_cust[i]/1.f, bias_st[i]/1.f, bias_regular[i]/1.f); + if(st_shift_cust[i] < accel_st_al_min || st_shift_cust[i] > accel_st_al_max) { + if(debug) + log_i("Accel FAIL axis:%d <= 225mg or >= 675mg\n", i); + result |= 1 << i; //Error condition + } + } + } + + if(result == 0) { + /* Self Test Pass/Fail Criteria C */ + accel_offset_max = test.max_g_offset * 65536.f; + if(debug) + log_i("Accel:CRITERIA C: bias less than %7.4f\n", accel_offset_max/1.f); + for (i = 0; i < 3; i++) { + if(fabs(bias_regular[i]) > accel_offset_max) { + if(debug) + log_i("FAILED: Accel axis:%d = %ld > 500mg\n", i, bias_regular[i]); + result |= 1 << i; //Error condition + } + } + } + + return result; +} + +static int gyro_6500_self_test(long *bias_regular, long *bias_st, int debug) +{ + int i, result = 0, otp_value_zero = 0; + float gyro_st_al_max; + float st_shift_cust[3], st_shift_ratio[3], ct_shift_prod[3], gyro_offset_max; + unsigned char regs[3]; + + if (i2c_read(st.hw->addr, REG_6500_XG_ST_DATA, 3, regs)) { + if(debug) + log_i("Reading OTP Register Error.\n"); + return 0x07; + } + + if(debug) + log_i("Gyro OTP:%d, %d, %d\r\n", regs[0], regs[1], regs[2]); + + for (i = 0; i < 3; i++) { + if (regs[i] != 0) { + ct_shift_prod[i] = mpu_6500_st_tb[regs[i] - 1]; + ct_shift_prod[i] *= 65536.f; + ct_shift_prod[i] /= test.gyro_sens; + } + else { + ct_shift_prod[i] = 0; + otp_value_zero = 1; + } + } + + if(otp_value_zero == 0) { + if(debug) + log_i("GYRO:CRITERIA A\n"); + /* Self Test Pass/Fail Criteria A */ + for (i = 0; i < 3; i++) { + st_shift_cust[i] = bias_st[i] - bias_regular[i]; + + if(debug) { + log_i("Bias_Shift=%7.4f, Bias_Reg=%7.4f, Bias_HWST=%7.4f\r\n", + st_shift_cust[i]/1.f, bias_regular[i]/1.f, + bias_st[i]/1.f); + log_i("OTP value: %7.4f\r\n", ct_shift_prod[i]/1.f); + } + + st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i]; + + if(debug) + log_i("ratio=%7.4f, threshold=%7.4f\r\n", st_shift_ratio[i]/1.f, + test.max_gyro_var/1.f); + + if (fabs(st_shift_ratio[i]) < test.max_gyro_var) { + if(debug) + log_i("Gyro Fail Axis = %d\n", i); + result |= 1 << i; //Error condition + } + } + } + else { + /* Self Test Pass/Fail Criteria B */ + gyro_st_al_max = test.max_dps * 65536.f; + + if(debug) { + log_i("GYRO:CRITERIA B\r\n"); + log_i("Max DPS: %7.4f\r\n", gyro_st_al_max/1.f); + } + + for (i = 0; i < 3; i++) { + st_shift_cust[i] = bias_st[i] - bias_regular[i]; + + if(debug) + log_i("Bias_shift=%7.4f, st=%7.4f, reg=%7.4f\n", st_shift_cust[i]/1.f, bias_st[i]/1.f, bias_regular[i]/1.f); + if(st_shift_cust[i] < gyro_st_al_max) { + if(debug) + log_i("GYRO FAIL axis:%d greater than 60dps\n", i); + result |= 1 << i; //Error condition + } + } + } + + if(result == 0) { + /* Self Test Pass/Fail Criteria C */ + gyro_offset_max = test.min_dps * 65536.f; + if(debug) + log_i("Gyro:CRITERIA C: bias less than %7.4f\n", gyro_offset_max/1.f); + for (i = 0; i < 3; i++) { + if(fabs(bias_regular[i]) > gyro_offset_max) { + if(debug) + log_i("FAILED: Gyro axis:%d = %ld > 20dps\n", i, bias_regular[i]); + result |= 1 << i; //Error condition + } + } + } + return result; +} + +static int get_st_6500_biases(long *gyro, long *accel, unsigned char hw_test, int debug) +{ + unsigned char data[HWST_MAX_PACKET_LENGTH]; + unsigned char packet_count, ii; + unsigned short fifo_count; + int s = 0, read_size = 0, ind; + + data[0] = 0x01; + data[1] = 0; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) + return -1; + delay_ms(200); + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + data[0] = BIT_FIFO_RST | BIT_DMP_RST; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + delay_ms(15); + data[0] = st.test->reg_lpf; + if (i2c_write(st.hw->addr, st.reg->lpf, 1, data)) + return -1; + data[0] = st.test->reg_rate_div; + if (i2c_write(st.hw->addr, st.reg->rate_div, 1, data)) + return -1; + if (hw_test) + data[0] = st.test->reg_gyro_fsr | 0xE0; + else + data[0] = st.test->reg_gyro_fsr; + if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, data)) + return -1; + + if (hw_test) + data[0] = st.test->reg_accel_fsr | 0xE0; + else + data[0] = test.reg_accel_fsr; + if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data)) + return -1; + + delay_ms(test.wait_ms); //wait 200ms for sensors to stabilize + + /* Enable FIFO */ + data[0] = BIT_FIFO_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + data[0] = INV_XYZ_GYRO | INV_XYZ_ACCEL; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + + //initialize the bias return values + gyro[0] = gyro[1] = gyro[2] = 0; + accel[0] = accel[1] = accel[2] = 0; + + if(debug) + log_i("Starting Bias Loop Reads\n"); + + //start reading samples + while (s < test.packet_thresh) { + delay_ms(test.sample_wait_ms); //wait 10ms to fill FIFO + if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) + return -1; + fifo_count = (data[0] << 8) | data[1]; + packet_count = fifo_count / MAX_PACKET_LENGTH; + if ((test.packet_thresh - s) < packet_count) + packet_count = test.packet_thresh - s; + read_size = packet_count * MAX_PACKET_LENGTH; + + //burst read from FIFO + if (i2c_read(st.hw->addr, st.reg->fifo_r_w, read_size, data)) + return -1; + ind = 0; + for (ii = 0; ii < packet_count; ii++) { + short accel_cur[3], gyro_cur[3]; + accel_cur[0] = ((short)data[ind + 0] << 8) | data[ind + 1]; + accel_cur[1] = ((short)data[ind + 2] << 8) | data[ind + 3]; + accel_cur[2] = ((short)data[ind + 4] << 8) | data[ind + 5]; + accel[0] += (long)accel_cur[0]; + accel[1] += (long)accel_cur[1]; + accel[2] += (long)accel_cur[2]; + gyro_cur[0] = (((short)data[ind + 6] << 8) | data[ind + 7]); + gyro_cur[1] = (((short)data[ind + 8] << 8) | data[ind + 9]); + gyro_cur[2] = (((short)data[ind + 10] << 8) | data[ind + 11]); + gyro[0] += (long)gyro_cur[0]; + gyro[1] += (long)gyro_cur[1]; + gyro[2] += (long)gyro_cur[2]; + ind += MAX_PACKET_LENGTH; + } + s += packet_count; + } + + if(debug) + log_i("Samples: %d\n", s); + + //stop FIFO + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + + gyro[0] = (long)(((long long)gyro[0]<<16) / test.gyro_sens / s); + gyro[1] = (long)(((long long)gyro[1]<<16) / test.gyro_sens / s); + gyro[2] = (long)(((long long)gyro[2]<<16) / test.gyro_sens / s); + accel[0] = (long)(((long long)accel[0]<<16) / test.accel_sens / s); + accel[1] = (long)(((long long)accel[1]<<16) / test.accel_sens / s); + accel[2] = (long)(((long long)accel[2]<<16) / test.accel_sens / s); + /* remove gravity from bias calculation */ + if (accel[2] > 0L) + accel[2] -= 65536L; + else + accel[2] += 65536L; + + + if(debug) { + log_i("Accel offset data HWST bit=%d: %7.4f %7.4f %7.4f\r\n", hw_test, accel[0]/65536.f, accel[1]/65536.f, accel[2]/65536.f); + log_i("Gyro offset data HWST bit=%d: %7.4f %7.4f %7.4f\r\n", hw_test, gyro[0]/65536.f, gyro[1]/65536.f, gyro[2]/65536.f); + } + + return 0; +} +/** + * @brief Trigger gyro/accel/compass self-test for MPU6500/MPU9250 + * On success/error, the self-test returns a mask representing the sensor(s) + * that failed. For each bit, a one (1) represents a "pass" case; conversely, + * a zero (0) indicates a failure. + * + * \n The mask is defined as follows: + * \n Bit 0: Gyro. + * \n Bit 1: Accel. + * \n Bit 2: Compass. + * + * @param[out] gyro Gyro biases in q16 format. + * @param[out] accel Accel biases (if applicable) in q16 format. + * @param[in] debug Debug flag used to print out more detailed logs. Must first set up logging in Motion Driver. + * @return Result mask (see above). + */ +int mpu_run_6500_self_test(long *gyro, long *accel, unsigned char debug) +{ + const unsigned char tries = 2; + long gyro_st[3], accel_st[3]; + unsigned char accel_result, gyro_result; +#ifdef AK89xx_SECONDARY + unsigned char compass_result; +#endif + int ii; + + int result; + unsigned char accel_fsr, fifo_sensors, sensors_on; + unsigned short gyro_fsr, sample_rate, lpf; + unsigned char dmp_was_on; + + + + if(debug) + log_i("Starting MPU6500 HWST!\r\n"); + + if (st.chip_cfg.dmp_on) { + mpu_set_dmp_state(0); + dmp_was_on = 1; + } else + dmp_was_on = 0; + + /* Get initial settings. */ + mpu_get_gyro_fsr(&gyro_fsr); + mpu_get_accel_fsr(&accel_fsr); + mpu_get_lpf(&lpf); + mpu_get_sample_rate(&sample_rate); + sensors_on = st.chip_cfg.sensors; + mpu_get_fifo_config(&fifo_sensors); + + if(debug) + log_i("Retrieving Biases\r\n"); + + for (ii = 0; ii < tries; ii++) + if (!get_st_6500_biases(gyro, accel, 0, debug)) + break; + if (ii == tries) { + /* If we reach this point, we most likely encountered an I2C error. + * We'll just report an error for all three sensors. + */ + if(debug) + log_i("Retrieving Biases Error - possible I2C error\n"); + + result = 0; + goto restore; + } + + if(debug) + log_i("Retrieving ST Biases\n"); + + for (ii = 0; ii < tries; ii++) + if (!get_st_6500_biases(gyro_st, accel_st, 1, debug)) + break; + if (ii == tries) { + + if(debug) + log_i("Retrieving ST Biases Error - possible I2C error\n"); + + /* Again, probably an I2C error. */ + result = 0; + goto restore; + } + + accel_result = accel_6500_self_test(accel, accel_st, debug); + if(debug) + log_i("Accel Self Test Results: %d\n", accel_result); + + gyro_result = gyro_6500_self_test(gyro, gyro_st, debug); + if(debug) + log_i("Gyro Self Test Results: %d\n", gyro_result); + + result = 0; + if (!gyro_result) + result |= 0x01; + if (!accel_result) + result |= 0x02; + +#ifdef AK89xx_SECONDARY + compass_result = compass_self_test(); + if(debug) + log_i("Compass Self Test Results: %d\n", compass_result); + if (!compass_result) + result |= 0x04; +#else + result |= 0x04; +#endif +restore: + if(debug) + log_i("Exiting HWST\n"); + /* Set to invalid values to ensure no I2C writes are skipped. */ + st.chip_cfg.gyro_fsr = 0xFF; + st.chip_cfg.accel_fsr = 0xFF; + st.chip_cfg.lpf = 0xFF; + st.chip_cfg.sample_rate = 0xFFFF; + st.chip_cfg.sensors = 0xFF; + st.chip_cfg.fifo_enable = 0xFF; + st.chip_cfg.clk_src = INV_CLK_PLL; + mpu_set_gyro_fsr(gyro_fsr); + mpu_set_accel_fsr(accel_fsr); + mpu_set_lpf(lpf); + mpu_set_sample_rate(sample_rate); + mpu_set_sensors(sensors_on); + mpu_configure_fifo(fifo_sensors); + + if (dmp_was_on) + mpu_set_dmp_state(1); + + return result; +} +#endif + /* + * \n This function must be called with the device either face-up or face-down + * (z-axis is parallel to gravity). + * @param[out] gyro Gyro biases in q16 format. + * @param[out] accel Accel biases (if applicable) in q16 format. + * @return Result mask (see above). + */ +int mpu_run_self_test(long *gyro, long *accel) +{ +#ifdef MPU6050 + const unsigned char tries = 2; + long gyro_st[3], accel_st[3]; + unsigned char accel_result, gyro_result; +#ifdef AK89xx_SECONDARY + unsigned char compass_result; +#endif + int ii; +#endif + int result; + unsigned char accel_fsr, fifo_sensors, sensors_on; + unsigned short gyro_fsr, sample_rate, lpf; + unsigned char dmp_was_on; + + if (st.chip_cfg.dmp_on) { + mpu_set_dmp_state(0); + dmp_was_on = 1; + } else + dmp_was_on = 0; + + /* Get initial settings. */ + mpu_get_gyro_fsr(&gyro_fsr); + mpu_get_accel_fsr(&accel_fsr); + mpu_get_lpf(&lpf); + mpu_get_sample_rate(&sample_rate); + sensors_on = st.chip_cfg.sensors; + mpu_get_fifo_config(&fifo_sensors); + + /* For older chips, the self-test will be different. */ +#if defined MPU6050 + for (ii = 0; ii < tries; ii++) + if (!get_st_biases(gyro, accel, 0)) + break; + if (ii == tries) { + /* If we reach this point, we most likely encountered an I2C error. + * We'll just report an error for all three sensors. + */ + result = 0; + goto restore; + } + for (ii = 0; ii < tries; ii++) + if (!get_st_biases(gyro_st, accel_st, 1)) + break; + if (ii == tries) { + /* Again, probably an I2C error. */ + result = 0; + goto restore; + } + accel_result = accel_self_test(accel, accel_st); + gyro_result = gyro_self_test(gyro, gyro_st); + + result = 0; + if (!gyro_result) + result |= 0x01; + if (!accel_result) + result |= 0x02; + +#ifdef AK89xx_SECONDARY + compass_result = compass_self_test(); + if (!compass_result) + result |= 0x04; +#else + result |= 0x04; +#endif +restore: +#elif defined MPU6500 + /* For now, this function will return a "pass" result for all three sensors + * for compatibility with current test applications. + */ + get_st_biases(gyro, accel, 0); + result = 0x7; +#endif + /* Set to invalid values to ensure no I2C writes are skipped. */ + st.chip_cfg.gyro_fsr = 0xFF; + st.chip_cfg.accel_fsr = 0xFF; + st.chip_cfg.lpf = 0xFF; + st.chip_cfg.sample_rate = 0xFFFF; + st.chip_cfg.sensors = 0xFF; + st.chip_cfg.fifo_enable = 0xFF; + st.chip_cfg.clk_src = INV_CLK_PLL; + mpu_set_gyro_fsr(gyro_fsr); + mpu_set_accel_fsr(accel_fsr); + mpu_set_lpf(lpf); + mpu_set_sample_rate(sample_rate); + mpu_set_sensors(sensors_on); + mpu_configure_fifo(fifo_sensors); + + if (dmp_was_on) + mpu_set_dmp_state(1); + + return result; +} + +/** + * @brief Write to the DMP memory. + * This function prevents I2C writes past the bank boundaries. The DMP memory + * is only accessible when the chip is awake. + * @param[in] mem_addr Memory location (bank << 8 | start address) + * @param[in] length Number of bytes to write. + * @param[in] data Bytes to write to memory. + * @return 0 if successful. + */ +int mpu_write_mem(unsigned short mem_addr, unsigned short length, + unsigned char *data) +{ + unsigned char tmp[2]; + + if (!data) + return -1; + if (!st.chip_cfg.sensors) + return -1; + + tmp[0] = (unsigned char)(mem_addr >> 8); + tmp[1] = (unsigned char)(mem_addr & 0xFF); + + /* Check bank boundaries. */ + if (tmp[1] + length > st.hw->bank_size) + return -1; + + if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) + return -1; + if (i2c_write(st.hw->addr, st.reg->mem_r_w, length, data)) + return -1; + return 0; +} + +/** + * @brief Read from the DMP memory. + * This function prevents I2C reads past the bank boundaries. The DMP memory + * is only accessible when the chip is awake. + * @param[in] mem_addr Memory location (bank << 8 | start address) + * @param[in] length Number of bytes to read. + * @param[out] data Bytes read from memory. + * @return 0 if successful. + */ +int mpu_read_mem(unsigned short mem_addr, unsigned short length, + unsigned char *data) +{ + unsigned char tmp[2]; + + if (!data) + return -1; + if (!st.chip_cfg.sensors) + return -1; + + tmp[0] = (unsigned char)(mem_addr >> 8); + tmp[1] = (unsigned char)(mem_addr & 0xFF); + + /* Check bank boundaries. */ + if (tmp[1] + length > st.hw->bank_size) + return -1; + + if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) + return -1; + if (i2c_read(st.hw->addr, st.reg->mem_r_w, length, data)) + return -1; + return 0; +} + +/** + * @brief Load and verify DMP image. + * @param[in] length Length of DMP image. + * @param[in] firmware DMP code. + * @param[in] start_addr Starting address of DMP code memory. + * @param[in] sample_rate Fixed sampling rate used when DMP is enabled. + * @return 0 if successful. + */ +int mpu_load_firmware(unsigned short length, const unsigned char *firmware, + unsigned short start_addr, unsigned short sample_rate) +{ + unsigned short ii; + unsigned short this_write; + /* Must divide evenly into st.hw->bank_size to avoid bank crossings. */ +#define LOAD_CHUNK (16) + unsigned char cur[LOAD_CHUNK], tmp[2]; + + if (st.chip_cfg.dmp_loaded) + /* DMP should only be loaded once. */ + return -1; + + if (!firmware) + return -1; + for (ii = 0; ii < length; ii += this_write) { + this_write = min(LOAD_CHUNK, length - ii); + if (mpu_write_mem(ii, this_write, (unsigned char*)&firmware[ii])) + return -1; + if (mpu_read_mem(ii, this_write, cur)) + return -1; + if (memcmp(firmware+ii, cur, this_write)) + return -2; + } + + /* Set program start address. */ + tmp[0] = start_addr >> 8; + tmp[1] = start_addr & 0xFF; + if (i2c_write(st.hw->addr, st.reg->prgm_start_h, 2, tmp)) + return -1; + + st.chip_cfg.dmp_loaded = 1; + st.chip_cfg.dmp_sample_rate = sample_rate; + return 0; +} + +/** + * @brief Enable/disable DMP support. + * @param[in] enable 1 to turn on the DMP. + * @return 0 if successful. + */ +int mpu_set_dmp_state(unsigned char enable) +{ + unsigned char tmp; + if (st.chip_cfg.dmp_on == enable) + return 0; + + if (enable) { + if (!st.chip_cfg.dmp_loaded) + return -1; + /* Disable data ready interrupt. */ + set_int_enable(0); + /* Disable bypass mode. */ + mpu_set_bypass(0); + /* Keep constant sample rate, FIFO rate controlled by DMP. */ + mpu_set_sample_rate(st.chip_cfg.dmp_sample_rate); + /* Remove FIFO elements. */ + tmp = 0; + i2c_write(st.hw->addr, 0x23, 1, &tmp); + st.chip_cfg.dmp_on = 1; + /* Enable DMP interrupt. */ + set_int_enable(1); + mpu_reset_fifo(); + } else { + /* Disable DMP interrupt. */ + set_int_enable(0); + /* Restore FIFO settings. */ + tmp = st.chip_cfg.fifo_enable; + i2c_write(st.hw->addr, 0x23, 1, &tmp); + st.chip_cfg.dmp_on = 0; + mpu_reset_fifo(); + } + return 0; +} + +/** + * @brief Get DMP state. + * @param[out] enabled 1 if enabled. + * @return 0 if successful. + */ +int mpu_get_dmp_state(unsigned char *enabled) +{ + enabled[0] = st.chip_cfg.dmp_on; + return 0; +} + +#ifdef AK89xx_SECONDARY +/* This initialization is similar to the one in ak8975.c. */ +static int setup_compass(void) +{ + unsigned char data[4], akm_addr; + + mpu_set_bypass(1); + + /* Find compass. Possible addresses range from 0x0C to 0x0F. */ + for (akm_addr = 0x0C; akm_addr <= 0x0F; akm_addr++) { + int result; + result = i2c_read(akm_addr, AKM_REG_WHOAMI, 1, data); + if (!result && (data[0] == AKM_WHOAMI)) + break; + } + + if (akm_addr > 0x0F) { + /* TODO: Handle this case in all compass-related functions. */ + log_e("Compass not found.\n"); + return -1; + } + + st.chip_cfg.compass_addr = akm_addr; + + data[0] = AKM_POWER_DOWN; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) + return -1; + delay_ms(1); + + data[0] = AKM_FUSE_ROM_ACCESS; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) + return -1; + delay_ms(1); + + /* Get sensitivity adjustment data from fuse ROM. */ + if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ASAX, 3, data)) + return -1; + st.chip_cfg.mag_sens_adj[0] = (long)data[0] + 128; + st.chip_cfg.mag_sens_adj[1] = (long)data[1] + 128; + st.chip_cfg.mag_sens_adj[2] = (long)data[2] + 128; + + data[0] = AKM_POWER_DOWN; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) + return -1; + delay_ms(1); + + mpu_set_bypass(0); + + /* Set up master mode, master clock, and ES bit. */ + data[0] = 0x40; + if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) + return -1; + + /* Slave 0 reads from AKM data registers. */ + data[0] = BIT_I2C_READ | st.chip_cfg.compass_addr; + if (i2c_write(st.hw->addr, st.reg->s0_addr, 1, data)) + return -1; + + /* Compass reads start at this register. */ + data[0] = AKM_REG_ST1; + if (i2c_write(st.hw->addr, st.reg->s0_reg, 1, data)) + return -1; + + /* Enable slave 0, 8-byte reads. */ + data[0] = BIT_SLAVE_EN | 8; + if (i2c_write(st.hw->addr, st.reg->s0_ctrl, 1, data)) + return -1; + + /* Slave 1 changes AKM measurement mode. */ + data[0] = st.chip_cfg.compass_addr; + if (i2c_write(st.hw->addr, st.reg->s1_addr, 1, data)) + return -1; + + /* AKM measurement mode register. */ + data[0] = AKM_REG_CNTL; + if (i2c_write(st.hw->addr, st.reg->s1_reg, 1, data)) + return -1; + + /* Enable slave 1, 1-byte writes. */ + data[0] = BIT_SLAVE_EN | 1; + if (i2c_write(st.hw->addr, st.reg->s1_ctrl, 1, data)) + return -1; + + /* Set slave 1 data. */ + data[0] = AKM_SINGLE_MEASUREMENT; + if (i2c_write(st.hw->addr, st.reg->s1_do, 1, data)) + return -1; + + /* Trigger slave 0 and slave 1 actions at each sample. */ + data[0] = 0x03; + if (i2c_write(st.hw->addr, st.reg->i2c_delay_ctrl, 1, data)) + return -1; + +#ifdef MPU9150 + /* For the MPU9150, the auxiliary I2C bus needs to be set to VDD. */ + data[0] = BIT_I2C_MST_VDDIO; + if (i2c_write(st.hw->addr, st.reg->yg_offs_tc, 1, data)) + return -1; +#endif + + return 0; +} +#endif + +/** + * @brief Read raw compass data. + * @param[out] data Raw data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. Null if not needed. + * @return 0 if successful. + */ +int mpu_get_compass_reg(short *data, unsigned long *timestamp) +{ +#ifdef AK89xx_SECONDARY + unsigned char tmp[9]; + + if (!(st.chip_cfg.sensors & INV_XYZ_COMPASS)) + return -1; + +#ifdef AK89xx_BYPASS + if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 8, tmp)) + return -1; + tmp[8] = AKM_SINGLE_MEASUREMENT; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp+8)) + return -1; +#else + if (i2c_read(st.hw->addr, st.reg->raw_compass, 8, tmp)) + return -1; +#endif + +#if defined AK8975_SECONDARY + /* AK8975 doesn't have the overrun error bit. */ + if (!(tmp[0] & AKM_DATA_READY)) + return -2; + if ((tmp[7] & AKM_OVERFLOW) || (tmp[7] & AKM_DATA_ERROR)) + return -3; +#elif defined AK8963_SECONDARY + /* AK8963 doesn't have the data read error bit. */ + if (!(tmp[0] & AKM_DATA_READY) || (tmp[0] & AKM_DATA_OVERRUN)) + return -2; + if (tmp[7] & AKM_OVERFLOW) + return -3; +#endif + data[0] = (tmp[2] << 8) | tmp[1]; + data[1] = (tmp[4] << 8) | tmp[3]; + data[2] = (tmp[6] << 8) | tmp[5]; + + data[0] = ((long)data[0] * st.chip_cfg.mag_sens_adj[0]) >> 8; + data[1] = ((long)data[1] * st.chip_cfg.mag_sens_adj[1]) >> 8; + data[2] = ((long)data[2] * st.chip_cfg.mag_sens_adj[2]) >> 8; + + if (timestamp) + get_ms(timestamp); + return 0; +#else + return -1; +#endif +} + +/** + * @brief Get the compass full-scale range. + * @param[out] fsr Current full-scale range. + * @return 0 if successful. + */ +int mpu_get_compass_fsr(unsigned short *fsr) +{ +#ifdef AK89xx_SECONDARY + fsr[0] = st.hw->compass_fsr; + return 0; +#else + return -1; +#endif +} + +/** + * @brief Enters LP accel motion interrupt mode. + * The behaviour of this feature is very different between the MPU6050 and the + * MPU6500. Each chip's version of this feature is explained below. + * + * \n The hardware motion threshold can be between 32mg and 8160mg in 32mg + * increments. + * + * \n Low-power accel mode supports the following frequencies: + * \n 1.25Hz, 5Hz, 20Hz, 40Hz + * + * \n MPU6500: + * \n Unlike the MPU6050 version, the hardware does not "lock in" a reference + * sample. The hardware monitors the accel data and detects any large change + * over a short period of time. + * + * \n The hardware motion threshold can be between 4mg and 1020mg in 4mg + * increments. + * + * \n MPU6500 Low-power accel mode supports the following frequencies: + * \n 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz + * + * \n\n NOTES: + * \n The driver will round down @e thresh to the nearest supported value if + * an unsupported threshold is selected. + * \n To select a fractional wake-up frequency, round down the value passed to + * @e lpa_freq. + * \n The MPU6500 does not support a delay parameter. If this function is used + * for the MPU6500, the value passed to @e time will be ignored. + * \n To disable this mode, set @e lpa_freq to zero. The driver will restore + * the previous configuration. + * + * @param[in] thresh Motion threshold in mg. + * @param[in] time Duration in milliseconds that the accel data must + * exceed @e thresh before motion is reported. + * @param[in] lpa_freq Minimum sampling rate, or zero to disable. + * @return 0 if successful. + */ +int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time, + unsigned short lpa_freq) +{ + +#if defined MPU6500 + unsigned char data[3]; +#endif + if (lpa_freq) { +#if defined MPU6500 + unsigned char thresh_hw; + + /* 1LSb = 4mg. */ + if (thresh > 1020) + thresh_hw = 255; + else if (thresh < 4) + thresh_hw = 1; + else + thresh_hw = thresh >> 2; +#endif + + if (!time) + /* Minimum duration must be 1ms. */ + time = 1; + +#if defined MPU6500 + if (lpa_freq > 640) + /* At this point, the chip has not been re-configured, so the + * function can safely exit. + */ + return -1; +#endif + + if (!st.chip_cfg.int_motion_only) { + /* Store current settings for later. */ + if (st.chip_cfg.dmp_on) { + mpu_set_dmp_state(0); + st.chip_cfg.cache.dmp_on = 1; + } else + st.chip_cfg.cache.dmp_on = 0; + mpu_get_gyro_fsr(&st.chip_cfg.cache.gyro_fsr); + mpu_get_accel_fsr(&st.chip_cfg.cache.accel_fsr); + mpu_get_lpf(&st.chip_cfg.cache.lpf); + mpu_get_sample_rate(&st.chip_cfg.cache.sample_rate); + st.chip_cfg.cache.sensors_on = st.chip_cfg.sensors; + mpu_get_fifo_config(&st.chip_cfg.cache.fifo_sensors); + } + +#if defined MPU6500 + /* Disable hardware interrupts. */ + set_int_enable(0); + + /* Enter full-power accel-only mode, no FIFO/DMP. */ + data[0] = 0; + data[1] = 0; + data[2] = BIT_STBY_XYZG; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 3, data)) + goto lp_int_restore; + + /* Set motion threshold. */ + data[0] = thresh_hw; + if (i2c_write(st.hw->addr, st.reg->motion_thr, 1, data)) + goto lp_int_restore; + + /* Set wake frequency. */ + if (lpa_freq == 1) + data[0] = INV_LPA_1_25HZ; + else if (lpa_freq == 2) + data[0] = INV_LPA_2_5HZ; + else if (lpa_freq <= 5) + data[0] = INV_LPA_5HZ; + else if (lpa_freq <= 10) + data[0] = INV_LPA_10HZ; + else if (lpa_freq <= 20) + data[0] = INV_LPA_20HZ; + else if (lpa_freq <= 40) + data[0] = INV_LPA_40HZ; + else if (lpa_freq <= 80) + data[0] = INV_LPA_80HZ; + else if (lpa_freq <= 160) + data[0] = INV_LPA_160HZ; + else if (lpa_freq <= 320) + data[0] = INV_LPA_320HZ; + else + data[0] = INV_LPA_640HZ; + if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, data)) + goto lp_int_restore; + + /* Enable motion interrupt (MPU6500 version). */ + data[0] = BITS_WOM_EN; + if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data)) + goto lp_int_restore; + + /* Enable cycle mode. */ + data[0] = BIT_LPA_CYCLE; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + goto lp_int_restore; + + /* Enable interrupt. */ + data[0] = BIT_MOT_INT_EN; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) + goto lp_int_restore; + + st.chip_cfg.int_motion_only = 1; + return 0; +#endif + } else { + /* Don't "restore" the previous state if no state has been saved. */ + unsigned int ii; + char *cache_ptr = (char*)&st.chip_cfg.cache; + for (ii = 0; ii < sizeof(st.chip_cfg.cache); ii++) { + if (cache_ptr[ii] != 0) + goto lp_int_restore; + } + /* If we reach this point, motion interrupt mode hasn't been used yet. */ + return -1; + } +lp_int_restore: + /* Set to invalid values to ensure no I2C writes are skipped. */ + st.chip_cfg.gyro_fsr = 0xFF; + st.chip_cfg.accel_fsr = 0xFF; + st.chip_cfg.lpf = 0xFF; + st.chip_cfg.sample_rate = 0xFFFF; + st.chip_cfg.sensors = 0xFF; + st.chip_cfg.fifo_enable = 0xFF; + st.chip_cfg.clk_src = INV_CLK_PLL; + mpu_set_sensors(st.chip_cfg.cache.sensors_on); + mpu_set_gyro_fsr(st.chip_cfg.cache.gyro_fsr); + mpu_set_accel_fsr(st.chip_cfg.cache.accel_fsr); + mpu_set_lpf(st.chip_cfg.cache.lpf); + mpu_set_sample_rate(st.chip_cfg.cache.sample_rate); + mpu_configure_fifo(st.chip_cfg.cache.fifo_sensors); + + if (st.chip_cfg.cache.dmp_on) + mpu_set_dmp_state(1); + +#ifdef MPU6500 + /* Disable motion interrupt (MPU6500 version). */ + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data)) + goto lp_int_restore; +#endif + + st.chip_cfg.int_motion_only = 0; + return 0; +} + +/** + * @} + */ + diff --git a/bsp/boards/mimsy2-cc2538/inv_mpu.h b/bsp/boards/mimsy2-cc2538/inv_mpu.h new file mode 100644 index 0000000000..39e81b4c51 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/inv_mpu.h @@ -0,0 +1,137 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @addtogroup DRIVERS Sensor Driver Layer + * @brief Hardware drivers to communicate with sensors via I2C. + * + * @{ + * @file inv_mpu.h + * @brief An I2C-based driver for Invensense gyroscopes. + * @details This driver currently works for the following devices: + * MPU6050 + * MPU6500 + * MPU9150 (or MPU6050 w/ AK8975 on the auxiliary bus) + * MPU9250 (or MPU6500 w/ AK8963 on the auxiliary bus) + */ + +#ifndef _INV_MPU_H_ +#define _INV_MPU_H_ + +#define INV_X_GYRO (0x40) +#define INV_Y_GYRO (0x20) +#define INV_Z_GYRO (0x10) +#define INV_XYZ_GYRO (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO) +#define INV_XYZ_ACCEL (0x08) +#define INV_XYZ_COMPASS (0x01) +#define MIMSY +struct int_param_s { +#if defined EMPL_TARGET_MSP430 || defined MOTION_DRIVER_TARGET_MSP430 + void (*cb)(void); + unsigned short pin; + unsigned char lp_exit; + unsigned char active_low; +#elif defined EMPL_TARGET_UC3L0 + unsigned long pin; + void (*cb)(volatile void*); + void *arg; +#elif defined EMPL_TARGET_STM32F4 + void (*cb)(void); + +#elif defined MIMSY + void (*cb)(void); +#endif +}; + +#define MPU_INT_STATUS_DATA_READY (0x0001) +#define MPU_INT_STATUS_DMP (0x0002) +#define MPU_INT_STATUS_PLL_READY (0x0004) +#define MPU_INT_STATUS_I2C_MST (0x0008) +#define MPU_INT_STATUS_FIFO_OVERFLOW (0x0010) +#define MPU_INT_STATUS_ZMOT (0x0020) +#define MPU_INT_STATUS_MOT (0x0040) +#define MPU_INT_STATUS_FREE_FALL (0x0080) +#define MPU_INT_STATUS_DMP_0 (0x0100) +#define MPU_INT_STATUS_DMP_1 (0x0200) +#define MPU_INT_STATUS_DMP_2 (0x0400) +#define MPU_INT_STATUS_DMP_3 (0x0800) +#define MPU_INT_STATUS_DMP_4 (0x1000) +#define MPU_INT_STATUS_DMP_5 (0x2000) + +/* Set up APIs */ +int mpu_init(struct int_param_s *int_param); +int mpu_init_slave(void); +int mpu_set_bypass(unsigned char bypass_on); + +/* Configuration APIs */ +int mpu_lp_accel_mode(unsigned short rate); +int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time, + unsigned short lpa_freq); +int mpu_set_int_level(unsigned char active_low); +int mpu_set_int_latched(unsigned char enable); + +int mpu_set_dmp_state(unsigned char enable); +int mpu_get_dmp_state(unsigned char *enabled); + +int mpu_get_lpf(unsigned short *lpf); +int mpu_set_lpf(unsigned short lpf); + +int mpu_get_gyro_fsr(unsigned short *fsr); +int mpu_set_gyro_fsr(unsigned short fsr); + +int mpu_get_accel_fsr(unsigned char *fsr); +int mpu_set_accel_fsr(unsigned char fsr); + +int mpu_get_compass_fsr(unsigned short *fsr); + +int mpu_get_gyro_sens(float *sens); +int mpu_get_accel_sens(unsigned short *sens); + +int mpu_get_sample_rate(unsigned short *rate); +int mpu_set_sample_rate(unsigned short rate); +int mpu_get_compass_sample_rate(unsigned short *rate); +int mpu_set_compass_sample_rate(unsigned short rate); + +int mpu_get_fifo_config(unsigned char *sensors); +int mpu_configure_fifo(unsigned char sensors); + +int mpu_get_power_state(unsigned char *power_on); +int mpu_set_sensors(unsigned char sensors); + +int mpu_read_6500_accel_bias(long *accel_bias); +int mpu_set_gyro_bias_reg(long * gyro_bias); +int mpu_set_accel_bias_6500_reg(const long *accel_bias); +int mpu_read_6050_accel_bias(long *accel_bias); +int mpu_set_accel_bias_6050_reg(const long *accel_bias); + +/* Data getter/setter APIs */ +int mpu_get_gyro_reg(short *data, unsigned long *timestamp); +int mpu_get_accel_reg(short *data, unsigned long *timestamp); +int mpu_get_compass_reg(short *data, unsigned long *timestamp); +int mpu_get_temperature(long *data, unsigned long *timestamp); + +int mpu_get_int_status(short *status); +int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, + unsigned char *sensors, unsigned char *more); +int mpu_read_fifo_stream(unsigned short length, unsigned char *data, + unsigned char *more); +int mpu_reset_fifo(void); + +int mpu_write_mem(unsigned short mem_addr, unsigned short length, + unsigned char *data); +int mpu_read_mem(unsigned short mem_addr, unsigned short length, + unsigned char *data); +int mpu_load_firmware(unsigned short length, const unsigned char *firmware, + unsigned short start_addr, unsigned short sample_rate); + +int mpu_reg_dump(void); +int mpu_read_reg(unsigned char reg, unsigned char *data); +int mpu_run_self_test(long *gyro, long *accel); +int mpu_run_6500_self_test(long *gyro, long *accel, unsigned char debug); +int mpu_register_tap_cb(void (*func)(unsigned char, unsigned char)); + +#endif /* #ifndef _INV_MPU_H_ */ + diff --git a/bsp/boards/mimsy2-cc2538/inv_mpu_dmp_motion_driver.c b/bsp/boards/mimsy2-cc2538/inv_mpu_dmp_motion_driver.c new file mode 100644 index 0000000000..1656cc1c18 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/inv_mpu_dmp_motion_driver.c @@ -0,0 +1,1390 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @addtogroup DRIVERS Sensor Driver Layer + * @brief Hardware drivers to communicate with sensors via I2C. + * + * @{ + * @file inv_mpu_dmp_motion_driver.c + * @brief DMP image and interface functions. + * @details All functions are preceded by the dmp_ prefix to + * differentiate among MPL and general driver function calls. + */ +#include +#include +#include +#include +#include +#include "inv_mpu.h" +#include "inv_mpu_dmp_motion_driver.h" +#include "dmpKey.h" +#include "dmpmap.h" +#define MIMSY + +/* The following functions must be defined for this platform: + * i2c_write(unsigned char slave_addr, unsigned char reg_addr, + * unsigned char length, unsigned char const *data) + * i2c_read(unsigned char slave_addr, unsigned char reg_addr, + * unsigned char length, unsigned char *data) + * delay_ms(unsigned long num_ms) + * get_ms(unsigned long *count) + */ + + +#if defined MIMSY + +#define i2c_write i2c_write_registers +#define i2c_read i2c_read_registers +#define delay_ms delay_ms +#define get_ms get_ms +#define log_i(...) do {} while (0) +#define log_e(...) do {} while (0) + +#elif defined EMPL_TARGET_STM32F4 +#include "i2c.h" +#include "main.h" +#include "board-st_discovery.h" + +#define i2c_write Sensors_I2C_WriteRegister +#define i2c_read Sensors_I2C_ReadRegister +#define get_ms get_tick_count + +#elif defined MOTION_DRIVER_TARGET_MSP430 +#include "msp430.h" +#include "msp430_clock.h" +#define delay_ms msp430_delay_ms +#define get_ms msp430_get_clock_ms +#define log_i(...) do {} while (0) +#define log_e(...) do {} while (0) + +#elif defined EMPL_TARGET_MSP430 +#include "msp430.h" +#include "msp430_clock.h" +#include "log.h" +#define delay_ms msp430_delay_ms +#define get_ms msp430_get_clock_ms +#define log_i MPL_LOGI +#define log_e MPL_LOGE + +#elif defined EMPL_TARGET_UC3L0 +/* Instead of using the standard TWI driver from the ASF library, we're using + * a TWI driver that follows the slave address + register address convention. + */ +#include "delay.h" +#include "sysclk.h" +#include "log.h" +#include "uc3l0_clock.h" +/* delay_ms is a function already defined in ASF. */ +#define get_ms uc3l0_get_clock_ms +#define log_i MPL_LOGI +#define log_e MPL_LOGE + +#else +#error Gyro driver is missing the system layer implementations. +#endif + +/* These defines are copied from dmpDefaultMPU6050.c in the general MPL + * releases. These defines may change for each DMP image, so be sure to modify + * these values when switching to a new image. + */ +#define CFG_LP_QUAT (2712) +#define END_ORIENT_TEMP (1866) +#define CFG_27 (2742) +#define CFG_20 (2224) +#define CFG_23 (2745) +#define CFG_FIFO_ON_EVENT (2690) +#define END_PREDICTION_UPDATE (1761) +#define CGNOTICE_INTR (2620) +#define X_GRT_Y_TMP (1358) +#define CFG_DR_INT (1029) +#define CFG_AUTH (1035) +#define UPDATE_PROP_ROT (1835) +#define END_COMPARE_Y_X_TMP2 (1455) +#define SKIP_X_GRT_Y_TMP (1359) +#define SKIP_END_COMPARE (1435) +#define FCFG_3 (1088) +#define FCFG_2 (1066) +#define FCFG_1 (1062) +#define END_COMPARE_Y_X_TMP3 (1434) +#define FCFG_7 (1073) +#define FCFG_6 (1106) +#define FLAT_STATE_END (1713) +#define SWING_END_4 (1616) +#define SWING_END_2 (1565) +#define SWING_END_3 (1587) +#define SWING_END_1 (1550) +#define CFG_8 (2718) +#define CFG_15 (2727) +#define CFG_16 (2746) +#define CFG_EXT_GYRO_BIAS (1189) +#define END_COMPARE_Y_X_TMP (1407) +#define DO_NOT_UPDATE_PROP_ROT (1839) +#define CFG_7 (1205) +#define FLAT_STATE_END_TEMP (1683) +#define END_COMPARE_Y_X (1484) +#define SKIP_SWING_END_1 (1551) +#define SKIP_SWING_END_3 (1588) +#define SKIP_SWING_END_2 (1566) +#define TILTG75_START (1672) +#define CFG_6 (2753) +#define TILTL75_END (1669) +#define END_ORIENT (1884) +#define CFG_FLICK_IN (2573) +#define TILTL75_START (1643) +#define CFG_MOTION_BIAS (1208) +#define X_GRT_Y (1408) +#define TEMPLABEL (2324) +#define CFG_ANDROID_ORIENT_INT (1853) +#define CFG_GYRO_RAW_DATA (2722) +#define X_GRT_Y_TMP2 (1379) + +#define D_0_22 (22+512) +#define D_0_24 (24+512) + +#define D_0_36 (36) +#define D_0_52 (52) +#define D_0_96 (96) +#define D_0_104 (104) +#define D_0_108 (108) +#define D_0_163 (163) +#define D_0_188 (188) +#define D_0_192 (192) +#define D_0_224 (224) +#define D_0_228 (228) +#define D_0_232 (232) +#define D_0_236 (236) + +#define D_1_2 (256 + 2) +#define D_1_4 (256 + 4) +#define D_1_8 (256 + 8) +#define D_1_10 (256 + 10) +#define D_1_24 (256 + 24) +#define D_1_28 (256 + 28) +#define D_1_36 (256 + 36) +#define D_1_40 (256 + 40) +#define D_1_44 (256 + 44) +#define D_1_72 (256 + 72) +#define D_1_74 (256 + 74) +#define D_1_79 (256 + 79) +#define D_1_88 (256 + 88) +#define D_1_90 (256 + 90) +#define D_1_92 (256 + 92) +#define D_1_96 (256 + 96) +#define D_1_98 (256 + 98) +#define D_1_106 (256 + 106) +#define D_1_108 (256 + 108) +#define D_1_112 (256 + 112) +#define D_1_128 (256 + 144) +#define D_1_152 (256 + 12) +#define D_1_160 (256 + 160) +#define D_1_176 (256 + 176) +#define D_1_178 (256 + 178) +#define D_1_218 (256 + 218) +#define D_1_232 (256 + 232) +#define D_1_236 (256 + 236) +#define D_1_240 (256 + 240) +#define D_1_244 (256 + 244) +#define D_1_250 (256 + 250) +#define D_1_252 (256 + 252) +#define D_2_12 (512 + 12) +#define D_2_96 (512 + 96) +#define D_2_108 (512 + 108) +#define D_2_208 (512 + 208) +#define D_2_224 (512 + 224) +#define D_2_236 (512 + 236) +#define D_2_244 (512 + 244) +#define D_2_248 (512 + 248) +#define D_2_252 (512 + 252) + +#define CPASS_BIAS_X (35 * 16 + 4) +#define CPASS_BIAS_Y (35 * 16 + 8) +#define CPASS_BIAS_Z (35 * 16 + 12) +#define CPASS_MTX_00 (36 * 16) +#define CPASS_MTX_01 (36 * 16 + 4) +#define CPASS_MTX_02 (36 * 16 + 8) +#define CPASS_MTX_10 (36 * 16 + 12) +#define CPASS_MTX_11 (37 * 16) +#define CPASS_MTX_12 (37 * 16 + 4) +#define CPASS_MTX_20 (37 * 16 + 8) +#define CPASS_MTX_21 (37 * 16 + 12) +#define CPASS_MTX_22 (43 * 16 + 12) +#define D_EXT_GYRO_BIAS_X (61 * 16) +#define D_EXT_GYRO_BIAS_Y (61 * 16) + 4 +#define D_EXT_GYRO_BIAS_Z (61 * 16) + 8 +#define D_ACT0 (40 * 16) +#define D_ACSX (40 * 16 + 4) +#define D_ACSY (40 * 16 + 8) +#define D_ACSZ (40 * 16 + 12) + +#define FLICK_MSG (45 * 16 + 4) +#define FLICK_COUNTER (45 * 16 + 8) +#define FLICK_LOWER (45 * 16 + 12) +#define FLICK_UPPER (46 * 16 + 12) + +#define D_AUTH_OUT (992) +#define D_AUTH_IN (996) +#define D_AUTH_A (1000) +#define D_AUTH_B (1004) + +#define D_PEDSTD_BP_B (768 + 0x1C) +#define D_PEDSTD_HP_A (768 + 0x78) +#define D_PEDSTD_HP_B (768 + 0x7C) +#define D_PEDSTD_BP_A4 (768 + 0x40) +#define D_PEDSTD_BP_A3 (768 + 0x44) +#define D_PEDSTD_BP_A2 (768 + 0x48) +#define D_PEDSTD_BP_A1 (768 + 0x4C) +#define D_PEDSTD_INT_THRSH (768 + 0x68) +#define D_PEDSTD_CLIP (768 + 0x6C) +#define D_PEDSTD_SB (768 + 0x28) +#define D_PEDSTD_SB_TIME (768 + 0x2C) +#define D_PEDSTD_PEAKTHRSH (768 + 0x98) +#define D_PEDSTD_TIML (768 + 0x2A) +#define D_PEDSTD_TIMH (768 + 0x2E) +#define D_PEDSTD_PEAK (768 + 0X94) +#define D_PEDSTD_STEPCTR (768 + 0x60) +#define D_PEDSTD_TIMECTR (964) +#define D_PEDSTD_DECI (768 + 0xA0) + +#define D_HOST_NO_MOT (976) +#define D_ACCEL_BIAS (660) + +#define D_ORIENT_GAP (76) + +#define D_TILT0_H (48) +#define D_TILT0_L (50) +#define D_TILT1_H (52) +#define D_TILT1_L (54) +#define D_TILT2_H (56) +#define D_TILT2_L (58) +#define D_TILT3_H (60) +#define D_TILT3_L (62) + +#define DMP_CODE_SIZE (3062) + +static const unsigned char dmp_memory[DMP_CODE_SIZE] = { + /* bank # 0 */ + 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x65, 0x00, 0x54, 0xff, 0xef, 0x00, 0x00, 0xfa, 0x80, 0x00, 0x0b, 0x12, 0x82, 0x00, 0x01, + 0x03, 0x0c, 0x30, 0xc3, 0x0e, 0x8c, 0x8c, 0xe9, 0x14, 0xd5, 0x40, 0x02, 0x13, 0x71, 0x0f, 0x8e, + 0x38, 0x83, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83, 0x25, 0x8e, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0xfe, 0xa9, 0xd6, 0x24, 0x00, 0x04, 0x00, 0x1a, 0x82, 0x79, 0xa1, + 0x00, 0x00, 0x00, 0x3c, 0xff, 0xff, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x38, 0x83, 0x6f, 0xa2, + 0x00, 0x3e, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xca, 0xe3, 0x09, 0x3e, 0x80, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x6e, 0x00, 0x00, 0x06, 0x92, 0x0a, 0x16, 0xc0, 0xdf, + 0xff, 0xff, 0x02, 0x56, 0xfd, 0x8c, 0xd3, 0x77, 0xff, 0xe1, 0xc4, 0x96, 0xe0, 0xc5, 0xbe, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x2b, 0x00, 0x00, 0x16, 0x57, 0x00, 0x00, 0x03, 0x59, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xfa, 0x00, 0x02, 0x6c, 0x1d, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xdf, 0xeb, 0x00, 0x3e, 0xb3, 0xb6, 0x00, 0x0d, 0x22, 0x78, 0x00, 0x00, 0x2f, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x42, 0xb5, 0x00, 0x00, 0x39, 0xa2, 0x00, 0x00, 0xb3, 0x65, + 0xd9, 0x0e, 0x9f, 0xc9, 0x1d, 0xcf, 0x4c, 0x34, 0x30, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x3b, 0xb6, 0x7a, 0xe8, 0x00, 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank # 1 */ + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0xfa, 0x92, 0x10, 0x00, 0x22, 0x5e, 0x00, 0x0d, 0x22, 0x9f, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0x63, 0xd4, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x04, 0xd6, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x72, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x64, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x32, 0xf8, 0x98, 0x00, 0x00, 0xff, 0x65, 0x00, 0x00, 0x83, 0x0f, 0x00, 0x00, + 0xff, 0x9b, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xb2, 0x6a, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x01, 0xfb, 0x83, 0x00, 0x68, 0x00, 0x00, 0x00, 0xd9, 0xfc, 0x00, 0x7c, 0xf1, 0xff, 0x83, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x64, 0x03, 0xe8, 0x00, 0x64, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x10, 0x00, + /* bank # 2 */ + 0x00, 0x28, 0x00, 0x00, 0xff, 0xff, 0x45, 0x81, 0xff, 0xff, 0xfa, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x05, 0x00, 0x05, 0xba, 0xc6, 0x00, 0x47, 0x78, 0xa2, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x25, 0x4d, 0x00, 0x2f, 0x70, 0x6d, 0x00, 0x00, 0x05, 0xae, 0x00, 0x0c, 0x02, 0xd0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x64, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, + 0x00, 0x00, 0x0a, 0xc7, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xff, 0xff, 0xff, 0x9c, + 0x00, 0x00, 0x0b, 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, + 0xff, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank # 3 */ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x24, 0x26, 0xd3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x96, 0x00, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x0a, 0x4e, 0x68, 0xcd, 0xcf, 0x77, 0x09, 0x50, 0x16, 0x67, 0x59, 0xc6, 0x19, 0xce, 0x82, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd7, 0x84, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x93, 0x8f, 0x9d, 0x1e, 0x1b, 0x1c, 0x19, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x18, 0x85, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x67, 0x7d, 0xdf, 0x7e, 0x72, 0x90, 0x2e, 0x55, 0x4c, 0xf6, 0xe6, 0x88, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* bank # 4 */ + 0xd8, 0xdc, 0xb4, 0xb8, 0xb0, 0xd8, 0xb9, 0xab, 0xf3, 0xf8, 0xfa, 0xb3, 0xb7, 0xbb, 0x8e, 0x9e, + 0xae, 0xf1, 0x32, 0xf5, 0x1b, 0xf1, 0xb4, 0xb8, 0xb0, 0x80, 0x97, 0xf1, 0xa9, 0xdf, 0xdf, 0xdf, + 0xaa, 0xdf, 0xdf, 0xdf, 0xf2, 0xaa, 0xc5, 0xcd, 0xc7, 0xa9, 0x0c, 0xc9, 0x2c, 0x97, 0xf1, 0xa9, + 0x89, 0x26, 0x46, 0x66, 0xb2, 0x89, 0x99, 0xa9, 0x2d, 0x55, 0x7d, 0xb0, 0xb0, 0x8a, 0xa8, 0x96, + 0x36, 0x56, 0x76, 0xf1, 0xba, 0xa3, 0xb4, 0xb2, 0x80, 0xc0, 0xb8, 0xa8, 0x97, 0x11, 0xb2, 0x83, + 0x98, 0xba, 0xa3, 0xf0, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xb2, 0xb9, 0xb4, 0x98, 0x83, 0xf1, + 0xa3, 0x29, 0x55, 0x7d, 0xba, 0xb5, 0xb1, 0xa3, 0x83, 0x93, 0xf0, 0x00, 0x28, 0x50, 0xf5, 0xb2, + 0xb6, 0xaa, 0x83, 0x93, 0x28, 0x54, 0x7c, 0xf1, 0xb9, 0xa3, 0x82, 0x93, 0x61, 0xba, 0xa2, 0xda, + 0xde, 0xdf, 0xdb, 0x81, 0x9a, 0xb9, 0xae, 0xf5, 0x60, 0x68, 0x70, 0xf1, 0xda, 0xba, 0xa2, 0xdf, + 0xd9, 0xba, 0xa2, 0xfa, 0xb9, 0xa3, 0x82, 0x92, 0xdb, 0x31, 0xba, 0xa2, 0xd9, 0xba, 0xa2, 0xf8, + 0xdf, 0x85, 0xa4, 0xd0, 0xc1, 0xbb, 0xad, 0x83, 0xc2, 0xc5, 0xc7, 0xb8, 0xa2, 0xdf, 0xdf, 0xdf, + 0xba, 0xa0, 0xdf, 0xdf, 0xdf, 0xd8, 0xd8, 0xf1, 0xb8, 0xaa, 0xb3, 0x8d, 0xb4, 0x98, 0x0d, 0x35, + 0x5d, 0xb2, 0xb6, 0xba, 0xaf, 0x8c, 0x96, 0x19, 0x8f, 0x9f, 0xa7, 0x0e, 0x16, 0x1e, 0xb4, 0x9a, + 0xb8, 0xaa, 0x87, 0x2c, 0x54, 0x7c, 0xba, 0xa4, 0xb0, 0x8a, 0xb6, 0x91, 0x32, 0x56, 0x76, 0xb2, + 0x84, 0x94, 0xa4, 0xc8, 0x08, 0xcd, 0xd8, 0xb8, 0xb4, 0xb0, 0xf1, 0x99, 0x82, 0xa8, 0x2d, 0x55, + 0x7d, 0x98, 0xa8, 0x0e, 0x16, 0x1e, 0xa2, 0x2c, 0x54, 0x7c, 0x92, 0xa4, 0xf0, 0x2c, 0x50, 0x78, + /* bank # 5 */ + 0xf1, 0x84, 0xa8, 0x98, 0xc4, 0xcd, 0xfc, 0xd8, 0x0d, 0xdb, 0xa8, 0xfc, 0x2d, 0xf3, 0xd9, 0xba, + 0xa6, 0xf8, 0xda, 0xba, 0xa6, 0xde, 0xd8, 0xba, 0xb2, 0xb6, 0x86, 0x96, 0xa6, 0xd0, 0xf3, 0xc8, + 0x41, 0xda, 0xa6, 0xc8, 0xf8, 0xd8, 0xb0, 0xb4, 0xb8, 0x82, 0xa8, 0x92, 0xf5, 0x2c, 0x54, 0x88, + 0x98, 0xf1, 0x35, 0xd9, 0xf4, 0x18, 0xd8, 0xf1, 0xa2, 0xd0, 0xf8, 0xf9, 0xa8, 0x84, 0xd9, 0xc7, + 0xdf, 0xf8, 0xf8, 0x83, 0xc5, 0xda, 0xdf, 0x69, 0xdf, 0x83, 0xc1, 0xd8, 0xf4, 0x01, 0x14, 0xf1, + 0xa8, 0x82, 0x4e, 0xa8, 0x84, 0xf3, 0x11, 0xd1, 0x82, 0xf5, 0xd9, 0x92, 0x28, 0x97, 0x88, 0xf1, + 0x09, 0xf4, 0x1c, 0x1c, 0xd8, 0x84, 0xa8, 0xf3, 0xc0, 0xf9, 0xd1, 0xd9, 0x97, 0x82, 0xf1, 0x29, + 0xf4, 0x0d, 0xd8, 0xf3, 0xf9, 0xf9, 0xd1, 0xd9, 0x82, 0xf4, 0xc2, 0x03, 0xd8, 0xde, 0xdf, 0x1a, + 0xd8, 0xf1, 0xa2, 0xfa, 0xf9, 0xa8, 0x84, 0x98, 0xd9, 0xc7, 0xdf, 0xf8, 0xf8, 0xf8, 0x83, 0xc7, + 0xda, 0xdf, 0x69, 0xdf, 0xf8, 0x83, 0xc3, 0xd8, 0xf4, 0x01, 0x14, 0xf1, 0x98, 0xa8, 0x82, 0x2e, + 0xa8, 0x84, 0xf3, 0x11, 0xd1, 0x82, 0xf5, 0xd9, 0x92, 0x50, 0x97, 0x88, 0xf1, 0x09, 0xf4, 0x1c, + 0xd8, 0x84, 0xa8, 0xf3, 0xc0, 0xf8, 0xf9, 0xd1, 0xd9, 0x97, 0x82, 0xf1, 0x49, 0xf4, 0x0d, 0xd8, + 0xf3, 0xf9, 0xf9, 0xd1, 0xd9, 0x82, 0xf4, 0xc4, 0x03, 0xd8, 0xde, 0xdf, 0xd8, 0xf1, 0xad, 0x88, + 0x98, 0xcc, 0xa8, 0x09, 0xf9, 0xd9, 0x82, 0x92, 0xa8, 0xf5, 0x7c, 0xf1, 0x88, 0x3a, 0xcf, 0x94, + 0x4a, 0x6e, 0x98, 0xdb, 0x69, 0x31, 0xda, 0xad, 0xf2, 0xde, 0xf9, 0xd8, 0x87, 0x95, 0xa8, 0xf2, + 0x21, 0xd1, 0xda, 0xa5, 0xf9, 0xf4, 0x17, 0xd9, 0xf1, 0xae, 0x8e, 0xd0, 0xc0, 0xc3, 0xae, 0x82, + /* bank # 6 */ + 0xc6, 0x84, 0xc3, 0xa8, 0x85, 0x95, 0xc8, 0xa5, 0x88, 0xf2, 0xc0, 0xf1, 0xf4, 0x01, 0x0e, 0xf1, + 0x8e, 0x9e, 0xa8, 0xc6, 0x3e, 0x56, 0xf5, 0x54, 0xf1, 0x88, 0x72, 0xf4, 0x01, 0x15, 0xf1, 0x98, + 0x45, 0x85, 0x6e, 0xf5, 0x8e, 0x9e, 0x04, 0x88, 0xf1, 0x42, 0x98, 0x5a, 0x8e, 0x9e, 0x06, 0x88, + 0x69, 0xf4, 0x01, 0x1c, 0xf1, 0x98, 0x1e, 0x11, 0x08, 0xd0, 0xf5, 0x04, 0xf1, 0x1e, 0x97, 0x02, + 0x02, 0x98, 0x36, 0x25, 0xdb, 0xf9, 0xd9, 0x85, 0xa5, 0xf3, 0xc1, 0xda, 0x85, 0xa5, 0xf3, 0xdf, + 0xd8, 0x85, 0x95, 0xa8, 0xf3, 0x09, 0xda, 0xa5, 0xfa, 0xd8, 0x82, 0x92, 0xa8, 0xf5, 0x78, 0xf1, + 0x88, 0x1a, 0x84, 0x9f, 0x26, 0x88, 0x98, 0x21, 0xda, 0xf4, 0x1d, 0xf3, 0xd8, 0x87, 0x9f, 0x39, + 0xd1, 0xaf, 0xd9, 0xdf, 0xdf, 0xfb, 0xf9, 0xf4, 0x0c, 0xf3, 0xd8, 0xfa, 0xd0, 0xf8, 0xda, 0xf9, + 0xf9, 0xd0, 0xdf, 0xd9, 0xf9, 0xd8, 0xf4, 0x0b, 0xd8, 0xf3, 0x87, 0x9f, 0x39, 0xd1, 0xaf, 0xd9, + 0xdf, 0xdf, 0xf4, 0x1d, 0xf3, 0xd8, 0xfa, 0xfc, 0xa8, 0x69, 0xf9, 0xf9, 0xaf, 0xd0, 0xda, 0xde, + 0xfa, 0xd9, 0xf8, 0x8f, 0x9f, 0xa8, 0xf1, 0xcc, 0xf3, 0x98, 0xdb, 0x45, 0xd9, 0xaf, 0xdf, 0xd0, + 0xf8, 0xd8, 0xf1, 0x8f, 0x9f, 0xa8, 0xca, 0xf3, 0x88, 0x09, 0xda, 0xaf, 0x8f, 0xcb, 0xf8, 0xd8, + 0xf2, 0xad, 0x97, 0x8d, 0x0c, 0xd9, 0xa5, 0xdf, 0xf9, 0xba, 0xa6, 0xf3, 0xfa, 0xf4, 0x12, 0xf2, + 0xd8, 0x95, 0x0d, 0xd1, 0xd9, 0xba, 0xa6, 0xf3, 0xfa, 0xda, 0xa5, 0xf2, 0xc1, 0xba, 0xa6, 0xf3, + 0xdf, 0xd8, 0xf1, 0xba, 0xb2, 0xb6, 0x86, 0x96, 0xa6, 0xd0, 0xca, 0xf3, 0x49, 0xda, 0xa6, 0xcb, + 0xf8, 0xd8, 0xb0, 0xb4, 0xb8, 0xd8, 0xad, 0x84, 0xf2, 0xc0, 0xdf, 0xf1, 0x8f, 0xcb, 0xc3, 0xa8, + /* bank # 7 */ + 0xb2, 0xb6, 0x86, 0x96, 0xc8, 0xc1, 0xcb, 0xc3, 0xf3, 0xb0, 0xb4, 0x88, 0x98, 0xa8, 0x21, 0xdb, + 0x71, 0x8d, 0x9d, 0x71, 0x85, 0x95, 0x21, 0xd9, 0xad, 0xf2, 0xfa, 0xd8, 0x85, 0x97, 0xa8, 0x28, + 0xd9, 0xf4, 0x08, 0xd8, 0xf2, 0x8d, 0x29, 0xda, 0xf4, 0x05, 0xd9, 0xf2, 0x85, 0xa4, 0xc2, 0xf2, + 0xd8, 0xa8, 0x8d, 0x94, 0x01, 0xd1, 0xd9, 0xf4, 0x11, 0xf2, 0xd8, 0x87, 0x21, 0xd8, 0xf4, 0x0a, + 0xd8, 0xf2, 0x84, 0x98, 0xa8, 0xc8, 0x01, 0xd1, 0xd9, 0xf4, 0x11, 0xd8, 0xf3, 0xa4, 0xc8, 0xbb, + 0xaf, 0xd0, 0xf2, 0xde, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xd8, 0xf1, 0xb8, 0xf6, + 0xb5, 0xb9, 0xb0, 0x8a, 0x95, 0xa3, 0xde, 0x3c, 0xa3, 0xd9, 0xf8, 0xd8, 0x5c, 0xa3, 0xd9, 0xf8, + 0xd8, 0x7c, 0xa3, 0xd9, 0xf8, 0xd8, 0xf8, 0xf9, 0xd1, 0xa5, 0xd9, 0xdf, 0xda, 0xfa, 0xd8, 0xb1, + 0x85, 0x30, 0xf7, 0xd9, 0xde, 0xd8, 0xf8, 0x30, 0xad, 0xda, 0xde, 0xd8, 0xf2, 0xb4, 0x8c, 0x99, + 0xa3, 0x2d, 0x55, 0x7d, 0xa0, 0x83, 0xdf, 0xdf, 0xdf, 0xb5, 0x91, 0xa0, 0xf6, 0x29, 0xd9, 0xfb, + 0xd8, 0xa0, 0xfc, 0x29, 0xd9, 0xfa, 0xd8, 0xa0, 0xd0, 0x51, 0xd9, 0xf8, 0xd8, 0xfc, 0x51, 0xd9, + 0xf9, 0xd8, 0x79, 0xd9, 0xfb, 0xd8, 0xa0, 0xd0, 0xfc, 0x79, 0xd9, 0xfa, 0xd8, 0xa1, 0xf9, 0xf9, + 0xf9, 0xf9, 0xf9, 0xa0, 0xda, 0xdf, 0xdf, 0xdf, 0xd8, 0xa1, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xac, + 0xde, 0xf8, 0xad, 0xde, 0x83, 0x93, 0xac, 0x2c, 0x54, 0x7c, 0xf1, 0xa8, 0xdf, 0xdf, 0xdf, 0xf6, + 0x9d, 0x2c, 0xda, 0xa0, 0xdf, 0xd9, 0xfa, 0xdb, 0x2d, 0xf8, 0xd8, 0xa8, 0x50, 0xda, 0xa0, 0xd0, + 0xde, 0xd9, 0xd0, 0xf8, 0xf8, 0xf8, 0xdb, 0x55, 0xf8, 0xd8, 0xa8, 0x78, 0xda, 0xa0, 0xd0, 0xdf, + /* bank # 8 */ + 0xd9, 0xd0, 0xfa, 0xf8, 0xf8, 0xf8, 0xf8, 0xdb, 0x7d, 0xf8, 0xd8, 0x9c, 0xa8, 0x8c, 0xf5, 0x30, + 0xdb, 0x38, 0xd9, 0xd0, 0xde, 0xdf, 0xa0, 0xd0, 0xde, 0xdf, 0xd8, 0xa8, 0x48, 0xdb, 0x58, 0xd9, + 0xdf, 0xd0, 0xde, 0xa0, 0xdf, 0xd0, 0xde, 0xd8, 0xa8, 0x68, 0xdb, 0x70, 0xd9, 0xdf, 0xdf, 0xa0, + 0xdf, 0xdf, 0xd8, 0xf1, 0xa8, 0x88, 0x90, 0x2c, 0x54, 0x7c, 0x98, 0xa8, 0xd0, 0x5c, 0x38, 0xd1, + 0xda, 0xf2, 0xae, 0x8c, 0xdf, 0xf9, 0xd8, 0xb0, 0x87, 0xa8, 0xc1, 0xc1, 0xb1, 0x88, 0xa8, 0xc6, + 0xf9, 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xa8, + 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xf7, 0x8d, 0x9d, 0xad, 0xf8, 0x18, 0xda, + 0xf2, 0xae, 0xdf, 0xd8, 0xf7, 0xad, 0xfa, 0x30, 0xd9, 0xa4, 0xde, 0xf9, 0xd8, 0xf2, 0xae, 0xde, + 0xfa, 0xf9, 0x83, 0xa7, 0xd9, 0xc3, 0xc5, 0xc7, 0xf1, 0x88, 0x9b, 0xa7, 0x7a, 0xad, 0xf7, 0xde, + 0xdf, 0xa4, 0xf8, 0x84, 0x94, 0x08, 0xa7, 0x97, 0xf3, 0x00, 0xae, 0xf2, 0x98, 0x19, 0xa4, 0x88, + 0xc6, 0xa3, 0x94, 0x88, 0xf6, 0x32, 0xdf, 0xf2, 0x83, 0x93, 0xdb, 0x09, 0xd9, 0xf2, 0xaa, 0xdf, + 0xd8, 0xd8, 0xae, 0xf8, 0xf9, 0xd1, 0xda, 0xf3, 0xa4, 0xde, 0xa7, 0xf1, 0x88, 0x9b, 0x7a, 0xd8, + 0xf3, 0x84, 0x94, 0xae, 0x19, 0xf9, 0xda, 0xaa, 0xf1, 0xdf, 0xd8, 0xa8, 0x81, 0xc0, 0xc3, 0xc5, + 0xc7, 0xa3, 0x92, 0x83, 0xf6, 0x28, 0xad, 0xde, 0xd9, 0xf8, 0xd8, 0xa3, 0x50, 0xad, 0xd9, 0xf8, + 0xd8, 0xa3, 0x78, 0xad, 0xd9, 0xf8, 0xd8, 0xf8, 0xf9, 0xd1, 0xa1, 0xda, 0xde, 0xc3, 0xc5, 0xc7, + 0xd8, 0xa1, 0x81, 0x94, 0xf8, 0x18, 0xf2, 0xb0, 0x89, 0xac, 0xc3, 0xc5, 0xc7, 0xf1, 0xd8, 0xb8, + /* bank # 9 */ + 0xb4, 0xb0, 0x97, 0x86, 0xa8, 0x31, 0x9b, 0x06, 0x99, 0x07, 0xab, 0x97, 0x28, 0x88, 0x9b, 0xf0, + 0x0c, 0x20, 0x14, 0x40, 0xb0, 0xb4, 0xb8, 0xf0, 0xa8, 0x8a, 0x9a, 0x28, 0x50, 0x78, 0xb7, 0x9b, + 0xa8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xf1, 0xbb, 0xab, + 0x88, 0x00, 0x2c, 0x54, 0x7c, 0xf0, 0xb3, 0x8b, 0xb8, 0xa8, 0x04, 0x28, 0x50, 0x78, 0xf1, 0xb0, + 0x88, 0xb4, 0x97, 0x26, 0xa8, 0x59, 0x98, 0xbb, 0xab, 0xb3, 0x8b, 0x02, 0x26, 0x46, 0x66, 0xb0, + 0xb8, 0xf0, 0x8a, 0x9c, 0xa8, 0x29, 0x51, 0x79, 0x8b, 0x29, 0x51, 0x79, 0x8a, 0x24, 0x70, 0x59, + 0x8b, 0x20, 0x58, 0x71, 0x8a, 0x44, 0x69, 0x38, 0x8b, 0x39, 0x40, 0x68, 0x8a, 0x64, 0x48, 0x31, + 0x8b, 0x30, 0x49, 0x60, 0x88, 0xf1, 0xac, 0x00, 0x2c, 0x54, 0x7c, 0xf0, 0x8c, 0xa8, 0x04, 0x28, + 0x50, 0x78, 0xf1, 0x88, 0x97, 0x26, 0xa8, 0x59, 0x98, 0xac, 0x8c, 0x02, 0x26, 0x46, 0x66, 0xf0, + 0x89, 0x9c, 0xa8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xa9, + 0x88, 0x09, 0x20, 0x59, 0x70, 0xab, 0x11, 0x38, 0x40, 0x69, 0xa8, 0x19, 0x31, 0x48, 0x60, 0x8c, + 0xa8, 0x3c, 0x41, 0x5c, 0x20, 0x7c, 0x00, 0xf1, 0x87, 0x98, 0x19, 0x86, 0xa8, 0x6e, 0x76, 0x7e, + 0xa9, 0x99, 0x88, 0x2d, 0x55, 0x7d, 0xd8, 0xb1, 0xb5, 0xb9, 0xa3, 0xdf, 0xdf, 0xdf, 0xae, 0xd0, + 0xdf, 0xaa, 0xd0, 0xde, 0xf2, 0xab, 0xf8, 0xf9, 0xd9, 0xb0, 0x87, 0xc4, 0xaa, 0xf1, 0xdf, 0xdf, + 0xbb, 0xaf, 0xdf, 0xdf, 0xb9, 0xd8, 0xb1, 0xf1, 0xa3, 0x97, 0x8e, 0x60, 0xdf, 0xb0, 0x84, 0xf2, + 0xc8, 0xf8, 0xf9, 0xd9, 0xde, 0xd8, 0x93, 0x85, 0xf1, 0x4a, 0xb1, 0x83, 0xa3, 0x08, 0xb5, 0x83, + /* bank # 10 */ + 0x9a, 0x08, 0x10, 0xb7, 0x9f, 0x10, 0xd8, 0xf1, 0xb0, 0xba, 0xae, 0xb0, 0x8a, 0xc2, 0xb2, 0xb6, + 0x8e, 0x9e, 0xf1, 0xfb, 0xd9, 0xf4, 0x1d, 0xd8, 0xf9, 0xd9, 0x0c, 0xf1, 0xd8, 0xf8, 0xf8, 0xad, + 0x61, 0xd9, 0xae, 0xfb, 0xd8, 0xf4, 0x0c, 0xf1, 0xd8, 0xf8, 0xf8, 0xad, 0x19, 0xd9, 0xae, 0xfb, + 0xdf, 0xd8, 0xf4, 0x16, 0xf1, 0xd8, 0xf8, 0xad, 0x8d, 0x61, 0xd9, 0xf4, 0xf4, 0xac, 0xf5, 0x9c, + 0x9c, 0x8d, 0xdf, 0x2b, 0xba, 0xb6, 0xae, 0xfa, 0xf8, 0xf4, 0x0b, 0xd8, 0xf1, 0xae, 0xd0, 0xf8, + 0xad, 0x51, 0xda, 0xae, 0xfa, 0xf8, 0xf1, 0xd8, 0xb9, 0xb1, 0xb6, 0xa3, 0x83, 0x9c, 0x08, 0xb9, + 0xb1, 0x83, 0x9a, 0xb5, 0xaa, 0xc0, 0xfd, 0x30, 0x83, 0xb7, 0x9f, 0x10, 0xb5, 0x8b, 0x93, 0xf2, + 0x02, 0x02, 0xd1, 0xab, 0xda, 0xde, 0xd8, 0xf1, 0xb0, 0x80, 0xba, 0xab, 0xc0, 0xc3, 0xb2, 0x84, + 0xc1, 0xc3, 0xd8, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9, 0xab, 0xde, 0xb0, + 0x87, 0x9c, 0xb9, 0xa3, 0xdd, 0xf1, 0xb3, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0xb0, 0x87, 0xa3, 0xa3, + 0xa3, 0xa3, 0xb2, 0x8b, 0xb6, 0x9b, 0xf2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xf1, 0xb0, 0x87, 0xb5, 0x9a, 0xa3, 0xf3, 0x9b, 0xa3, 0xa3, 0xdc, 0xba, 0xac, 0xdf, 0xb9, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xd8, 0xd8, 0xd8, 0xbb, 0xb3, 0xb7, 0xf1, 0xaa, 0xf9, 0xda, 0xff, 0xd9, 0x80, 0x9a, 0xaa, 0x28, + 0xb4, 0x80, 0x98, 0xa7, 0x20, 0xb7, 0x97, 0x87, 0xa8, 0x66, 0x88, 0xf0, 0x79, 0x51, 0xf1, 0x90, + 0x2c, 0x87, 0x0c, 0xa7, 0x81, 0x97, 0x62, 0x93, 0xf0, 0x71, 0x71, 0x60, 0x85, 0x94, 0x01, 0x29, + /* bank # 11 */ + 0x51, 0x79, 0x90, 0xa5, 0xf1, 0x28, 0x4c, 0x6c, 0x87, 0x0c, 0x95, 0x18, 0x85, 0x78, 0xa3, 0x83, + 0x90, 0x28, 0x4c, 0x6c, 0x88, 0x6c, 0xd8, 0xf3, 0xa2, 0x82, 0x00, 0xf2, 0x10, 0xa8, 0x92, 0x19, + 0x80, 0xa2, 0xf2, 0xd9, 0x26, 0xd8, 0xf1, 0x88, 0xa8, 0x4d, 0xd9, 0x48, 0xd8, 0x96, 0xa8, 0x39, + 0x80, 0xd9, 0x3c, 0xd8, 0x95, 0x80, 0xa8, 0x39, 0xa6, 0x86, 0x98, 0xd9, 0x2c, 0xda, 0x87, 0xa7, + 0x2c, 0xd8, 0xa8, 0x89, 0x95, 0x19, 0xa9, 0x80, 0xd9, 0x38, 0xd8, 0xa8, 0x89, 0x39, 0xa9, 0x80, + 0xda, 0x3c, 0xd8, 0xa8, 0x2e, 0xa8, 0x39, 0x90, 0xd9, 0x0c, 0xd8, 0xa8, 0x95, 0x31, 0x98, 0xd9, + 0x0c, 0xd8, 0xa8, 0x09, 0xd9, 0xff, 0xd8, 0x01, 0xda, 0xff, 0xd8, 0x95, 0x39, 0xa9, 0xda, 0x26, + 0xff, 0xd8, 0x90, 0xa8, 0x0d, 0x89, 0x99, 0xa8, 0x10, 0x80, 0x98, 0x21, 0xda, 0x2e, 0xd8, 0x89, + 0x99, 0xa8, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, 0x86, 0x96, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, + 0x87, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, 0x82, 0x92, 0xf3, 0x41, 0x80, 0xf1, 0xd9, 0x2e, 0xd8, + 0xa8, 0x82, 0xf3, 0x19, 0x80, 0xf1, 0xd9, 0x2e, 0xd8, 0x82, 0xac, 0xf3, 0xc0, 0xa2, 0x80, 0x22, + 0xf1, 0xa6, 0x2e, 0xa7, 0x2e, 0xa9, 0x22, 0x98, 0xa8, 0x29, 0xda, 0xac, 0xde, 0xff, 0xd8, 0xa2, + 0xf2, 0x2a, 0xf1, 0xa9, 0x2e, 0x82, 0x92, 0xa8, 0xf2, 0x31, 0x80, 0xa6, 0x96, 0xf1, 0xd9, 0x00, + 0xac, 0x8c, 0x9c, 0x0c, 0x30, 0xac, 0xde, 0xd0, 0xde, 0xff, 0xd8, 0x8c, 0x9c, 0xac, 0xd0, 0x10, + 0xac, 0xde, 0x80, 0x92, 0xa2, 0xf2, 0x4c, 0x82, 0xa8, 0xf1, 0xca, 0xf2, 0x35, 0xf1, 0x96, 0x88, + 0xa6, 0xd9, 0x00, 0xd8, 0xf1, 0xff +}; + +static const unsigned short sStartAddress = 0x0400; + +/* END OF SECTION COPIED FROM dmpDefaultMPU6050.c */ + +#define INT_SRC_TAP (0x01) +#define INT_SRC_ANDROID_ORIENT (0x08) + +#define DMP_FEATURE_SEND_ANY_GYRO (DMP_FEATURE_SEND_RAW_GYRO | \ + DMP_FEATURE_SEND_CAL_GYRO) + +#define MAX_PACKET_LENGTH (32) + +#define DMP_SAMPLE_RATE (200) +#define GYRO_SF (46850825LL * 200 / DMP_SAMPLE_RATE) + +#define FIFO_CORRUPTION_CHECK +#ifdef FIFO_CORRUPTION_CHECK +#define QUAT_ERROR_THRESH (1L<<24) +#define QUAT_MAG_SQ_NORMALIZED (1L<<28) +#define QUAT_MAG_SQ_MIN (QUAT_MAG_SQ_NORMALIZED - QUAT_ERROR_THRESH) +#define QUAT_MAG_SQ_MAX (QUAT_MAG_SQ_NORMALIZED + QUAT_ERROR_THRESH) +#endif + +struct dmp_s { + void (*tap_cb)(unsigned char count, unsigned char direction); + void (*android_orient_cb)(unsigned char orientation); + unsigned short orient; + unsigned short feature_mask; + unsigned short fifo_rate; + unsigned char packet_length; +}; + +static struct dmp_s dmp = { + .tap_cb = NULL, + .android_orient_cb = NULL, + .orient = 0, + .feature_mask = 0, + .fifo_rate = 0, + .packet_length = 0 +}; + +/** + * @brief Load the DMP with this image. + * @return 0 if successful. + */ +int dmp_load_motion_driver_firmware(void) +{ + return mpu_load_firmware(DMP_CODE_SIZE, dmp_memory, sStartAddress, + DMP_SAMPLE_RATE); +} + +/** + * @brief Push gyro and accel orientation to the DMP. + * The orientation is represented here as the output of + * @e inv_orientation_matrix_to_scalar. + * @param[in] orient Gyro and accel orientation in body frame. + * @return 0 if successful. + */ +int dmp_set_orientation(unsigned short orient) +{ + unsigned char gyro_regs[3], accel_regs[3]; + const unsigned char gyro_axes[3] = {DINA4C, DINACD, DINA6C}; + const unsigned char accel_axes[3] = {DINA0C, DINAC9, DINA2C}; + const unsigned char gyro_sign[3] = {DINA36, DINA56, DINA76}; + const unsigned char accel_sign[3] = {DINA26, DINA46, DINA66}; + + gyro_regs[0] = gyro_axes[orient & 3]; + gyro_regs[1] = gyro_axes[(orient >> 3) & 3]; + gyro_regs[2] = gyro_axes[(orient >> 6) & 3]; + accel_regs[0] = accel_axes[orient & 3]; + accel_regs[1] = accel_axes[(orient >> 3) & 3]; + accel_regs[2] = accel_axes[(orient >> 6) & 3]; + + /* Chip-to-body, axes only. */ + if (mpu_write_mem(FCFG_1, 3, gyro_regs)) + return -1; + if (mpu_write_mem(FCFG_2, 3, accel_regs)) + return -1; + + memcpy(gyro_regs, gyro_sign, 3); + memcpy(accel_regs, accel_sign, 3); + if (orient & 4) { + gyro_regs[0] |= 1; + accel_regs[0] |= 1; + } + if (orient & 0x20) { + gyro_regs[1] |= 1; + accel_regs[1] |= 1; + } + if (orient & 0x100) { + gyro_regs[2] |= 1; + accel_regs[2] |= 1; + } + + /* Chip-to-body, sign only. */ + if (mpu_write_mem(FCFG_3, 3, gyro_regs)) + return -1; + if (mpu_write_mem(FCFG_7, 3, accel_regs)) + return -1; + dmp.orient = orient; + return 0; +} + +/** + * @brief Push gyro biases to the DMP. + * Because the gyro integration is handled in the DMP, any gyro biases + * calculated by the MPL should be pushed down to DMP memory to remove + * 3-axis quaternion drift. + * \n NOTE: If the DMP-based gyro calibration is enabled, the DMP will + * overwrite the biases written to this location once a new one is computed. + * @param[in] bias Gyro biases in q16. + * @return 0 if successful. + */ +int dmp_set_gyro_bias(long *bias) +{ + long gyro_bias_body[3]; + unsigned char regs[4]; + + gyro_bias_body[0] = bias[dmp.orient & 3]; + if (dmp.orient & 4) + gyro_bias_body[0] *= -1; + gyro_bias_body[1] = bias[(dmp.orient >> 3) & 3]; + if (dmp.orient & 0x20) + gyro_bias_body[1] *= -1; + gyro_bias_body[2] = bias[(dmp.orient >> 6) & 3]; + if (dmp.orient & 0x100) + gyro_bias_body[2] *= -1; + +#ifdef EMPL_NO_64BIT + gyro_bias_body[0] = (long)(((float)gyro_bias_body[0] * GYRO_SF) / 1073741824.f); + gyro_bias_body[1] = (long)(((float)gyro_bias_body[1] * GYRO_SF) / 1073741824.f); + gyro_bias_body[2] = (long)(((float)gyro_bias_body[2] * GYRO_SF) / 1073741824.f); +#else + gyro_bias_body[0] = (long)(((long long)gyro_bias_body[0] * GYRO_SF) >> 30); + gyro_bias_body[1] = (long)(((long long)gyro_bias_body[1] * GYRO_SF) >> 30); + gyro_bias_body[2] = (long)(((long long)gyro_bias_body[2] * GYRO_SF) >> 30); +#endif + + regs[0] = (unsigned char)((gyro_bias_body[0] >> 24) & 0xFF); + regs[1] = (unsigned char)((gyro_bias_body[0] >> 16) & 0xFF); + regs[2] = (unsigned char)((gyro_bias_body[0] >> 8) & 0xFF); + regs[3] = (unsigned char)(gyro_bias_body[0] & 0xFF); + if (mpu_write_mem(D_EXT_GYRO_BIAS_X, 4, regs)) + return -1; + + regs[0] = (unsigned char)((gyro_bias_body[1] >> 24) & 0xFF); + regs[1] = (unsigned char)((gyro_bias_body[1] >> 16) & 0xFF); + regs[2] = (unsigned char)((gyro_bias_body[1] >> 8) & 0xFF); + regs[3] = (unsigned char)(gyro_bias_body[1] & 0xFF); + if (mpu_write_mem(D_EXT_GYRO_BIAS_Y, 4, regs)) + return -1; + + regs[0] = (unsigned char)((gyro_bias_body[2] >> 24) & 0xFF); + regs[1] = (unsigned char)((gyro_bias_body[2] >> 16) & 0xFF); + regs[2] = (unsigned char)((gyro_bias_body[2] >> 8) & 0xFF); + regs[3] = (unsigned char)(gyro_bias_body[2] & 0xFF); + return mpu_write_mem(D_EXT_GYRO_BIAS_Z, 4, regs); +} + +/** + * @brief Push accel biases to the DMP. + * These biases will be removed from the DMP 6-axis quaternion. + * @param[in] bias Accel biases in q16. + * @return 0 if successful. + */ +int dmp_set_accel_bias(long *bias) +{ + long accel_bias_body[3]; + unsigned char regs[12]; + long long accel_sf; + unsigned short accel_sens; + + mpu_get_accel_sens(&accel_sens); + accel_sf = (long long)accel_sens << 15; + //__no_operation(); + + accel_bias_body[0] = bias[dmp.orient & 3]; + if (dmp.orient & 4) + accel_bias_body[0] *= -1; + accel_bias_body[1] = bias[(dmp.orient >> 3) & 3]; + if (dmp.orient & 0x20) + accel_bias_body[1] *= -1; + accel_bias_body[2] = bias[(dmp.orient >> 6) & 3]; + if (dmp.orient & 0x100) + accel_bias_body[2] *= -1; + +#ifdef EMPL_NO_64BIT + accel_bias_body[0] = (long)(((float)accel_bias_body[0] * accel_sf) / 1073741824.f); + accel_bias_body[1] = (long)(((float)accel_bias_body[1] * accel_sf) / 1073741824.f); + accel_bias_body[2] = (long)(((float)accel_bias_body[2] * accel_sf) / 1073741824.f); +#else + accel_bias_body[0] = (long)(((long long)accel_bias_body[0] * accel_sf) >> 30); + accel_bias_body[1] = (long)(((long long)accel_bias_body[1] * accel_sf) >> 30); + accel_bias_body[2] = (long)(((long long)accel_bias_body[2] * accel_sf) >> 30); +#endif + + regs[0] = (unsigned char)((accel_bias_body[0] >> 24) & 0xFF); + regs[1] = (unsigned char)((accel_bias_body[0] >> 16) & 0xFF); + regs[2] = (unsigned char)((accel_bias_body[0] >> 8) & 0xFF); + regs[3] = (unsigned char)(accel_bias_body[0] & 0xFF); + regs[4] = (unsigned char)((accel_bias_body[1] >> 24) & 0xFF); + regs[5] = (unsigned char)((accel_bias_body[1] >> 16) & 0xFF); + regs[6] = (unsigned char)((accel_bias_body[1] >> 8) & 0xFF); + regs[7] = (unsigned char)(accel_bias_body[1] & 0xFF); + regs[8] = (unsigned char)((accel_bias_body[2] >> 24) & 0xFF); + regs[9] = (unsigned char)((accel_bias_body[2] >> 16) & 0xFF); + regs[10] = (unsigned char)((accel_bias_body[2] >> 8) & 0xFF); + regs[11] = (unsigned char)(accel_bias_body[2] & 0xFF); + return mpu_write_mem(D_ACCEL_BIAS, 12, regs); +} + +/** + * @brief Set DMP output rate. + * Only used when DMP is on. + * @param[in] rate Desired fifo rate (Hz). + * @return 0 if successful. + */ +int dmp_set_fifo_rate(unsigned short rate) +{ + const unsigned char regs_end[12] = {DINAFE, DINAF2, DINAAB, + 0xc4, DINAAA, DINAF1, DINADF, DINADF, 0xBB, 0xAF, DINADF, DINADF}; + unsigned short div; + unsigned char tmp[8]; + + if (rate > DMP_SAMPLE_RATE) + return -1; + div = DMP_SAMPLE_RATE / rate - 1; + tmp[0] = (unsigned char)((div >> 8) & 0xFF); + tmp[1] = (unsigned char)(div & 0xFF); + if (mpu_write_mem(D_0_22, 2, tmp)) + return -1; + if (mpu_write_mem(CFG_6, 12, (unsigned char*)regs_end)) + return -1; + + dmp.fifo_rate = rate; + return 0; +} + +/** + * @brief Get DMP output rate. + * @param[out] rate Current fifo rate (Hz). + * @return 0 if successful. + */ +int dmp_get_fifo_rate(unsigned short *rate) +{ + rate[0] = dmp.fifo_rate; + return 0; +} + +/** + * @brief Set tap threshold for a specific axis. + * @param[in] axis 1, 2, and 4 for XYZ accel, respectively. + * @param[in] thresh Tap threshold, in mg/ms. + * @return 0 if successful. + */ +int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh) +{ + unsigned char tmp[4], accel_fsr; + float scaled_thresh; + unsigned short dmp_thresh, dmp_thresh_2; + if (!(axis & TAP_XYZ) || thresh > 1600) + return -1; + + scaled_thresh = (float)thresh / DMP_SAMPLE_RATE; + + mpu_get_accel_fsr(&accel_fsr); + switch (accel_fsr) { + case 2: + dmp_thresh = (unsigned short)(scaled_thresh * 16384); + /* dmp_thresh * 0.75 */ + dmp_thresh_2 = (unsigned short)(scaled_thresh * 12288); + break; + case 4: + dmp_thresh = (unsigned short)(scaled_thresh * 8192); + /* dmp_thresh * 0.75 */ + dmp_thresh_2 = (unsigned short)(scaled_thresh * 6144); + break; + case 8: + dmp_thresh = (unsigned short)(scaled_thresh * 4096); + /* dmp_thresh * 0.75 */ + dmp_thresh_2 = (unsigned short)(scaled_thresh * 3072); + break; + case 16: + dmp_thresh = (unsigned short)(scaled_thresh * 2048); + /* dmp_thresh * 0.75 */ + dmp_thresh_2 = (unsigned short)(scaled_thresh * 1536); + break; + default: + return -1; + } + tmp[0] = (unsigned char)(dmp_thresh >> 8); + tmp[1] = (unsigned char)(dmp_thresh & 0xFF); + tmp[2] = (unsigned char)(dmp_thresh_2 >> 8); + tmp[3] = (unsigned char)(dmp_thresh_2 & 0xFF); + + if (axis & TAP_X) { + if (mpu_write_mem(DMP_TAP_THX, 2, tmp)) + return -1; + if (mpu_write_mem(D_1_36, 2, tmp+2)) + return -1; + } + if (axis & TAP_Y) { + if (mpu_write_mem(DMP_TAP_THY, 2, tmp)) + return -1; + if (mpu_write_mem(D_1_40, 2, tmp+2)) + return -1; + } + if (axis & TAP_Z) { + if (mpu_write_mem(DMP_TAP_THZ, 2, tmp)) + return -1; + if (mpu_write_mem(D_1_44, 2, tmp+2)) + return -1; + } + return 0; +} + +/** + * @brief Set which axes will register a tap. + * @param[in] axis 1, 2, and 4 for XYZ, respectively. + * @return 0 if successful. + */ +int dmp_set_tap_axes(unsigned char axis) +{ + unsigned char tmp = 0; + + if (axis & TAP_X) + tmp |= 0x30; + if (axis & TAP_Y) + tmp |= 0x0C; + if (axis & TAP_Z) + tmp |= 0x03; + return mpu_write_mem(D_1_72, 1, &tmp); +} + +/** + * @brief Set minimum number of taps needed for an interrupt. + * @param[in] min_taps Minimum consecutive taps (1-4). + * @return 0 if successful. + */ +int dmp_set_tap_count(unsigned char min_taps) +{ + unsigned char tmp; + + if (min_taps < 1) + min_taps = 1; + else if (min_taps > 4) + min_taps = 4; + + tmp = min_taps - 1; + return mpu_write_mem(D_1_79, 1, &tmp); +} + +/** + * @brief Set length between valid taps. + * @param[in] time Milliseconds between taps. + * @return 0 if successful. + */ +int dmp_set_tap_time(unsigned short time) +{ + unsigned short dmp_time; + unsigned char tmp[2]; + + dmp_time = time / (1000 / DMP_SAMPLE_RATE); + tmp[0] = (unsigned char)(dmp_time >> 8); + tmp[1] = (unsigned char)(dmp_time & 0xFF); + return mpu_write_mem(DMP_TAPW_MIN, 2, tmp); +} + +/** + * @brief Set max time between taps to register as a multi-tap. + * @param[in] time Max milliseconds between taps. + * @return 0 if successful. + */ +int dmp_set_tap_time_multi(unsigned short time) +{ + unsigned short dmp_time; + unsigned char tmp[2]; + + dmp_time = time / (1000 / DMP_SAMPLE_RATE); + tmp[0] = (unsigned char)(dmp_time >> 8); + tmp[1] = (unsigned char)(dmp_time & 0xFF); + return mpu_write_mem(D_1_218, 2, tmp); +} + +/** + * @brief Set shake rejection threshold. + * If the DMP detects a gyro sample larger than @e thresh, taps are rejected. + * @param[in] sf Gyro scale factor. + * @param[in] thresh Gyro threshold in dps. + * @return 0 if successful. + */ +int dmp_set_shake_reject_thresh(long sf, unsigned short thresh) +{ + unsigned char tmp[4]; + long thresh_scaled = sf / 1000 * thresh; + tmp[0] = (unsigned char)(((long)thresh_scaled >> 24) & 0xFF); + tmp[1] = (unsigned char)(((long)thresh_scaled >> 16) & 0xFF); + tmp[2] = (unsigned char)(((long)thresh_scaled >> 8) & 0xFF); + tmp[3] = (unsigned char)((long)thresh_scaled & 0xFF); + return mpu_write_mem(D_1_92, 4, tmp); +} + +/** + * @brief Set shake rejection time. + * Sets the length of time that the gyro must be outside of the threshold set + * by @e gyro_set_shake_reject_thresh before taps are rejected. A mandatory + * 60 ms is added to this parameter. + * @param[in] time Time in milliseconds. + * @return 0 if successful. + */ +int dmp_set_shake_reject_time(unsigned short time) +{ + unsigned char tmp[2]; + + time /= (1000 / DMP_SAMPLE_RATE); + tmp[0] = time >> 8; + tmp[1] = time & 0xFF; + return mpu_write_mem(D_1_90,2,tmp); +} + +/** + * @brief Set shake rejection timeout. + * Sets the length of time after a shake rejection that the gyro must stay + * inside of the threshold before taps can be detected again. A mandatory + * 60 ms is added to this parameter. + * @param[in] time Time in milliseconds. + * @return 0 if successful. + */ +int dmp_set_shake_reject_timeout(unsigned short time) +{ + unsigned char tmp[2]; + + time /= (1000 / DMP_SAMPLE_RATE); + tmp[0] = time >> 8; + tmp[1] = time & 0xFF; + return mpu_write_mem(D_1_88,2,tmp); +} + +/** + * @brief Get current step count. + * @param[out] count Number of steps detected. + * @return 0 if successful. + */ +int dmp_get_pedometer_step_count(unsigned long *count) +{ + unsigned char tmp[4]; + if (!count) + return -1; + + if (mpu_read_mem(D_PEDSTD_STEPCTR, 4, tmp)) + return -1; + + count[0] = ((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) | + ((unsigned long)tmp[2] << 8) | tmp[3]; + return 0; +} + +/** + * @brief Overwrite current step count. + * WARNING: This function writes to DMP memory and could potentially encounter + * a race condition if called while the pedometer is enabled. + * @param[in] count New step count. + * @return 0 if successful. + */ +int dmp_set_pedometer_step_count(unsigned long count) +{ + unsigned char tmp[4]; + + tmp[0] = (unsigned char)((count >> 24) & 0xFF); + tmp[1] = (unsigned char)((count >> 16) & 0xFF); + tmp[2] = (unsigned char)((count >> 8) & 0xFF); + tmp[3] = (unsigned char)(count & 0xFF); + return mpu_write_mem(D_PEDSTD_STEPCTR, 4, tmp); +} + +/** + * @brief Get duration of walking time. + * @param[in] time Walk time in milliseconds. + * @return 0 if successful. + */ +int dmp_get_pedometer_walk_time(unsigned long *time) +{ + unsigned char tmp[4]; + if (!time) + return -1; + + if (mpu_read_mem(D_PEDSTD_TIMECTR, 4, tmp)) + return -1; + + time[0] = (((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) | + ((unsigned long)tmp[2] << 8) | tmp[3]) * 20; + return 0; +} + +/** + * @brief Overwrite current walk time. + * WARNING: This function writes to DMP memory and could potentially encounter + * a race condition if called while the pedometer is enabled. + * @param[in] time New walk time in milliseconds. + */ +int dmp_set_pedometer_walk_time(unsigned long time) +{ + unsigned char tmp[4]; + + time /= 20; + + tmp[0] = (unsigned char)((time >> 24) & 0xFF); + tmp[1] = (unsigned char)((time >> 16) & 0xFF); + tmp[2] = (unsigned char)((time >> 8) & 0xFF); + tmp[3] = (unsigned char)(time & 0xFF); + return mpu_write_mem(D_PEDSTD_TIMECTR, 4, tmp); +} + +/** + * @brief Enable DMP features. + * The following \#define's are used in the input mask: + * \n DMP_FEATURE_TAP + * \n DMP_FEATURE_ANDROID_ORIENT + * \n DMP_FEATURE_LP_QUAT + * \n DMP_FEATURE_6X_LP_QUAT + * \n DMP_FEATURE_GYRO_CAL + * \n DMP_FEATURE_SEND_RAW_ACCEL + * \n DMP_FEATURE_SEND_RAW_GYRO + * \n NOTE: DMP_FEATURE_LP_QUAT and DMP_FEATURE_6X_LP_QUAT are mutually + * exclusive. + * \n NOTE: DMP_FEATURE_SEND_RAW_GYRO and DMP_FEATURE_SEND_CAL_GYRO are also + * mutually exclusive. + * @param[in] mask Mask of features to enable. + * @return 0 if successful. + */ +int dmp_enable_feature(unsigned short mask) +{ + unsigned char tmp[10]; + + /* TODO: All of these settings can probably be integrated into the default + * DMP image. + */ + /* Set integration scale factor. */ + tmp[0] = (unsigned char)((GYRO_SF >> 24) & 0xFF); + tmp[1] = (unsigned char)((GYRO_SF >> 16) & 0xFF); + tmp[2] = (unsigned char)((GYRO_SF >> 8) & 0xFF); + tmp[3] = (unsigned char)(GYRO_SF & 0xFF); + mpu_write_mem(D_0_104, 4, tmp); + + /* Send sensor data to the FIFO. */ + tmp[0] = 0xA3; + if (mask & DMP_FEATURE_SEND_RAW_ACCEL) { + tmp[1] = 0xC0; + tmp[2] = 0xC8; + tmp[3] = 0xC2; + } else { + tmp[1] = 0xA3; + tmp[2] = 0xA3; + tmp[3] = 0xA3; + } + if (mask & DMP_FEATURE_SEND_ANY_GYRO) { + tmp[4] = 0xC4; + tmp[5] = 0xCC; + tmp[6] = 0xC6; + } else { + tmp[4] = 0xA3; + tmp[5] = 0xA3; + tmp[6] = 0xA3; + } + tmp[7] = 0xA3; + tmp[8] = 0xA3; + tmp[9] = 0xA3; + mpu_write_mem(CFG_15,10,tmp); + + /* Send gesture data to the FIFO. */ + if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) + tmp[0] = DINA20; + else + tmp[0] = 0xD8; + mpu_write_mem(CFG_27,1,tmp); + + if (mask & DMP_FEATURE_GYRO_CAL) + dmp_enable_gyro_cal(1); + else + dmp_enable_gyro_cal(0); + + if (mask & DMP_FEATURE_SEND_ANY_GYRO) { + if (mask & DMP_FEATURE_SEND_CAL_GYRO) { + tmp[0] = 0xB2; + tmp[1] = 0x8B; + tmp[2] = 0xB6; + tmp[3] = 0x9B; + } else { + tmp[0] = DINAC0; + tmp[1] = DINA80; + tmp[2] = DINAC2; + tmp[3] = DINA90; + } + mpu_write_mem(CFG_GYRO_RAW_DATA, 4, tmp); + } + + if (mask & DMP_FEATURE_TAP) { + /* Enable tap. */ + tmp[0] = 0xF8; + mpu_write_mem(CFG_20, 1, tmp); + dmp_set_tap_thresh(TAP_XYZ, 250); + dmp_set_tap_axes(TAP_XYZ); + dmp_set_tap_count(1); + dmp_set_tap_time(100); + dmp_set_tap_time_multi(500); + + dmp_set_shake_reject_thresh(GYRO_SF, 200); + dmp_set_shake_reject_time(40); + dmp_set_shake_reject_timeout(10); + } else { + tmp[0] = 0xD8; + mpu_write_mem(CFG_20, 1, tmp); + } + + if (mask & DMP_FEATURE_ANDROID_ORIENT) { + tmp[0] = 0xD9; + } else + tmp[0] = 0xD8; + mpu_write_mem(CFG_ANDROID_ORIENT_INT, 1, tmp); + + if (mask & DMP_FEATURE_LP_QUAT) + dmp_enable_lp_quat(1); + else + dmp_enable_lp_quat(0); + + if (mask & DMP_FEATURE_6X_LP_QUAT) + dmp_enable_6x_lp_quat(1); + else + dmp_enable_6x_lp_quat(0); + + /* Pedometer is always enabled. */ + dmp.feature_mask = mask | DMP_FEATURE_PEDOMETER; + mpu_reset_fifo(); + + dmp.packet_length = 0; + if (mask & DMP_FEATURE_SEND_RAW_ACCEL) + dmp.packet_length += 6; + if (mask & DMP_FEATURE_SEND_ANY_GYRO) + dmp.packet_length += 6; + if (mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) + dmp.packet_length += 16; + if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) + dmp.packet_length += 4; + + return 0; +} + +/** + * @brief Get list of currently enabled DMP features. + * @param[out] Mask of enabled features. + * @return 0 if successful. + */ +int dmp_get_enabled_features(unsigned short *mask) +{ + mask[0] = dmp.feature_mask; + return 0; +} + +/** + * @brief Calibrate the gyro data in the DMP. + * After eight seconds of no motion, the DMP will compute gyro biases and + * subtract them from the quaternion output. If @e dmp_enable_feature is + * called with @e DMP_FEATURE_SEND_CAL_GYRO, the biases will also be + * subtracted from the gyro output. + * @param[in] enable 1 to enable gyro calibration. + * @return 0 if successful. + */ +int dmp_enable_gyro_cal(unsigned char enable) +{ + if (enable) { + unsigned char regs[9] = {0xb8, 0xaa, 0xb3, 0x8d, 0xb4, 0x98, 0x0d, 0x35, 0x5d}; + return mpu_write_mem(CFG_MOTION_BIAS, 9, regs); + } else { + unsigned char regs[9] = {0xb8, 0xaa, 0xaa, 0xaa, 0xb0, 0x88, 0xc3, 0xc5, 0xc7}; + return mpu_write_mem(CFG_MOTION_BIAS, 9, regs); + } +} + +/** + * @brief Generate 3-axis quaternions from the DMP. + * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually + * exclusive. + * @param[in] enable 1 to enable 3-axis quaternion. + * @return 0 if successful. + */ +int dmp_enable_lp_quat(unsigned char enable) +{ + unsigned char regs[4]; + if (enable) { + regs[0] = DINBC0; + regs[1] = DINBC2; + regs[2] = DINBC4; + regs[3] = DINBC6; + } + else + memset(regs, 0x8B, 4); + + mpu_write_mem(CFG_LP_QUAT, 4, regs); + + return mpu_reset_fifo(); +} + +/** + * @brief Generate 6-axis quaternions from the DMP. + * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually + * exclusive. + * @param[in] enable 1 to enable 6-axis quaternion. + * @return 0 if successful. + */ +int dmp_enable_6x_lp_quat(unsigned char enable) +{ + unsigned char regs[4]; + if (enable) { + regs[0] = DINA20; + regs[1] = DINA28; + regs[2] = DINA30; + regs[3] = DINA38; + } else + memset(regs, 0xA3, 4); + + mpu_write_mem(CFG_8, 4, regs); + + return mpu_reset_fifo(); +} + +/** + * @brief Decode the four-byte gesture data and execute any callbacks. + * @param[in] gesture Gesture data from DMP packet. + * @return 0 if successful. + */ +static int decode_gesture(unsigned char *gesture) +{ + unsigned char tap, android_orient; + + android_orient = gesture[3] & 0xC0; + tap = 0x3F & gesture[3]; + + if (gesture[1] & INT_SRC_TAP) { + unsigned char direction, count; + direction = tap >> 3; + count = (tap % 8) + 1; + if (dmp.tap_cb) + dmp.tap_cb(direction, count); + } + + if (gesture[1] & INT_SRC_ANDROID_ORIENT) { + if (dmp.android_orient_cb) + dmp.android_orient_cb(android_orient >> 6); + } + + return 0; +} + +/** + * @brief Specify when a DMP interrupt should occur. + * A DMP interrupt can be configured to trigger on either of the two + * conditions below: + * \n a. One FIFO period has elapsed (set by @e mpu_set_sample_rate). + * \n b. A tap event has been detected. + * @param[in] mode DMP_INT_GESTURE or DMP_INT_CONTINUOUS. + * @return 0 if successful. + */ +int dmp_set_interrupt_mode(unsigned char mode) +{ + const unsigned char regs_continuous[11] = + {0xd8, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9}; + const unsigned char regs_gesture[11] = + {0xda, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0xda, 0xb4, 0xda}; + + switch (mode) { + case DMP_INT_CONTINUOUS: + return mpu_write_mem(CFG_FIFO_ON_EVENT, 11, + (unsigned char*)regs_continuous); + case DMP_INT_GESTURE: + return mpu_write_mem(CFG_FIFO_ON_EVENT, 11, + (unsigned char*)regs_gesture); + default: + return -1; + } +} + +/** + * @brief Get one packet from the FIFO. + * If @e sensors does not contain a particular sensor, disregard the data + * returned to that pointer. + * \n @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * \n INV_WXYZ_QUAT + * \n If the FIFO has no new data, @e sensors will be zero. + * \n If the FIFO is disabled, @e sensors will be zero and this function will + * return a non-zero error code. + * @param[out] gyro Gyro data in hardware units. + * @param[out] accel Accel data in hardware units. + * @param[out] quat 3-axis quaternion data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. + * @param[out] sensors Mask of sensors read from FIFO. + * @param[out] more Number of remaining packets. + * @return 0 if successful. + */ +int dmp_read_fifo(short *gyro, short *accel, long *quat, + unsigned long *timestamp, short *sensors, unsigned char *more) +{ + unsigned char fifo_data[MAX_PACKET_LENGTH]; + unsigned char ii = 0; + + /* TODO: sensors[0] only changes when dmp_enable_feature is called. We can + * cache this value and save some cycles. + */ + sensors[0] = 0; + + /* Get a packet. */ + if (mpu_read_fifo_stream(dmp.packet_length, fifo_data, more)) + return -1; + + /* Parse DMP packet. */ + if (dmp.feature_mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) { +#ifdef FIFO_CORRUPTION_CHECK + long quat_q14[4], quat_mag_sq; +#endif + quat[0] = ((long)fifo_data[0] << 24) | ((long)fifo_data[1] << 16) | + ((long)fifo_data[2] << 8) | fifo_data[3]; + quat[1] = ((long)fifo_data[4] << 24) | ((long)fifo_data[5] << 16) | + ((long)fifo_data[6] << 8) | fifo_data[7]; + quat[2] = ((long)fifo_data[8] << 24) | ((long)fifo_data[9] << 16) | + ((long)fifo_data[10] << 8) | fifo_data[11]; + quat[3] = ((long)fifo_data[12] << 24) | ((long)fifo_data[13] << 16) | + ((long)fifo_data[14] << 8) | fifo_data[15]; + ii += 16; +#ifdef FIFO_CORRUPTION_CHECK + /* We can detect a corrupted FIFO by monitoring the quaternion data and + * ensuring that the magnitude is always normalized to one. This + * shouldn't happen in normal operation, but if an I2C error occurs, + * the FIFO reads might become misaligned. + * + * Let's start by scaling down the quaternion data to avoid long long + * math. + */ + quat_q14[0] = quat[0] >> 16; + quat_q14[1] = quat[1] >> 16; + quat_q14[2] = quat[2] >> 16; + quat_q14[3] = quat[3] >> 16; + quat_mag_sq = quat_q14[0] * quat_q14[0] + quat_q14[1] * quat_q14[1] + + quat_q14[2] * quat_q14[2] + quat_q14[3] * quat_q14[3]; + if ((quat_mag_sq < QUAT_MAG_SQ_MIN) || + (quat_mag_sq > QUAT_MAG_SQ_MAX)) { + /* Quaternion is outside of the acceptable threshold. */ + mpu_reset_fifo(); + sensors[0] = 0; + return -1; + } + sensors[0] |= INV_WXYZ_QUAT; +#endif + } + + if (dmp.feature_mask & DMP_FEATURE_SEND_RAW_ACCEL) { + accel[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1]; + accel[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3]; + accel[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5]; + ii += 6; + sensors[0] |= INV_XYZ_ACCEL; + } + + if (dmp.feature_mask & DMP_FEATURE_SEND_ANY_GYRO) { + gyro[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1]; + gyro[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3]; + gyro[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5]; + ii += 6; + sensors[0] |= INV_XYZ_GYRO; + } + + /* Gesture data is at the end of the DMP packet. Parse it and call + * the gesture callbacks (if registered). + */ + if (dmp.feature_mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) + decode_gesture(fifo_data + ii); + + get_ms(timestamp); + return 0; +} + +/** + * @brief Register a function to be executed on a tap event. + * The tap direction is represented by one of the following: + * \n TAP_X_UP + * \n TAP_X_DOWN + * \n TAP_Y_UP + * \n TAP_Y_DOWN + * \n TAP_Z_UP + * \n TAP_Z_DOWN + * @param[in] func Callback function. + * @return 0 if successful. + */ +int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char)) +{ + dmp.tap_cb = func; + return 0; +} + +/** + * @brief Register a function to be executed on a android orientation event. + * @param[in] func Callback function. + * @return 0 if successful. + */ +int dmp_register_android_orient_cb(void (*func)(unsigned char)) +{ + dmp.android_orient_cb = func; + return 0; +} + +/** + * @} + */ + diff --git a/bsp/boards/mimsy2-cc2538/inv_mpu_dmp_motion_driver.h b/bsp/boards/mimsy2-cc2538/inv_mpu_dmp_motion_driver.h new file mode 100644 index 0000000000..352e9e8e4b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/inv_mpu_dmp_motion_driver.h @@ -0,0 +1,97 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @addtogroup DRIVERS Sensor Driver Layer + * @brief Hardware drivers to communicate with sensors via I2C. + * + * @{ + * @file inv_mpu_dmp_motion_driver.h + * @brief DMP image and interface functions. + * @details All functions are preceded by the dmp_ prefix to + * differentiate among MPL and general driver function calls. + */ +#ifndef _INV_MPU_DMP_MOTION_DRIVER_H_ +#define _INV_MPU_DMP_MOTION_DRIVER_H_ + +#define TAP_X (0x01) +#define TAP_Y (0x02) +#define TAP_Z (0x04) +#define TAP_XYZ (0x07) + +#define TAP_X_UP (0x01) +#define TAP_X_DOWN (0x02) +#define TAP_Y_UP (0x03) +#define TAP_Y_DOWN (0x04) +#define TAP_Z_UP (0x05) +#define TAP_Z_DOWN (0x06) + +#define ANDROID_ORIENT_PORTRAIT (0x00) +#define ANDROID_ORIENT_LANDSCAPE (0x01) +#define ANDROID_ORIENT_REVERSE_PORTRAIT (0x02) +#define ANDROID_ORIENT_REVERSE_LANDSCAPE (0x03) + +#define DMP_INT_GESTURE (0x01) +#define DMP_INT_CONTINUOUS (0x02) + +#define DMP_FEATURE_TAP (0x001) +#define DMP_FEATURE_ANDROID_ORIENT (0x002) +#define DMP_FEATURE_LP_QUAT (0x004) +#define DMP_FEATURE_PEDOMETER (0x008) +#define DMP_FEATURE_6X_LP_QUAT (0x010) +#define DMP_FEATURE_GYRO_CAL (0x020) +#define DMP_FEATURE_SEND_RAW_ACCEL (0x040) +#define DMP_FEATURE_SEND_RAW_GYRO (0x080) +#define DMP_FEATURE_SEND_CAL_GYRO (0x100) + +#define INV_WXYZ_QUAT (0x100) + +/* Set up functions. */ +int dmp_load_motion_driver_firmware(void); +int dmp_set_fifo_rate(unsigned short rate); +int dmp_get_fifo_rate(unsigned short *rate); +int dmp_enable_feature(unsigned short mask); +int dmp_get_enabled_features(unsigned short *mask); +int dmp_set_interrupt_mode(unsigned char mode); +int dmp_set_orientation(unsigned short orient); +int dmp_set_gyro_bias(long *bias); +int dmp_set_accel_bias(long *bias); + +/* Tap functions. */ +int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char)); +int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh); +int dmp_set_tap_axes(unsigned char axis); +int dmp_set_tap_count(unsigned char min_taps); +int dmp_set_tap_time(unsigned short time); +int dmp_set_tap_time_multi(unsigned short time); +int dmp_set_shake_reject_thresh(long sf, unsigned short thresh); +int dmp_set_shake_reject_time(unsigned short time); +int dmp_set_shake_reject_timeout(unsigned short time); + +/* Android orientation functions. */ +int dmp_register_android_orient_cb(void (*func)(unsigned char)); + +/* LP quaternion functions. */ +int dmp_enable_lp_quat(unsigned char enable); +int dmp_enable_6x_lp_quat(unsigned char enable); + +/* Pedometer functions. */ +int dmp_get_pedometer_step_count(unsigned long *count); +int dmp_set_pedometer_step_count(unsigned long count); +int dmp_get_pedometer_walk_time(unsigned long *time); +int dmp_set_pedometer_walk_time(unsigned long time); + +/* DMP gyro calibration functions. */ +int dmp_enable_gyro_cal(unsigned char enable); + +/* Read function. This function should be called whenever the MPU interrupt is + * detected. + */ +int dmp_read_fifo(short *gyro, short *accel, long *quat, + unsigned long *timestamp, short *sensors, unsigned char *more); + +#endif /* #ifndef _INV_MPU_DMP_MOTION_DRIVER_H_ */ + diff --git a/bsp/boards/mimsy2-cc2538/invensense.h b/bsp/boards/mimsy2-cc2538/invensense.h new file mode 100644 index 0000000000..3453ed9615 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/invensense.h @@ -0,0 +1,28 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ + +/** + * Main header file for Invensense's basic library. + */ + +#include "data_builder.h" +#include "hal_outputs.h" +#include "message_layer.h" +#include "mlmath.h" +#include "ml_math_func.h" +#include "mpl.h" +#include "results_holder.h" +#include "start_manager.h" +#include "storage_manager.h" +#include "log.h" +#include "mlinclude.h" +//#include "..\HAL\include\mlos.h" \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/invensense_adv.h b/bsp/boards/mimsy2-cc2538/invensense_adv.h new file mode 100644 index 0000000000..f101cb5c98 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/invensense_adv.h @@ -0,0 +1,27 @@ +/* + $License: + Copyright (C) 2012 InvenSense Corporation, All Rights Reserved. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ + +/* + Main header file for Invensense's Advanced library. +*/ + +#include "accel_auto_cal.h" +#include "compass_vec_cal.h" +#include "fast_no_motion.h" +#include "fusion_9axis.h" +#include "gyro_tc.h" +#include "heading_from_gyro.h" +#include "mag_disturb.h" +#include "motion_no_motion.h" +#include "no_gyro_fusion.h" +#include "quaternion_supervisor.h" +#include "mag_disturb.h" \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/led_mimsy.c b/bsp/boards/mimsy2-cc2538/led_mimsy.c new file mode 100644 index 0000000000..054bab6bb0 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/led_mimsy.c @@ -0,0 +1,61 @@ +//includes +#include "gpio.h" //for gpio driver functions +#include "led_mimsy.h" +#include "hw_memmap.h" //contains GPIO_C_BASE and other hardware mappings + +#define LED_BASE GPIO_C_BASE //memory base for gpio bank c, which has all the leds +void +mimsyLedInit(void) +{ + // + // Set GPIO pins as output low + // + GPIOPinTypeGPIOOutput(LED_BASE, RED_LED | GREEN_LED); + GPIOPinWrite(LED_BASE, RED_LED|GREEN_LED, 0); +} + +void +mimsyLedSet(uint8_t ui8Leds) +{ + // + // Turn on specified LEDs + // + GPIOPinWrite(LED_BASE, ui8Leds, ui8Leds); +} + +/**************************************************************************//** +* @brief This function clears LED(s) specified by \e ui8Leds. +* This function assumes that LED pins have been initialized by, +* for example, bspLedInit(). +* +* @param ui8Leds is an ORed bitmask of LEDs (for example \b BSP_LED_1). +* +* @return None +******************************************************************************/ +void +mimsyLedClear(uint8_t ui8Leds) +{ + // + // Turn off specified LEDs + // + GPIOPinWrite(LED_BASE, ui8Leds, 0); +} + +void +mimsyLedToggle(uint8_t ui8Leds) +{ + // + // Get current pin values of selected bits + // + uint32_t ui32Toggle = GPIOPinRead(LED_BASE, ui8Leds); + + // + // Invert selected bits + // + ui32Toggle = (~ui32Toggle) & ui8Leds; + + // + // Set GPIO + // + GPIOPinWrite(LED_BASE, ui8Leds, ui32Toggle); +} diff --git a/bsp/boards/mimsy2-cc2538/led_mimsy.h b/bsp/boards/mimsy2-cc2538/led_mimsy.h new file mode 100644 index 0000000000..45960782c3 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/led_mimsy.h @@ -0,0 +1,8 @@ +#include "gpio.h" //for gpio driver functions +#define RED_LED GPIO_PIN_4 +#define GREEN_LED GPIO_PIN_7 + +extern void mimsyLedInit(void); +extern void mimsyLedSet(uint8_t ui8Leds); +extern void mimsyLedClear(uint8_t ui8Leds); +extern void mimsyLedToggle(uint8_t ui8Leds); diff --git a/bsp/boards/mimsy2-cc2538/leds.c b/bsp/boards/mimsy2-cc2538/leds.c new file mode 100644 index 0000000000..19dc87520b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/leds.c @@ -0,0 +1,213 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "leds" bsp module. + */ + +#include + +#include +#include + +#include + +#include "board.h" +#include "leds.h" + +//=========================== defines ========================================= + +// Board LED defines +#define BSP_LED_BASE GPIO_C_BASE +#define BSP_LED_1 GPIO_PIN_4 //!< PC4 -- red +#define BSP_LED_2 GPIO_PIN_5 //!< PC5 -- orange +#define BSP_LED_3 GPIO_PIN_6 //!< PC6 -- yellow +#define BSP_LED_4 GPIO_PIN_7 //!< PC7 -- green + +#define BSP_LED_ALL (BSP_LED_1 | \ + BSP_LED_2 | \ + BSP_LED_3 | \ + BSP_LED_4) //!< Bitmask of all LEDs + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +void bspLedSet(uint8_t ui8Leds); +void bspLedClear(uint8_t ui8Leds); +void bspLedToggle(uint8_t ui8Leds); + +//=========================== public ========================================== + +void leds_init() { + GPIOPinTypeGPIOOutput(BSP_LED_BASE, BSP_LED_ALL); + GPIOPinWrite(BSP_LED_BASE, BSP_LED_ALL, 0); +} + +// red +void leds_error_on() { + bspLedSet(BSP_LED_1); +} +void leds_error_off() { + bspLedClear(BSP_LED_1); +} +void leds_error_toggle() { + bspLedToggle(BSP_LED_1); +} +uint8_t leds_error_isOn() { + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_1); + return (uint8_t)(ui32Toggle & BSP_LED_1)>>4; +} + +// orange +void leds_sync_on() { + bspLedSet(BSP_LED_2); +} +void leds_sync_off() { + bspLedClear(BSP_LED_2); +} +void leds_sync_toggle() { + bspLedToggle(BSP_LED_2); +} +uint8_t leds_sync_isOn() { + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_2); + return (uint8_t)(ui32Toggle & BSP_LED_2)>>5; +} + +// green +void leds_radio_on() { + bspLedSet(BSP_LED_4); +} +void leds_radio_off() { + bspLedClear(BSP_LED_4); +} +void leds_radio_toggle() { + bspLedToggle(BSP_LED_4); +} +uint8_t leds_radio_isOn() { + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_4); + return (uint8_t)(ui32Toggle & BSP_LED_4)>>7; +} + +// yellow +void leds_debug_on() { + bspLedSet(BSP_LED_3); +} +void leds_debug_off() { + bspLedClear(BSP_LED_3); +} +void leds_debug_toggle() { + bspLedToggle(BSP_LED_3); +} +uint8_t leds_debug_isOn() { + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_3); + return (uint8_t)(ui32Toggle & BSP_LED_3)>>6; +} + +// all +void leds_all_on() { + bspLedSet(BSP_LED_ALL); +} +void leds_all_off() { + bspLedClear(BSP_LED_ALL); +} +void leds_all_toggle() { + bspLedToggle(BSP_LED_ALL); +} + +void leds_error_blink() { + uint8_t i; + volatile uint16_t delay; + + // turn all LEDs off + bspLedClear(BSP_LED_ALL); + + // blink error LED for ~10s + for (i=0;i<80;i++) { + bspLedToggle(BSP_LED_1); + for (delay=0xffff;delay>0;delay--); + for (delay=0xffff;delay>0;delay--); + } +} + +void leds_circular_shift() { + uint8_t i; + volatile uint16_t delay; + + // turn all LEDs off + bspLedClear(BSP_LED_ALL); + + // incrementally turn LED on + for (i=0;i<10;i++) { + bspLedSet(BSP_LED_1); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_1); + bspLedSet(BSP_LED_2); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_2); + bspLedSet(BSP_LED_3); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_3); + bspLedSet(BSP_LED_4); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_ALL); + } +} + +void leds_increment() { + uint8_t i; + volatile uint16_t delay; + + // turn all LEDs off + bspLedClear(BSP_LED_ALL); + + // incrementally turn LED on + for (i=0;i<10;i++) { + bspLedSet(BSP_LED_1); + for (delay=0xffff;delay>0;delay--); + bspLedSet(BSP_LED_2); + for (delay=0xffff;delay>0;delay--); + bspLedSet(BSP_LED_3); + for (delay=0xffff;delay>0;delay--); + bspLedSet(BSP_LED_4); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_ALL); + } +} + +//=========================== private ========================================= + +port_INLINE void bspLedSet(uint8_t ui8Leds) +{ + // + // Turn on specified LEDs + // + GPIOPinWrite(BSP_LED_BASE, ui8Leds, ui8Leds); +} + +port_INLINE void bspLedClear(uint8_t ui8Leds) +{ + // + // Turn off specified LEDs + // + GPIOPinWrite(BSP_LED_BASE, ui8Leds, 0); +} + +port_INLINE void bspLedToggle(uint8_t ui8Leds) +{ + // + // Get current pin values of selected bits + // + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, ui8Leds); + + // + // Invert selected bits + // + ui32Toggle = (~ui32Toggle) & ui8Leds; + + // + // Set GPIO + // + GPIOPinWrite(BSP_LED_BASE, ui8Leds, ui32Toggle); +} + diff --git a/bsp/boards/mimsy2-cc2538/log.h b/bsp/boards/mimsy2-cc2538/log.h new file mode 100644 index 0000000000..085c58730d --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/log.h @@ -0,0 +1,372 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +/* + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * C/C++ logging functions. See the logging documentation for API details. + * + * We'd like these to be available from C code (in case we import some from + * somewhere), so this has a C interface. + * + * The output will be correct when the log file is shared between multiple + * threads and/or multiple processes so long as the operating system + * supports O_APPEND. These calls have mutex-protected data structures + * and so are NOT reentrant. Do not use MPL_LOG in a signal handler. + */ +#ifndef _LIBS_CUTILS_MPL_LOG_H +#define _LIBS_CUTILS_MPL_LOG_H + +#include +#include + +#ifdef ANDROID +#ifdef NDK_BUILD +#include "log_macros.h" +#else +#include /* For the LOG macro */ +#endif +#endif + +#ifdef __KERNEL__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined ANDROID_JELLYBEAN +#define LOG ALOG +#define LOG_ERRROR ANDROID_LOG_ERROR +#endif + +/* --------------------------------------------------------------------- */ + +/* + * Normally we strip MPL_LOGV (VERBOSE messages) from release builds. + * You can modify this (for example with "#define MPL_LOG_NDEBUG 0" + * at the top of your source file) to change that behavior. + */ +#ifndef MPL_LOG_NDEBUG +#ifdef NDEBUG +#define MPL_LOG_NDEBUG 1 +#else +#define MPL_LOG_NDEBUG 0 +#endif +#endif + +#ifdef __KERNEL__ +#define MPL_LOG_UNKNOWN MPL_LOG_VERBOSE +#define MPL_LOG_DEFAULT KERN_DEFAULT +#define MPL_LOG_VERBOSE KERN_CONT +#define MPL_LOG_DEBUG KERN_NOTICE +#define MPL_LOG_INFO KERN_INFO +#define MPL_LOG_WARN KERN_WARNING +#define MPL_LOG_ERROR KERN_ERR +#define MPL_LOG_SILENT MPL_LOG_VERBOSE + +#else + /* Based off the log priorities in android + /system/core/include/android/log.h */ +#define MPL_LOG_UNKNOWN (0) +#define MPL_LOG_DEFAULT (1) +#define MPL_LOG_VERBOSE (2) +#define MPL_LOG_DEBUG (3) +#define MPL_LOG_INFO (4) +#define MPL_LOG_WARN (5) +#define MPL_LOG_ERROR (6) +#define MPL_LOG_SILENT (8) +#endif + + +/* + * This is the local tag used for the following simplified + * logging macros. You can change this preprocessor definition + * before using the other macros to change the tag. + */ +#ifndef MPL_LOG_TAG +#ifdef __KERNEL__ +#define MPL_LOG_TAG +#else +#define MPL_LOG_TAG NULL +#endif +#endif + +/* --------------------------------------------------------------------- */ + +/* + * Simplified macro to send a verbose log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGV +#if MPL_LOG_NDEBUG +#ifdef _WIN32 +#define MPL_LOGV(fmt, ...) \ + do { \ + __pragma (warning(suppress : 4127 )) \ + if (0) \ + MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__);\ + __pragma (warning(suppress : 4127 )) \ + } while (0) +#else +#define MPL_LOGV(fmt, ...) \ + do { \ + if (0) \ + MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__);\ + } while (0) +#endif + +#else +#define MPL_LOGV(fmt, ...) MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif +#endif + +#ifndef CONDITION +#define CONDITION(cond) ((cond) != 0) +#endif + +#ifndef MPL_LOGV_IF +#if MPL_LOG_NDEBUG +#define MPL_LOGV_IF(cond, fmt, ...) \ + do { if (0) MPL_LOG(fmt, ##__VA_ARGS__); } while (0) +#else +#define MPL_LOGV_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif +#endif + +/* + * Simplified macro to send a debug log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGD +#define MPL_LOGD(fmt, ...) MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif + +#ifndef MPL_LOGD_IF +#define MPL_LOGD_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif + +/* + * Simplified macro to send an info log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGI +#ifdef __KERNEL__ +#define MPL_LOGI(fmt, ...) pr_info(KERN_INFO MPL_LOG_TAG fmt, ##__VA_ARGS__) +#else +#define MPL_LOGI(fmt, ...) MPL_LOG(LOG_INFO, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif +#endif + +#ifndef MPL_LOGI_IF +#define MPL_LOGI_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_INFO, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif + +/* + * Simplified macro to send a warning log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGW +#ifdef __KERNEL__ +#define MPL_LOGW(fmt, ...) printk(KERN_WARNING MPL_LOG_TAG fmt, ##__VA_ARGS__) +#else +#define MPL_LOGW(fmt, ...) MPL_LOG(LOG_WARN, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif +#endif + +#ifndef MPL_LOGW_IF +#define MPL_LOGW_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_WARN, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif + +/* + * Simplified macro to send an error log message using the current MPL_LOG_TAG. + */ +#ifndef MPL_LOGE +#ifdef __KERNEL__ +#define MPL_LOGE(fmt, ...) printk(KERN_ERR MPL_LOG_TAG fmt, ##__VA_ARGS__) +#else +#define MPL_LOGE(fmt, ...) MPL_LOG(LOG_ERROR, MPL_LOG_TAG, fmt, ##__VA_ARGS__) +#endif +#endif + +#ifndef MPL_LOGE_IF +#define MPL_LOGE_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? MPL_LOG(LOG_ERROR, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ + : (void)0) +#endif + +/* --------------------------------------------------------------------- */ + +/* + * Log a fatal error. If the given condition fails, this stops program + * execution like a normal assertion, but also generating the given message. + * It is NOT stripped from release builds. Note that the condition test + * is -inverted- from the normal assert() semantics. + */ +#define MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ...) \ + ((CONDITION(cond)) \ + ? ((void)android_printAssert(#cond, MPL_LOG_TAG, \ + fmt, ##__VA_ARGS__)) \ + : (void)0) + +#define MPL_LOG_ALWAYS_FATAL(fmt, ...) \ + (((void)android_printAssert(NULL, MPL_LOG_TAG, fmt, ##__VA_ARGS__))) + +/* + * Versions of MPL_LOG_ALWAYS_FATAL_IF and MPL_LOG_ALWAYS_FATAL that + * are stripped out of release builds. + */ +#if MPL_LOG_NDEBUG +#define MPL_LOG_FATAL_IF(cond, fmt, ...) \ + do { \ + if (0) \ + MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__); \ + } while (0) +#define MPL_LOG_FATAL(fmt, ...) \ + do { \ + if (0) \ + MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__) \ + } while (0) +#else +#define MPL_LOG_FATAL_IF(cond, fmt, ...) \ + MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__) +#define MPL_LOG_FATAL(fmt, ...) \ + MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__) +#endif + +/* + * Assertion that generates a log message when the assertion fails. + * Stripped out of release builds. Uses the current MPL_LOG_TAG. + */ +#define MPL_LOG_ASSERT(cond, fmt, ...) \ + MPL_LOG_FATAL_IF(!(cond), fmt, ##__VA_ARGS__) + +/* --------------------------------------------------------------------- */ + +/* + * Basic log message macro. + * + * Example: + * MPL_LOG(MPL_LOG_WARN, NULL, "Failed with error %d", errno); + * + * The second argument may be NULL or "" to indicate the "global" tag. + */ +#ifndef MPL_LOG +#ifdef REMOVE_LOGGING +#define MPL_LOG(priority, tag, fmt, ...) do {} while (0) +#else +#define MPL_LOG(priority, tag, fmt, ...) \ + MPL_LOG_PRI(priority, tag, fmt, ##__VA_ARGS__) +#endif +#endif + +/* + * Log macro that allows you to specify a number for the priority. + */ +#ifndef MPL_LOG_PRI +#ifdef ANDROID +#define MPL_LOG_PRI(priority, tag, fmt, ...) \ + LOG(priority, tag, fmt, ##__VA_ARGS__) +#elif defined __KERNEL__ +#define MPL_LOG_PRI(priority, tag, fmt, ...) \ + pr_debug(MPL_##priority tag fmt, ##__VA_ARGS__) +#else +#define MPL_LOG_PRI(priority, tag, fmt, ...) \ + _MLPrintLog(MPL_##priority, tag, fmt, ##__VA_ARGS__) +#endif +#endif + +/* + * Log macro that allows you to pass in a varargs ("args" is a va_list). + */ +#ifndef MPL_LOG_PRI_VA +#ifdef ANDROID +#define MPL_LOG_PRI_VA(priority, tag, fmt, args) \ + android_vprintLog(priority, NULL, tag, fmt, args) +#elif defined __KERNEL__ +/* not allowed in the Kernel because there is no dev_dbg that takes a va_list */ +#else +#define MPL_LOG_PRI_VA(priority, tag, fmt, args) \ + _MLPrintVaLog(priority, NULL, tag, fmt, args) +#endif +#endif + +/* --------------------------------------------------------------------- */ + +/* + * =========================================================================== + * + * The stuff in the rest of this file should not be used directly. + */ + +#ifndef ANDROID +int _MLPrintLog(int priority, const char *tag, const char *fmt, ...); +int _MLPrintVaLog(int priority, const char *tag, const char *fmt, va_list args); +/* Final implementation of actual writing to a character device */ +int _MLWriteLog(const char *buf, int buflen); +#endif + +static inline void __print_result_location(int result, + const char *file, + const char *func, int line) +{ + MPL_LOGE("%s|%s|%d returning %d\n", file, func, line, result); +} + +#ifdef _WIN32 +/* The pragma removes warning about expression being constant */ +#define LOG_RESULT_LOCATION(condition) \ + do { \ + __print_result_location((int)(condition), __FILE__, \ + __func__, __LINE__); \ + __pragma (warning(suppress : 4127 )) \ + } while (0) +#else +#define LOG_RESULT_LOCATION(condition) \ + do { \ + __print_result_location((int)(condition), __FILE__, \ + __func__, __LINE__); \ + } while (0) +#endif + + +#define INV_ERROR_CHECK(r_1329) \ + if (r_1329) { \ + LOG_RESULT_LOCATION(r_1329); \ + return r_1329; \ + } + +#ifdef __cplusplus +} +#endif +#endif /* _LIBS_CUTILS_MPL_LOG_H */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mag_disturb.h b/bsp/boards/mimsy2-cc2538/mag_disturb.h new file mode 100644 index 0000000000..ae64064f1f --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mag_disturb.h @@ -0,0 +1,37 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +#ifndef MLDMP_MAGDISTURB_H__ +#define MLDMP_MAGDISTURB_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + int inv_check_magnetic_disturbance(unsigned long delta_time, const long *quat, + const long *compass, const long *gravity); + + void inv_track_dip_angle(int mode, float currdip); + + inv_error_t inv_enable_magnetic_disturbance(void); + inv_error_t inv_disable_magnetic_disturbance(void); + int inv_get_magnetic_disturbance_state(void); + inv_error_t inv_set_magnetic_disturbance(int time_ms); + inv_error_t inv_disable_dip_tracking(void); + inv_error_t inv_enable_dip_tracking(void); + inv_error_t inv_init_magnetic_disturbance(void); + + float Mag3ofNormalizedLong(const long *x); + +#ifdef __cplusplus +} +#endif + + +#endif // MLDMP_MAGDISTURB_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/math.h b/bsp/boards/mimsy2-cc2538/math.h new file mode 100644 index 0000000000..ebbdac68c6 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/math.h @@ -0,0 +1,691 @@ +#ifndef _MATH_H_ + +#define _MATH_H_ + +#include +#include +#include +#include "_ansi.h" + +_BEGIN_STD_C + +/* __dmath, __fmath, and __ldmath are only here for backwards compatibility + * in case any code used them. They are no longer used by Newlib, itself, + * other than legacy. */ +union __dmath +{ + double d; + __ULong i[2]; +}; + +union __fmath +{ + float f; + __ULong i[1]; +}; + +#if defined(_HAVE_LONG_DOUBLE) +union __ldmath +{ + long double ld; + __ULong i[4]; +}; +#endif + +/* Natural log of 2 */ +#define _M_LN2 0.693147180559945309417 + +#if __GNUC_PREREQ (3, 3) + /* gcc >= 3.3 implicitly defines builtins for HUGE_VALx values. */ + +# ifndef HUGE_VAL +# define HUGE_VAL (__builtin_huge_val()) +# endif + +# ifndef HUGE_VALF +# define HUGE_VALF (__builtin_huge_valf()) +# endif + +# ifndef HUGE_VALL +# define HUGE_VALL (__builtin_huge_vall()) +# endif + +# ifndef INFINITY +# define INFINITY (__builtin_inff()) +# endif + +# ifndef NAN +# define NAN (__builtin_nanf("")) +# endif + +#else /* !gcc >= 3.3 */ + + /* No builtins. Use fixed defines instead. (All 3 HUGE plus the INFINITY + * and NAN macros are required to be constant expressions. Using a variable-- + * even a static const--does not meet this requirement, as it cannot be + * evaluated at translation time.) + * The infinities are done using numbers that are far in excess of + * something that would be expected to be encountered in a floating-point + * implementation. (A more certain way uses values from float.h, but that is + * avoided because system includes are not supposed to include each other.) + * This method might produce warnings from some compilers. (It does in + * newer GCCs, but not for ones that would hit this #else.) If this happens, + * please report details to the Newlib mailing list. */ + + #ifndef HUGE_VAL + #define HUGE_VAL (1.0e999999999) + #endif + + #ifndef HUGE_VALF + #define HUGE_VALF (1.0e999999999F) + #endif + + #if !defined(HUGE_VALL) && defined(_HAVE_LONG_DOUBLE) + #define HUGE_VALL (1.0e999999999L) + #endif + + #if !defined(INFINITY) + #define INFINITY (HUGE_VALF) + #endif + + #if !defined(NAN) + #if defined(__GNUC__) && defined(__cplusplus) + /* Exception: older g++ versions warn about the divide by 0 used in the + * normal case (even though older gccs do not). This trick suppresses the + * warning, but causes errors for plain gcc, so is only used in the one + * special case. */ + static const union { __ULong __i[1]; float __d; } __Nanf = {0x7FC00000}; + #define NAN (__Nanf.__d) + #else + #define NAN (0.0F/0.0F) + #endif + #endif + +#endif /* !gcc >= 3.3 */ + +/* Reentrant ANSI C functions. */ + +#ifndef __math_68881 +extern double atan _PARAMS((double)); +extern double cos _PARAMS((double)); +extern double sin _PARAMS((double)); +extern double tan _PARAMS((double)); +extern double tanh _PARAMS((double)); +extern double frexp _PARAMS((double, int *)); +extern double modf _PARAMS((double, double *)); +extern double ceil _PARAMS((double)); +extern double fabs _PARAMS((double)); +extern double floor _PARAMS((double)); +#endif /* ! defined (__math_68881) */ + +/* Non reentrant ANSI C functions. */ + +#ifndef _REENT_ONLY +#ifndef __math_68881 +extern double acos _PARAMS((double)); +extern double asin _PARAMS((double)); +extern double atan2 _PARAMS((double, double)); +extern double cosh _PARAMS((double)); +extern double sinh _PARAMS((double)); +extern double exp _PARAMS((double)); +extern double ldexp _PARAMS((double, int)); +extern double log _PARAMS((double)); +extern double log10 _PARAMS((double)); +extern double pow _PARAMS((double, double)); +extern double sqrt _PARAMS((double)); +extern double fmod _PARAMS((double, double)); +#endif /* ! defined (__math_68881) */ +#endif /* ! defined (_REENT_ONLY) */ + +#if __MISC_VISIBLE +extern int finite _PARAMS((double)); +extern int finitef _PARAMS((float)); +extern int finitel _PARAMS((long double)); +extern int isinff _PARAMS((float)); +extern int isnanf _PARAMS((float)); +#ifdef __CYGWIN__ /* not implemented in newlib yet */ +extern int isinfl _PARAMS((long double)); +extern int isnanl _PARAMS((long double)); +#endif +#if !defined(__cplusplus) || __cplusplus < 201103L +extern int isinf _PARAMS((double)); +#endif +#endif /* __MISC_VISIBLE */ +#if (__MISC_VISIBLE || (__XSI_VISIBLE && __XSI_VISIBLE < 600)) \ + && (!defined(__cplusplus) || __cplusplus < 201103L) +extern int isnan _PARAMS((double)); +#endif + +#if __ISO_C_VISIBLE >= 1999 +/* ISO C99 types and macros. */ + +/* FIXME: FLT_EVAL_METHOD should somehow be gotten from float.h (which is hard, + * considering that the standard says the includes it defines should not + * include other includes that it defines) and that value used. (This can be + * solved, but autoconf has a bug which makes the solution more difficult, so + * it has been skipped for now.) */ +#if !defined(FLT_EVAL_METHOD) && defined(__FLT_EVAL_METHOD__) + #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ + #define __TMP_FLT_EVAL_METHOD +#endif /* FLT_EVAL_METHOD */ +#if defined FLT_EVAL_METHOD + #if FLT_EVAL_METHOD == 0 + typedef float float_t; + typedef double double_t; + #elif FLT_EVAL_METHOD == 1 + typedef double float_t; + typedef double double_t; + #elif FLT_EVAL_METHOD == 2 + typedef long double float_t; + typedef long double double_t; + #else + /* Implementation-defined. Assume float_t and double_t have been + * defined previously for this configuration (e.g. config.h). */ + #endif +#else + /* Assume basic definitions. */ + typedef float float_t; + typedef double double_t; +#endif +#if defined(__TMP_FLT_EVAL_METHOD) + #undef FLT_EVAL_METHOD +#endif + +#define FP_NAN 0 +#define FP_INFINITE 1 +#define FP_ZERO 2 +#define FP_SUBNORMAL 3 +#define FP_NORMAL 4 + +#ifndef FP_ILOGB0 +# define FP_ILOGB0 (-__INT_MAX__) +#endif +#ifndef FP_ILOGBNAN +# define FP_ILOGBNAN __INT_MAX__ +#endif + +#ifndef MATH_ERRNO +# define MATH_ERRNO 1 +#endif +#ifndef MATH_ERREXCEPT +# define MATH_ERREXCEPT 2 +#endif +#ifndef math_errhandling +# define math_errhandling MATH_ERRNO +#endif + +extern int __isinff (float x); +extern int __isinfd (double x); +extern int __isnanf (float x); +extern int __isnand (double x); +extern int __fpclassifyf (float x); +extern int __fpclassifyd (double x); +extern int __signbitf (float x); +extern int __signbitd (double x); + +/* Note: isinf and isnan were once functions in newlib that took double + * arguments. C99 specifies that these names are reserved for macros + * supporting multiple floating point types. Thus, they are + * now defined as macros. Implementations of the old functions + * taking double arguments still exist for compatibility purposes + * (prototypes for them are earlier in this header). */ + +#if __GNUC_PREREQ (4, 4) + #define fpclassify(__x) (__builtin_fpclassify (FP_NAN, FP_INFINITE, \ + FP_NORMAL, FP_SUBNORMAL, \ + FP_ZERO, __x)) + #ifndef isfinite + #define isfinite(__x) (__builtin_isfinite (__x)) + #endif + #ifndef isinf + #define isinf(__x) (__builtin_isinf_sign (__x)) + #endif + #ifndef isnan + #define isnan(__x) (__builtin_isnan (__x)) + #endif + #define isnormal(__x) (__builtin_isnormal (__x)) +#else + #define fpclassify(__x) \ + ((sizeof(__x) == sizeof(float)) ? __fpclassifyf(__x) : \ + __fpclassifyd(__x)) + #ifndef isfinite + #define isfinite(__y) \ + (__extension__ ({int __cy = fpclassify(__y); \ + __cy != FP_INFINITE && __cy != FP_NAN;})) + #endif + #ifndef isinf + #define isinf(__x) (fpclassify(__x) == FP_INFINITE) + #endif + #ifndef isnan + #define isnan(__x) (fpclassify(__x) == FP_NAN) + #endif + #define isnormal(__x) (fpclassify(__x) == FP_NORMAL) +#endif + +#if __GNUC_PREREQ (4, 0) + #if defined(_HAVE_LONG_DOUBLE) + #define signbit(__x) \ + ((sizeof(__x) == sizeof(float)) ? __builtin_signbitf(__x) : \ + (sizeof(__x) == sizeof(double)) ? __builtin_signbit (__x) : \ + __builtin_signbitl(__x)) + #else + #define signbit(__x) \ + ((sizeof(__x) == sizeof(float)) ? __builtin_signbitf(__x) : \ + __builtin_signbit (__x)) + #endif +#else + #define signbit(__x) \ + ((sizeof(__x) == sizeof(float)) ? __signbitf(__x) : \ + __signbitd(__x)) +#endif + +#if __GNUC_PREREQ (2, 97) +#define isgreater(__x,__y) (__builtin_isgreater (__x, __y)) +#define isgreaterequal(__x,__y) (__builtin_isgreaterequal (__x, __y)) +#define isless(__x,__y) (__builtin_isless (__x, __y)) +#define islessequal(__x,__y) (__builtin_islessequal (__x, __y)) +#define islessgreater(__x,__y) (__builtin_islessgreater (__x, __y)) +#define isunordered(__x,__y) (__builtin_isunordered (__x, __y)) +#else +#define isgreater(x,y) \ + (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + !isunordered(__x,__y) && (__x > __y);})) +#define isgreaterequal(x,y) \ + (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + !isunordered(__x,__y) && (__x >= __y);})) +#define isless(x,y) \ + (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + !isunordered(__x,__y) && (__x < __y);})) +#define islessequal(x,y) \ + (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + !isunordered(__x,__y) && (__x <= __y);})) +#define islessgreater(x,y) \ + (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + !isunordered(__x,__y) && (__x < __y || __x > __y);})) + +#define isunordered(a,b) \ + (__extension__ ({__typeof__(a) __a = (a); __typeof__(b) __b = (b); \ + fpclassify(__a) == FP_NAN || fpclassify(__b) == FP_NAN;})) +#endif + +/* Non ANSI double precision functions. */ + +extern double infinity _PARAMS((void)); +extern double nan _PARAMS((const char *)); +extern double copysign _PARAMS((double, double)); +extern double logb _PARAMS((double)); +extern int ilogb _PARAMS((double)); + +extern double asinh _PARAMS((double)); +extern double cbrt _PARAMS((double)); +extern double nextafter _PARAMS((double, double)); +extern double rint _PARAMS((double)); +extern double scalbn _PARAMS((double, int)); + +extern double exp2 _PARAMS((double)); +extern double scalbln _PARAMS((double, long int)); +extern double tgamma _PARAMS((double)); +extern double nearbyint _PARAMS((double)); +extern long int lrint _PARAMS((double)); +extern long long int llrint _PARAMS((double)); +extern double round _PARAMS((double)); +extern long int lround _PARAMS((double)); +extern long long int llround _PARAMS((double)); +extern double trunc _PARAMS((double)); +extern double remquo _PARAMS((double, double, int *)); +extern double fdim _PARAMS((double, double)); +extern double fmax _PARAMS((double, double)); +extern double fmin _PARAMS((double, double)); +extern double fma _PARAMS((double, double, double)); + +#ifndef __math_68881 +extern double log1p _PARAMS((double)); +extern double expm1 _PARAMS((double)); +#endif /* ! defined (__math_68881) */ + +#ifndef _REENT_ONLY +extern double acosh _PARAMS((double)); +extern double atanh _PARAMS((double)); +extern double remainder _PARAMS((double, double)); +extern double gamma _PARAMS((double)); +extern double lgamma _PARAMS((double)); +extern double erf _PARAMS((double)); +extern double erfc _PARAMS((double)); +extern double log2 _PARAMS((double)); +#if !defined(__cplusplus) +#define log2(x) (log (x) / _M_LN2) +#endif + +#ifndef __math_68881 +extern double hypot _PARAMS((double, double)); +#endif + +#endif /* ! defined (_REENT_ONLY) */ + +/* Single precision versions of ANSI functions. */ + +extern float atanf _PARAMS((float)); +extern float cosf _PARAMS((float)); +extern float sinf _PARAMS((float)); +extern float tanf _PARAMS((float)); +extern float tanhf _PARAMS((float)); +extern float frexpf _PARAMS((float, int *)); +extern float modff _PARAMS((float, float *)); +extern float ceilf _PARAMS((float)); +extern float fabsf _PARAMS((float)); +extern float floorf _PARAMS((float)); + +#ifndef _REENT_ONLY +extern float acosf _PARAMS((float)); +extern float asinf _PARAMS((float)); +extern float atan2f _PARAMS((float, float)); +extern float coshf _PARAMS((float)); +extern float sinhf _PARAMS((float)); +extern float expf _PARAMS((float)); +extern float ldexpf _PARAMS((float, int)); +extern float logf _PARAMS((float)); +extern float log10f _PARAMS((float)); +extern float powf _PARAMS((float, float)); +extern float sqrtf _PARAMS((float)); +extern float fmodf _PARAMS((float, float)); +#endif /* ! defined (_REENT_ONLY) */ + +/* Other single precision functions. */ + +extern float exp2f _PARAMS((float)); +extern float scalblnf _PARAMS((float, long int)); +extern float tgammaf _PARAMS((float)); +extern float nearbyintf _PARAMS((float)); +extern long int lrintf _PARAMS((float)); +extern long long int llrintf _PARAMS((float)); +extern float roundf _PARAMS((float)); +extern long int lroundf _PARAMS((float)); +extern long long int llroundf _PARAMS((float)); +extern float truncf _PARAMS((float)); +extern float remquof _PARAMS((float, float, int *)); +extern float fdimf _PARAMS((float, float)); +extern float fmaxf _PARAMS((float, float)); +extern float fminf _PARAMS((float, float)); +extern float fmaf _PARAMS((float, float, float)); + +extern float infinityf _PARAMS((void)); +extern float nanf _PARAMS((const char *)); +extern float copysignf _PARAMS((float, float)); +extern float logbf _PARAMS((float)); +extern int ilogbf _PARAMS((float)); + +extern float asinhf _PARAMS((float)); +extern float cbrtf _PARAMS((float)); +extern float nextafterf _PARAMS((float, float)); +extern float rintf _PARAMS((float)); +extern float scalbnf _PARAMS((float, int)); +extern float log1pf _PARAMS((float)); +extern float expm1f _PARAMS((float)); + +#ifndef _REENT_ONLY +extern float acoshf _PARAMS((float)); +extern float atanhf _PARAMS((float)); +extern float remainderf _PARAMS((float, float)); +extern float gammaf _PARAMS((float)); +extern float lgammaf _PARAMS((float)); +extern float erff _PARAMS((float)); +extern float erfcf _PARAMS((float)); +extern float log2f _PARAMS((float)); +extern float hypotf _PARAMS((float, float)); +#endif /* ! defined (_REENT_ONLY) */ + +/* Newlib doesn't fully support long double math functions so far. + On platforms where long double equals double the long double functions + simply call the double functions. On Cygwin the long double functions + are implemented independently from newlib to be able to use optimized + assembler functions despite using the Microsoft x86_64 ABI. */ +#if defined (_LDBL_EQ_DBL) || defined (__CYGWIN__) +/* Reentrant ANSI C functions. */ +#ifndef __math_68881 +extern long double atanl _PARAMS((long double)); +extern long double cosl _PARAMS((long double)); +extern long double sinl _PARAMS((long double)); +extern long double tanl _PARAMS((long double)); +extern long double tanhl _PARAMS((long double)); +extern long double frexpl _PARAMS((long double, int *)); +extern long double modfl _PARAMS((long double, long double *)); +extern long double ceill _PARAMS((long double)); +extern long double fabsl _PARAMS((long double)); +extern long double floorl _PARAMS((long double)); +extern long double log1pl _PARAMS((long double)); +extern long double expm1l _PARAMS((long double)); +#endif /* ! defined (__math_68881) */ +/* Non reentrant ANSI C functions. */ +#ifndef _REENT_ONLY +#ifndef __math_68881 +extern long double acosl _PARAMS((long double)); +extern long double asinl _PARAMS((long double)); +extern long double atan2l _PARAMS((long double, long double)); +extern long double coshl _PARAMS((long double)); +extern long double sinhl _PARAMS((long double)); +extern long double expl _PARAMS((long double)); +extern long double ldexpl _PARAMS((long double, int)); +extern long double logl _PARAMS((long double)); +extern long double log10l _PARAMS((long double)); +extern long double powl _PARAMS((long double, long double)); +extern long double sqrtl _PARAMS((long double)); +extern long double fmodl _PARAMS((long double, long double)); +extern long double hypotl _PARAMS((long double, long double)); +#endif /* ! defined (__math_68881) */ +#endif /* ! defined (_REENT_ONLY) */ +extern long double copysignl _PARAMS((long double, long double)); +extern long double nanl _PARAMS((const char *)); +extern int ilogbl _PARAMS((long double)); +extern long double asinhl _PARAMS((long double)); +extern long double cbrtl _PARAMS((long double)); +extern long double nextafterl _PARAMS((long double, long double)); +extern float nexttowardf _PARAMS((float, long double)); +extern double nexttoward _PARAMS((double, long double)); +extern long double nexttowardl _PARAMS((long double, long double)); +extern long double logbl _PARAMS((long double)); +extern long double log2l _PARAMS((long double)); +extern long double rintl _PARAMS((long double)); +extern long double scalbnl _PARAMS((long double, int)); +extern long double exp2l _PARAMS((long double)); +extern long double scalblnl _PARAMS((long double, long)); +extern long double tgammal _PARAMS((long double)); +extern long double nearbyintl _PARAMS((long double)); +extern long int lrintl _PARAMS((long double)); +extern long long int llrintl _PARAMS((long double)); +extern long double roundl _PARAMS((long double)); +extern long lroundl _PARAMS((long double)); +extern long long int llroundl _PARAMS((long double)); +extern long double truncl _PARAMS((long double)); +extern long double remquol _PARAMS((long double, long double, int *)); +extern long double fdiml _PARAMS((long double, long double)); +extern long double fmaxl _PARAMS((long double, long double)); +extern long double fminl _PARAMS((long double, long double)); +extern long double fmal _PARAMS((long double, long double, long double)); +#ifndef _REENT_ONLY +extern long double acoshl _PARAMS((long double)); +extern long double atanhl _PARAMS((long double)); +extern long double remainderl _PARAMS((long double, long double)); +extern long double lgammal _PARAMS((long double)); +extern long double erfl _PARAMS((long double)); +extern long double erfcl _PARAMS((long double)); +#endif /* ! defined (_REENT_ONLY) */ +#else /* !_LDBL_EQ_DBL && !__CYGWIN__ */ +extern long double hypotl _PARAMS((long double, long double)); +extern long double sqrtl _PARAMS((long double)); +#ifdef __i386__ +/* Other long double precision functions. */ +extern _LONG_DOUBLE rintl _PARAMS((_LONG_DOUBLE)); +extern long int lrintl _PARAMS((_LONG_DOUBLE)); +extern long long int llrintl _PARAMS((_LONG_DOUBLE)); +#endif /* __i386__ */ +#endif /* !_LDBL_EQ_DBL && !__CYGWIN__ */ + +#endif /* __ISO_C_VISIBLE >= 1999 */ + +#if __MISC_VISIBLE +extern double drem _PARAMS((double, double)); +extern float dremf _PARAMS((float, float)); +#ifdef __CYGWIN__ +extern float dreml _PARAMS((long double, long double)); +#endif /* __CYGWIN__ */ +extern double gamma_r _PARAMS((double, int *)); +extern double lgamma_r _PARAMS((double, int *)); +extern float gammaf_r _PARAMS((float, int *)); +extern float lgammaf_r _PARAMS((float, int *)); +#endif + +#if __MISC_VISIBLE || __XSI_VISIBLE +extern double y0 _PARAMS((double)); +extern double y1 _PARAMS((double)); +extern double yn _PARAMS((int, double)); +extern double j0 _PARAMS((double)); +extern double j1 _PARAMS((double)); +extern double jn _PARAMS((int, double)); +#endif + +#if __MISC_VISIBLE || __XSI_VISIBLE >= 600 +extern float y0f _PARAMS((float)); +extern float y1f _PARAMS((float)); +extern float ynf _PARAMS((int, float)); +extern float j0f _PARAMS((float)); +extern float j1f _PARAMS((float)); +extern float jnf _PARAMS((int, float)); +#endif + +/* GNU extensions */ +#if __GNU_VISIBLE +extern void sincos _PARAMS((double, double *, double *)); +extern void sincosf _PARAMS((float, float *, float *)); +#ifdef __CYGWIN__ +extern void sincosl _PARAMS((long double, long double *, long double *)); +#endif /* __CYGWIN__ */ +# ifndef exp10 +extern double exp10 _PARAMS((double)); +# endif +# ifndef pow10 +extern double pow10 _PARAMS((double)); +# endif +# ifndef exp10f +extern float exp10f _PARAMS((float)); +# endif +# ifndef pow10f +extern float pow10f _PARAMS((float)); +# endif +#ifdef __CYGWIN__ +# ifndef exp10l +extern float exp10l _PARAMS((float)); +# endif +# ifndef pow10l +extern float pow10l _PARAMS((float)); +# endif +#endif /* __CYGWIN__ */ +#endif /* __GNU_VISIBLE */ + +#if __MISC_VISIBLE || __XSI_VISIBLE +/* The gamma functions use a global variable, signgam. */ +#ifndef _REENT_ONLY +#define signgam (*__signgam()) +extern int *__signgam _PARAMS((void)); +#endif /* ! defined (_REENT_ONLY) */ + +#define __signgam_r(ptr) _REENT_SIGNGAM(ptr) +#endif /* __MISC_VISIBLE || __XSI_VISIBLE */ + +#if __SVID_VISIBLE +/* The exception structure passed to the matherr routine. */ +/* We have a problem when using C++ since `exception' is a reserved + name in C++. */ +#ifdef __cplusplus +struct __exception +#else +struct exception +#endif +{ + int type; + char *name; + double arg1; + double arg2; + double retval; + int err; +}; + +#ifdef __cplusplus +extern int matherr _PARAMS((struct __exception *e)); +#else +extern int matherr _PARAMS((struct exception *e)); +#endif + +/* Values for the type field of struct exception. */ + +#define DOMAIN 1 +#define SING 2 +#define OVERFLOW 3 +#define UNDERFLOW 4 +#define TLOSS 5 +#define PLOSS 6 + +#endif /* __SVID_VISIBLE */ + +/* Useful constants. */ + +#if __BSD_VISIBLE || __XSI_VISIBLE + +#define MAXFLOAT 3.40282347e+38F + +#define M_E 2.7182818284590452354 +#define M_LOG2E 1.4426950408889634074 +#define M_LOG10E 0.43429448190325182765 +#define M_LN2 _M_LN2 +#define M_LN10 2.30258509299404568402 +#define M_PI 3.14159265358979323846 +#define M_PI_2 1.57079632679489661923 +#define M_PI_4 0.78539816339744830962 +#define M_1_PI 0.31830988618379067154 +#define M_2_PI 0.63661977236758134308 +#define M_2_SQRTPI 1.12837916709551257390 +#define M_SQRT2 1.41421356237309504880 +#define M_SQRT1_2 0.70710678118654752440 + +#endif + +#if __BSD_VISIBLE + +#define M_TWOPI (M_PI * 2.0) +#define M_3PI_4 2.3561944901923448370E0 +#define M_SQRTPI 1.77245385090551602792981 +#define M_LN2LO 1.9082149292705877000E-10 +#define M_LN2HI 6.9314718036912381649E-1 +#define M_SQRT3 1.73205080756887719000 +#define M_IVLN10 0.43429448190325182765 /* 1 / log(10) */ +#define M_LOG2_E _M_LN2 +#define M_INVLN2 1.4426950408889633870E0 /* 1 / log(2) */ + +/* Global control over fdlibm error handling. */ + +enum __fdlibm_version +{ + __fdlibm_ieee = -1, + __fdlibm_svid, + __fdlibm_xopen, + __fdlibm_posix +}; + +#define _LIB_VERSION_TYPE enum __fdlibm_version +#define _LIB_VERSION __fdlib_version + +extern __IMPORT _LIB_VERSION_TYPE _LIB_VERSION; + +#define _IEEE_ __fdlibm_ieee +#define _SVID_ __fdlibm_svid +#define _XOPEN_ __fdlibm_xopen +#define _POSIX_ __fdlibm_posix + +#endif /* __BSD_VISIBLE */ + +_END_STD_C + +#ifdef __FAST_MATH__ +#include +#endif + +#endif /* _MATH_H_ */ diff --git a/bsp/boards/mimsy2-cc2538/message_layer.c b/bsp/boards/mimsy2-cc2538/message_layer.c new file mode 100644 index 0000000000..d266d80ff7 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/message_layer.c @@ -0,0 +1,59 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @defgroup Message_Layer message_layer + * @brief Motion Library - Message Layer + * Holds Low Occurance messages + * + * @{ + * @file message_layer.c + * @brief Holds Low Occurance Messages. + */ +#include "message_layer.h" +#include "log.h" + +struct message_holder_t { + long message; +}; + +static struct message_holder_t mh; + +/** Sets a message. +* @param[in] set The flags to set. +* @param[in] clear Before setting anything this will clear these messages, +* which is useful for mutually exclusive messages such +* a motion or no motion message. +* @param[in] level Level of the messages. It starts at 0, and may increase +* in the future to allow more messages if the bit storage runs out. +*/ +void inv_set_message(long set, long clear, int level) +{ + if (level == 0) { + mh.message &= ~clear; + mh.message |= set; + } +} + +/** Returns Message Flags for Level 0 Messages. +* Levels are to allow expansion of more messages in the future. +* @param[in] clear If set, will clear the message. Typically this will be set +* for one reader, so that you don't get the same message over and over. +* @return bit field to corresponding message. +*/ +long inv_get_message_level_0(int clear) +{ + long msg; + msg = mh.message; + if (clear) { + mh.message = 0; + } + return msg; +} + +/** + * @} + */ diff --git a/bsp/boards/mimsy2-cc2538/message_layer.h b/bsp/boards/mimsy2-cc2538/message_layer.h new file mode 100644 index 0000000000..e6d90d5357 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/message_layer.h @@ -0,0 +1,35 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INV_MESSAGE_LAYER_H__ +#define INV_MESSAGE_LAYER_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* Level 0 Type Messages */ + /** A motion event has occured */ +#define INV_MSG_MOTION_EVENT (0x01) + /** A no motion event has occured */ +#define INV_MSG_NO_MOTION_EVENT (0x02) + /** A setting of the gyro bias has occured */ +#define INV_MSG_NEW_GB_EVENT (0x04) + /** A setting of the compass bias has occured */ +#define INV_MSG_NEW_CB_EVENT (0x08) + /** A setting of the accel bias has occured */ +#define INV_MSG_NEW_AB_EVENT (0x10) + + void inv_set_message(long set, long clear, int level); + long inv_get_message_level_0(int clear); + +#ifdef __cplusplus +} +#endif + +#endif // INV_MESSAGE_LAYER_H__ diff --git a/bsp/boards/mimsy2-cc2538/ml_math_func.c b/bsp/boards/mimsy2-cc2538/ml_math_func.c new file mode 100644 index 0000000000..cfea1b18d9 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/ml_math_func.c @@ -0,0 +1,781 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ + +/** + * @defgroup ML_MATH_FUNC ml_math_func + * @brief Motion Library - Math Functions + * Common math functions the Motion Library + * + * @{ + * @file ml_math_func.c + * @brief Math Functions. + */ + +#include "mlmath.h" +#include "ml_math_func.h" +#include "mlinclude.h" +#include +#include "math.h" + +#ifdef EMPL +#define TABLE_SIZE (256) + +/* TODO: If memory becomes a big issue, we can just store the data for a single + * quadrant and transform the inputs and outputs of the lookup functions. + */ +const float sin_lookup[TABLE_SIZE] = { + 0.000000f, 0.024541f, 0.049068f, 0.073565f, 0.098017f, 0.122411f, 0.146730f, 0.170962f, + 0.195090f, 0.219101f, 0.242980f, 0.266713f, 0.290285f, 0.313682f, 0.336890f, 0.359895f, + 0.382683f, 0.405241f, 0.427555f, 0.449611f, 0.471397f, 0.492898f, 0.514103f, 0.534998f, + 0.555570f, 0.575808f, 0.595699f, 0.615232f, 0.634393f, 0.653173f, 0.671559f, 0.689541f, + 0.707107f, 0.724247f, 0.740951f, 0.757209f, 0.773010f, 0.788346f, 0.803208f, 0.817585f, + 0.831470f, 0.844854f, 0.857729f, 0.870087f, 0.881921f, 0.893224f, 0.903989f, 0.914210f, + 0.923880f, 0.932993f, 0.941544f, 0.949528f, 0.956940f, 0.963776f, 0.970031f, 0.975702f, + 0.980785f, 0.985278f, 0.989177f, 0.992480f, 0.995185f, 0.997290f, 0.998795f, 0.999699f, + 1.000000f, 0.999699f, 0.998795f, 0.997290f, 0.995185f, 0.992480f, 0.989177f, 0.985278f, + 0.980785f, 0.975702f, 0.970031f, 0.963776f, 0.956940f, 0.949528f, 0.941544f, 0.932993f, + 0.923880f, 0.914210f, 0.903989f, 0.893224f, 0.881921f, 0.870087f, 0.857729f, 0.844854f, + 0.831470f, 0.817585f, 0.803208f, 0.788346f, 0.773010f, 0.757209f, 0.740951f, 0.724247f, + 0.707107f, 0.689541f, 0.671559f, 0.653173f, 0.634393f, 0.615232f, 0.595699f, 0.575808f, + 0.555570f, 0.534998f, 0.514103f, 0.492898f, 0.471397f, 0.449611f, 0.427555f, 0.405241f, + 0.382683f, 0.359895f, 0.336890f, 0.313682f, 0.290285f, 0.266713f, 0.242980f, 0.219101f, + 0.195091f, 0.170962f, 0.146731f, 0.122411f, 0.098017f, 0.073565f, 0.049068f, 0.024541f, + 0.000000f, -0.024541f, -0.049067f, -0.073564f, -0.098017f, -0.122411f, -0.146730f, -0.170962f, + -0.195090f, -0.219101f, -0.242980f, -0.266713f, -0.290284f, -0.313682f, -0.336890f, -0.359895f, + -0.382683f, -0.405241f, -0.427555f, -0.449611f, -0.471397f, -0.492898f, -0.514103f, -0.534997f, + -0.555570f, -0.575808f, -0.595699f, -0.615231f, -0.634393f, -0.653173f, -0.671559f, -0.689540f, + -0.707107f, -0.724247f, -0.740951f, -0.757209f, -0.773010f, -0.788346f, -0.803207f, -0.817585f, + -0.831469f, -0.844853f, -0.857729f, -0.870087f, -0.881921f, -0.893224f, -0.903989f, -0.914210f, + -0.923880f, -0.932993f, -0.941544f, -0.949528f, -0.956940f, -0.963776f, -0.970031f, -0.975702f, + -0.980785f, -0.985278f, -0.989176f, -0.992480f, -0.995185f, -0.997290f, -0.998795f, -0.999699f, + -1.000000f, -0.999699f, -0.998795f, -0.997290f, -0.995185f, -0.992480f, -0.989177f, -0.985278f, + -0.980785f, -0.975702f, -0.970031f, -0.963776f, -0.956940f, -0.949528f, -0.941544f, -0.932993f, + -0.923880f, -0.914210f, -0.903989f, -0.893224f, -0.881921f, -0.870087f, -0.857729f, -0.844854f, + -0.831470f, -0.817585f, -0.803208f, -0.788347f, -0.773011f, -0.757209f, -0.740951f, -0.724247f, + -0.707107f, -0.689541f, -0.671559f, -0.653173f, -0.634394f, -0.615232f, -0.595699f, -0.575808f, + -0.555570f, -0.534998f, -0.514103f, -0.492898f, -0.471397f, -0.449612f, -0.427555f, -0.405241f, + -0.382684f, -0.359895f, -0.336890f, -0.313682f, -0.290285f, -0.266713f, -0.242981f, -0.219102f, + -0.195091f, -0.170962f, -0.146731f, -0.122411f, -0.098017f, -0.073565f, -0.049068f, -0.024542f +}; + +float inv_sinf(float x) +{ + int index = (unsigned int)((x * (TABLE_SIZE>>1)) / 3.14159f) % TABLE_SIZE; + return sin_lookup[index]; +} + +float inv_cosf(float x) +{ + int index = ((unsigned int)((x * (TABLE_SIZE>>1)) / 3.14159f) + (TABLE_SIZE>>2)) % TABLE_SIZE; + return sin_lookup[index]; +} +#endif + +/** @internal + * Does the cross product of compass by gravity, then converts that + * to the world frame using the quaternion, then computes the angle that + * is made. + * + * @param[in] compass Compass Vector (Body Frame), length 3 + * @param[in] grav Gravity Vector (Body Frame), length 3 + * @param[in] quat Quaternion, Length 4 + * @return Angle Cross Product makes after quaternion rotation. + */ +float inv_compass_angle(const long *compass, const long *grav, const long *quat) +{ + long cgcross[4], q1[4], q2[4], qi[4]; + float angW; + + // Compass cross Gravity + cgcross[0] = 0L; + cgcross[1] = inv_q30_mult(compass[1], grav[2]) - inv_q30_mult(compass[2], grav[1]); + cgcross[2] = inv_q30_mult(compass[2], grav[0]) - inv_q30_mult(compass[0], grav[2]); + cgcross[3] = inv_q30_mult(compass[0], grav[1]) - inv_q30_mult(compass[1], grav[0]); + + // Now convert cross product into world frame + inv_q_mult(quat, cgcross, q1); + inv_q_invert(quat, qi); + inv_q_mult(q1, qi, q2); + + // Protect against atan2 of 0,0 + if ((q2[2] == 0L) && (q2[1] == 0L)) + return 0.f; + + // This is the unfiltered heading correction + angW = -atan2f(inv_q30_to_float(q2[2]), inv_q30_to_float(q2[1])); + return angW; +} + +/** + * @brief The gyro data magnitude squared : + * (1 degree per second)^2 = 2^6 = 2^GYRO_MAG_SQR_SHIFT. + * @param[in] gyro Gyro data scaled with 1 dps = 2^16 + * @return the computed magnitude squared output of the gyroscope. + */ +unsigned long inv_get_gyro_sum_of_sqr(const long *gyro) +{ + unsigned long gmag = 0; + long temp; + int kk; + + for (kk = 0; kk < 3; ++kk) { + temp = gyro[kk] >> (16 - (GYRO_MAG_SQR_SHIFT / 2)); + gmag += temp * temp; + } + + return gmag; +} + +/** Performs a multiply and shift by 29. These are good functions to write in assembly on + * with devices with small memory where you want to get rid of the long long which some + * assemblers don't handle well + * @param[in] a + * @param[in] b + * @return ((long long)a*b)>>29 +*/ +long inv_q29_mult(long a, long b) +{ +#ifdef EMPL_NO_64BIT + long result; + result = (long)((float)a * b / (1L << 29)); + return result; +#else + long long temp; + long result; + temp = (long long)a * b; + result = (long)(temp >> 29); + return result; +#endif +} + +/** Performs a multiply and shift by 30. These are good functions to write in assembly on + * with devices with small memory where you want to get rid of the long long which some + * assemblers don't handle well + * @param[in] a + * @param[in] b + * @return ((long long)a*b)>>30 +*/ +long inv_q30_mult(long a, long b) +{ +#ifdef EMPL_NO_64BIT + long result; + result = (long)((float)a * b / (1L << 30)); + return result; +#else + long long temp; + long result; + temp = (long long)a * b; + result = (long)(temp >> 30); + return result; +#endif +} + +#ifndef EMPL_NO_64BIT +long inv_q30_div(long a, long b) +{ + long long temp; + long result; + temp = (((long long)a) << 30) / b; + result = (long)temp; + return result; +} +#endif + +/** Performs a multiply and shift by shift. These are good functions to write + * in assembly on with devices with small memory where you want to get rid of + * the long long which some assemblers don't handle well + * @param[in] a First multicand + * @param[in] b Second multicand + * @param[in] shift Shift amount after multiplying + * @return ((long long)a*b)<> shift); + return result; +} +#endif + +/** Performs a fixed point quaternion multiply. +* @param[in] q1 First Quaternion Multicand, length 4. 1.0 scaled +* to 2^30 +* @param[in] q2 Second Quaternion Multicand, length 4. 1.0 scaled +* to 2^30 +* @param[out] qProd Product after quaternion multiply. Length 4. +* 1.0 scaled to 2^30. +*/ +void inv_q_mult(const long *q1, const long *q2, long *qProd) +{ + INVENSENSE_FUNC_START; + qProd[0] = inv_q30_mult(q1[0], q2[0]) - inv_q30_mult(q1[1], q2[1]) - + inv_q30_mult(q1[2], q2[2]) - inv_q30_mult(q1[3], q2[3]); + + qProd[1] = inv_q30_mult(q1[0], q2[1]) + inv_q30_mult(q1[1], q2[0]) + + inv_q30_mult(q1[2], q2[3]) - inv_q30_mult(q1[3], q2[2]); + + qProd[2] = inv_q30_mult(q1[0], q2[2]) - inv_q30_mult(q1[1], q2[3]) + + inv_q30_mult(q1[2], q2[0]) + inv_q30_mult(q1[3], q2[1]); + + qProd[3] = inv_q30_mult(q1[0], q2[3]) + inv_q30_mult(q1[1], q2[2]) - + inv_q30_mult(q1[2], q2[1]) + inv_q30_mult(q1[3], q2[0]); +} + +/** Performs a fixed point quaternion addition. +* @param[in] q1 First Quaternion term, length 4. 1.0 scaled +* to 2^30 +* @param[in] q2 Second Quaternion term, length 4. 1.0 scaled +* to 2^30 +* @param[out] qSum Sum after quaternion summation. Length 4. +* 1.0 scaled to 2^30. +*/ +void inv_q_add(long *q1, long *q2, long *qSum) +{ + INVENSENSE_FUNC_START; + qSum[0] = q1[0] + q2[0]; + qSum[1] = q1[1] + q2[1]; + qSum[2] = q1[2] + q2[2]; + qSum[3] = q1[3] + q2[3]; +} + +void inv_vector_normalize(long *vec, int length) +{ + INVENSENSE_FUNC_START; + double normSF = 0; + int ii; + for (ii = 0; ii < length; ii++) { + normSF += + inv_q30_to_double(vec[ii]) * inv_q30_to_double(vec[ii]); + } + if (normSF > 0) { + normSF = 1 / sqrt(normSF); + for (ii = 0; ii < length; ii++) { + vec[ii] = (int)((double)vec[ii] * normSF); + } + } else { + vec[0] = 1073741824L; + for (ii = 1; ii < length; ii++) { + vec[ii] = 0; + } + } +} + +void inv_q_normalize(long *q) +{ + INVENSENSE_FUNC_START; + inv_vector_normalize(q, 4); +} + +void inv_q_invert(const long *q, long *qInverted) +{ + INVENSENSE_FUNC_START; + qInverted[0] = q[0]; + qInverted[1] = -q[1]; + qInverted[2] = -q[2]; + qInverted[3] = -q[3]; +} + +double quaternion_to_rotation_angle(const long *quat) { + double quat0 = (double )quat[0] / 1073741824; + if (quat0 > 1.0f) { + quat0 = 1.0; + } else if (quat0 < -1.0f) { + quat0 = -1.0; + } + + return acos(quat0)*2*180/M_PI; +} + +/** Rotates a 3-element vector by Rotation defined by Q +*/ +void inv_q_rotate(const long *q, const long *in, long *out) +{ + long q_temp1[4], q_temp2[4]; + long in4[4], out4[4]; + + // Fixme optimize + in4[0] = 0; + memcpy(&in4[1], in, 3 * sizeof(long)); + inv_q_mult(q, in4, q_temp1); + inv_q_invert(q, q_temp2); + inv_q_mult(q_temp1, q_temp2, out4); + memcpy(out, &out4[1], 3 * sizeof(long)); +} + +void inv_q_multf(const float *q1, const float *q2, float *qProd) +{ + INVENSENSE_FUNC_START; + qProd[0] = + (q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]); + qProd[1] = + (q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]); + qProd[2] = + (q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]); + qProd[3] = + (q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0]); +} + +void inv_q_addf(const float *q1, const float *q2, float *qSum) +{ + INVENSENSE_FUNC_START; + qSum[0] = q1[0] + q2[0]; + qSum[1] = q1[1] + q2[1]; + qSum[2] = q1[2] + q2[2]; + qSum[3] = q1[3] + q2[3]; +} + +void inv_q_normalizef(float *q) +{ + INVENSENSE_FUNC_START; + float normSF = 0; + float xHalf = 0; + normSF = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + if (normSF < 2) { + xHalf = 0.5f * normSF; + normSF = normSF * (1.5f - xHalf * normSF * normSF); + normSF = normSF * (1.5f - xHalf * normSF * normSF); + normSF = normSF * (1.5f - xHalf * normSF * normSF); + normSF = normSF * (1.5f - xHalf * normSF * normSF); + q[0] *= normSF; + q[1] *= normSF; + q[2] *= normSF; + q[3] *= normSF; + } else { + q[0] = 1.0; + q[1] = 0.0; + q[2] = 0.0; + q[3] = 0.0; + } + normSF = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); +} + +/** Performs a length 4 vector normalization with a square root. +* @param[in,out] q vector to normalize. Returns [1,0,0,0] is magnitude is zero. +*/ +void inv_q_norm4(float *q) +{ + float mag; + mag = sqrtf(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + if (mag) { + q[0] /= mag; + q[1] /= mag; + q[2] /= mag; + q[3] /= mag; + } else { + q[0] = 1.f; + q[1] = 0.f; + q[2] = 0.f; + q[3] = 0.f; + } +} + +void inv_q_invertf(const float *q, float *qInverted) +{ + INVENSENSE_FUNC_START; + qInverted[0] = q[0]; + qInverted[1] = -q[1]; + qInverted[2] = -q[2]; + qInverted[3] = -q[3]; +} + +/** + * Converts a quaternion to a rotation matrix. + * @param[in] quat 4-element quaternion in fixed point. One is 2^30. + * @param[out] rot Rotation matrix in fixed point. One is 2^30. The + * First 3 elements of the rotation matrix, represent + * the first row of the matrix. Rotation matrix multiplied + * by a 3 element column vector transform a vector from Body + * to World. + */ +void inv_quaternion_to_rotation(const long *quat, long *rot) +{ + rot[0] = + inv_q29_mult(quat[1], quat[1]) + inv_q29_mult(quat[0], + quat[0]) - + 1073741824L; + rot[1] = + inv_q29_mult(quat[1], quat[2]) - inv_q29_mult(quat[3], quat[0]); + rot[2] = + inv_q29_mult(quat[1], quat[3]) + inv_q29_mult(quat[2], quat[0]); + rot[3] = + inv_q29_mult(quat[1], quat[2]) + inv_q29_mult(quat[3], quat[0]); + rot[4] = + inv_q29_mult(quat[2], quat[2]) + inv_q29_mult(quat[0], + quat[0]) - + 1073741824L; + rot[5] = + inv_q29_mult(quat[2], quat[3]) - inv_q29_mult(quat[1], quat[0]); + rot[6] = + inv_q29_mult(quat[1], quat[3]) - inv_q29_mult(quat[2], quat[0]); + rot[7] = + inv_q29_mult(quat[2], quat[3]) + inv_q29_mult(quat[1], quat[0]); + rot[8] = + inv_q29_mult(quat[3], quat[3]) + inv_q29_mult(quat[0], + quat[0]) - + 1073741824L; +} + +/** + * Converts a quaternion to a rotation vector. A rotation vector is + * a method to represent a 4-element quaternion vector in 3-elements. + * To get the quaternion from the 3-elements, The last 3-elements of + * the quaternion will be the given rotation vector. The first element + * of the quaternion will be the positive value that will be required + * to make the magnitude of the quaternion 1.0 or 2^30 in fixed point units. + * @param[in] quat 4-element quaternion in fixed point. One is 2^30. + * @param[out] rot Rotation vector in fixed point. One is 2^30. + */ +void inv_quaternion_to_rotation_vector(const long *quat, long *rot) +{ + rot[0] = quat[1]; + rot[1] = quat[2]; + rot[2] = quat[3]; + + if (quat[0] < 0.0) { + rot[0] = -rot[0]; + rot[1] = -rot[1]; + rot[2] = -rot[2]; + } +} + +/** Converts a 32-bit long to a big endian byte stream */ +unsigned char *inv_int32_to_big8(long x, unsigned char *big8) +{ + big8[0] = (unsigned char)((x >> 24) & 0xff); + big8[1] = (unsigned char)((x >> 16) & 0xff); + big8[2] = (unsigned char)((x >> 8) & 0xff); + big8[3] = (unsigned char)(x & 0xff); + return big8; +} + +/** Converts a big endian byte stream into a 32-bit long */ +long inv_big8_to_int32(const unsigned char *big8) +{ + long x; + x = ((long)big8[0] << 24) | ((long)big8[1] << 16) | ((long)big8[2] << 8) + | ((long)big8[3]); + return x; +} + +/** Converts a big endian byte stream into a 16-bit integer (short) */ +short inv_big8_to_int16(const unsigned char *big8) +{ + short x; + x = ((short)big8[0] << 8) | ((short)big8[1]); + return x; +} + +/** Converts a little endian byte stream into a 16-bit integer (short) */ +short inv_little8_to_int16(const unsigned char *little8) +{ + short x; + x = ((short)little8[1] << 8) | ((short)little8[0]); + return x; +} + +/** Converts a 16-bit short to a big endian byte stream */ +unsigned char *inv_int16_to_big8(short x, unsigned char *big8) +{ + big8[0] = (unsigned char)((x >> 8) & 0xff); + big8[1] = (unsigned char)(x & 0xff); + return big8; +} + +void inv_matrix_det_inc(float *a, float *b, int *n, int x, int y) +{ + int k, l, i, j; + for (i = 0, k = 0; i < *n; i++, k++) { + for (j = 0, l = 0; j < *n; j++, l++) { + if (i == x) + i++; + if (j == y) + j++; + *(b + 6 * k + l) = *(a + 6 * i + j); + } + } + *n = *n - 1; +} + +void inv_matrix_det_incd(double *a, double *b, int *n, int x, int y) +{ + int k, l, i, j; + for (i = 0, k = 0; i < *n; i++, k++) { + for (j = 0, l = 0; j < *n; j++, l++) { + if (i == x) + i++; + if (j == y) + j++; + *(b + 6 * k + l) = *(a + 6 * i + j); + } + } + *n = *n - 1; +} + +float inv_matrix_det(float *p, int *n) +{ + float d[6][6], sum = 0; + int i, j, m; + m = *n; + if (*n == 2) + return (*p ** (p + 7) - *(p + 1) ** (p + 6)); + for (i = 0, j = 0; j < m; j++) { + *n = m; + inv_matrix_det_inc(p, &d[0][0], n, i, j); + sum = + sum + *(p + 6 * i + j) * SIGNM(i + + j) * + inv_matrix_det(&d[0][0], n); + } + + return (sum); +} + +double inv_matrix_detd(double *p, int *n) +{ + double d[6][6], sum = 0; + int i, j, m; + m = *n; + if (*n == 2) + return (*p ** (p + 7) - *(p + 1) ** (p + 6)); + for (i = 0, j = 0; j < m; j++) { + *n = m; + inv_matrix_det_incd(p, &d[0][0], n, i, j); + sum = + sum + *(p + 6 * i + j) * SIGNM(i + + j) * + inv_matrix_detd(&d[0][0], n); + } + + return (sum); +} + +/** Wraps angle from (-M_PI,M_PI] + * @param[in] ang Angle in radians to wrap + * @return Wrapped angle from (-M_PI,M_PI] + */ +float inv_wrap_angle(float ang) +{ + if (ang > M_PI) + return ang - 2 * (float)M_PI; + else if (ang <= -(float)M_PI) + return ang + 2 * (float)M_PI; + else + return ang; +} + +/** Finds the minimum angle difference ang1-ang2 such that difference + * is between [-M_PI,M_PI] + * @param[in] ang1 + * @param[in] ang2 + * @return angle difference ang1-ang2 + */ +float inv_angle_diff(float ang1, float ang2) +{ + float d; + ang1 = inv_wrap_angle(ang1); + ang2 = inv_wrap_angle(ang2); + d = ang1 - ang2; + if (d > M_PI) + d -= 2 * (float)M_PI; + else if (d < -(float)M_PI) + d += 2 * (float)M_PI; + return d; +} + +/** bernstein hash, derived from public domain source */ +uint32_t inv_checksum(const unsigned char *str, int len) +{ + uint32_t hash = 5381; + int i, c; + + for (i = 0; i < len; i++) { + c = *(str + i); + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + } + + return hash; +} + +static unsigned short inv_row_2_scale(const signed char *row) +{ + unsigned short b; + + if (row[0] > 0) + b = 0; + else if (row[0] < 0) + b = 4; + else if (row[1] > 0) + b = 1; + else if (row[1] < 0) + b = 5; + else if (row[2] > 0) + b = 2; + else if (row[2] < 0) + b = 6; + else + b = 7; // error + return b; +} + + +/** Converts an orientation matrix made up of 0,+1,and -1 to a scalar representation. +* @param[in] mtx Orientation matrix to convert to a scalar. +* @return Description of orientation matrix. The lowest 2 bits (0 and 1) represent the column the one is on for the +* first row, with the bit number 2 being the sign. The next 2 bits (3 and 4) represent +* the column the one is on for the second row with bit number 5 being the sign. +* The next 2 bits (6 and 7) represent the column the one is on for the third row with +* bit number 8 being the sign. In binary the identity matrix would therefor be: +* 010_001_000 or 0x88 in hex. +*/ +unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx) +{ + + unsigned short scalar; + + /* + XYZ 010_001_000 Identity Matrix + XZY 001_010_000 + YXZ 010_000_001 + YZX 000_010_001 + ZXY 001_000_010 + ZYX 000_001_010 + */ + + scalar = inv_row_2_scale(mtx); + scalar |= inv_row_2_scale(mtx + 3) << 3; + scalar |= inv_row_2_scale(mtx + 6) << 6; + + + return scalar; +} + +/** Uses the scalar orientation value to convert from chip frame to body frame +* @param[in] orientation A scalar that represent how to go from chip to body frame +* @param[in] input Input vector, length 3 +* @param[out] output Output vector, length 3 +*/ +void inv_convert_to_body(unsigned short orientation, const long *input, long *output) +{ + output[0] = input[orientation & 0x03] * SIGNSET(orientation & 0x004); + output[1] = input[(orientation>>3) & 0x03] * SIGNSET(orientation & 0x020); + output[2] = input[(orientation>>6) & 0x03] * SIGNSET(orientation & 0x100); +} + +/** Uses the scalar orientation value to convert from body frame to chip frame +* @param[in] orientation A scalar that represent how to go from chip to body frame +* @param[in] input Input vector, length 3 +* @param[out] output Output vector, length 3 +*/ +void inv_convert_to_chip(unsigned short orientation, const long *input, long *output) +{ + output[orientation & 0x03] = input[0] * SIGNSET(orientation & 0x004); + output[(orientation>>3) & 0x03] = input[1] * SIGNSET(orientation & 0x020); + output[(orientation>>6) & 0x03] = input[2] * SIGNSET(orientation & 0x100); +} + + +/** Uses the scalar orientation value to convert from chip frame to body frame and +* apply appropriate scaling. +* @param[in] orientation A scalar that represent how to go from chip to body frame +* @param[in] sensitivity Sensitivity scale +* @param[in] input Input vector, length 3 +* @param[out] output Output vector, length 3 +*/ +void inv_convert_to_body_with_scale(unsigned short orientation, long sensitivity, const long *input, long *output) +{ + output[0] = inv_q30_mult(input[orientation & 0x03] * + SIGNSET(orientation & 0x004), sensitivity); + output[1] = inv_q30_mult(input[(orientation>>3) & 0x03] * + SIGNSET(orientation & 0x020), sensitivity); + output[2] = inv_q30_mult(input[(orientation>>6) & 0x03] * + SIGNSET(orientation & 0x100), sensitivity); +} + +/** find a norm for a vector +* @param[in] a vector [3x1] +* @param[out] output the norm of the input vector +*/ +double inv_vector_norm(const float *x) +{ + return sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]); +} + +void inv_init_biquad_filter(inv_biquad_filter_t *pFilter, float *pBiquadCoeff) { + int i; + // initial state to zero + pFilter->state[0] = 0; + pFilter->state[1] = 0; + + // set up coefficients + for (i=0; i<5; i++) { + pFilter->c[i] = pBiquadCoeff[i]; + } +} + +void inv_calc_state_to_match_output(inv_biquad_filter_t *pFilter, float input) +{ + pFilter->input = input; + pFilter->output = input; + pFilter->state[0] = input / (1 + pFilter->c[2] + pFilter->c[3]); + pFilter->state[1] = pFilter->state[0]; +} + +float inv_biquad_filter_process(inv_biquad_filter_t *pFilter, float input) { + float stateZero; + + pFilter->input = input; + // calculate the new state; + stateZero = pFilter->input - pFilter->c[2]*pFilter->state[0] + - pFilter->c[3]*pFilter->state[1]; + + pFilter->output = stateZero + pFilter->c[0]*pFilter->state[0] + + pFilter->c[1]*pFilter->state[1]; + + // update the output and state + pFilter->output = pFilter->output * pFilter->c[4]; + pFilter->state[1] = pFilter->state[0]; + pFilter->state[0] = stateZero; + return pFilter->output; +} + +void inv_get_cross_product_vec(float *cgcross, float compass[3], float grav[3]) { + + cgcross[0] = (float)compass[1] * grav[2] - (float)compass[2] * grav[1]; + cgcross[1] = (float)compass[2] * grav[0] - (float)compass[0] * grav[2]; + cgcross[2] = (float)compass[0] * grav[1] - (float)compass[1] * grav[0]; +} + +void mlMatrixVectorMult(long matrix[9], const long vecIn[3], long *vecOut) { + // matrix format + // [ 0 3 6; + // 1 4 7; + // 2 5 8] + + // vector format: [0 1 2]^T; + int i, j; + long temp; + + for (i=0; i<3; i++) { + temp = 0; + for (j=0; j<3; j++) { + temp += inv_q30_mult(matrix[i+j*3], vecIn[j]); + } + vecOut[i] = temp; + } +} + + +/** + * @} + */ diff --git a/bsp/boards/mimsy2-cc2538/ml_math_func.h b/bsp/boards/mimsy2-cc2538/ml_math_func.h new file mode 100644 index 0000000000..66d271b0f9 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/ml_math_func.h @@ -0,0 +1,132 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INVENSENSE_INV_MATH_FUNC_H__ +#define INVENSENSE_INV_MATH_FUNC_H__ + +#include "mltypes.h" + +#define GYRO_MAG_SQR_SHIFT 6 +#define NUM_ROTATION_MATRIX_ELEMENTS (9) +#define ROT_MATRIX_SCALE_LONG (1073741824L) +#define ROT_MATRIX_SCALE_FLOAT (1073741824.0f) +#define ROT_MATRIX_LONG_TO_FLOAT( longval ) \ + ((float) ((longval) / ROT_MATRIX_SCALE_FLOAT )) +#define SIGNM(k)((int)(k)&1?-1:1) +#define SIGNSET(x) ((x) ? -1 : +1) + +#define INV_TWO_POWER_NEG_30 9.313225746154785e-010f + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct { + float state[4]; + float c[5]; + float input; + float output; + } inv_biquad_filter_t; + + static inline float inv_q30_to_float(long q30) + { + return (float) q30 / ((float)(1L << 30)); + } + + static inline double inv_q30_to_double(long q30) + { + return (double) q30 / ((double)(1L << 30)); + } + + static inline float inv_q16_to_float(long q16) + { + return (float) q16 / (1L << 16); + } + + static inline double inv_q16_to_double(long q16) + { + return (double) q16 / (1L << 16); + } + + + + + long inv_q29_mult(long a, long b); + long inv_q30_mult(long a, long b); + + /* UMPL_ELIMINATE_64BIT Notes: + * An alternate implementation using float instead of long long accudoublemulators + * is provided for q29_mult and q30_mult. + * When long long accumulators are used and an alternate implementation is not + * available, we eliminate the entire function and header with a macro. + */ +#ifndef UMPL_ELIMINATE_64BIT + long inv_q30_div(long a, long b); + long inv_q_shift_mult(long a, long b, int shift); +#endif + + void inv_q_mult(const long *q1, const long *q2, long *qProd); + void inv_q_add(long *q1, long *q2, long *qSum); + void inv_q_normalize(long *q); + void inv_q_invert(const long *q, long *qInverted); + void inv_q_multf(const float *q1, const float *q2, float *qProd); + void inv_q_addf(const float *q1, const float *q2, float *qSum); + void inv_q_normalizef(float *q); + void inv_q_norm4(float *q); + void inv_q_invertf(const float *q, float *qInverted); + void inv_quaternion_to_rotation(const long *quat, long *rot); + unsigned char *inv_int32_to_big8(long x, unsigned char *big8); + long inv_big8_to_int32(const unsigned char *big8); + short inv_big8_to_int16(const unsigned char *big8); + short inv_little8_to_int16(const unsigned char *little8); + unsigned char *inv_int16_to_big8(short x, unsigned char *big8); + float inv_matrix_det(float *p, int *n); + void inv_matrix_det_inc(float *a, float *b, int *n, int x, int y); + double inv_matrix_detd(double *p, int *n); + void inv_matrix_det_incd(double *a, double *b, int *n, int x, int y); + float inv_wrap_angle(float ang); + float inv_angle_diff(float ang1, float ang2); + void inv_quaternion_to_rotation_vector(const long *quat, long *rot); + unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx); + void inv_convert_to_body(unsigned short orientation, const long *input, long *output); + void inv_convert_to_chip(unsigned short orientation, const long *input, long *output); + void inv_convert_to_body_with_scale(unsigned short orientation, long sensitivity, const long *input, long *output); + void inv_q_rotate(const long *q, const long *in, long *out); + void inv_vector_normalize(long *vec, int length); + uint32_t inv_checksum(const unsigned char *str, int len); + float inv_compass_angle(const long *compass, const long *grav, + const long *quat); + unsigned long inv_get_gyro_sum_of_sqr(const long *gyro); + +#ifdef EMPL + float inv_sinf(float x); + float inv_cosf(float x); + /* eMPL timestamps are assumed to be in milliseconds. */ + static inline long inv_delta_time_ms(inv_time_t t1, inv_time_t t2) + { + return (long)((t1 - t2)); + } +#else + static inline long inv_delta_time_ms(inv_time_t t1, inv_time_t t2) + { + return (long)((t1 - t2) / 1000000L); + } +#endif + + double quaternion_to_rotation_angle(const long *quat); + double inv_vector_norm(const float *x); + + void inv_init_biquad_filter(inv_biquad_filter_t *pFilter, float *pBiquadCoeff); + float inv_biquad_filter_process(inv_biquad_filter_t *pFilter, float input); + void inv_calc_state_to_match_output(inv_biquad_filter_t *pFilter, float input); + void inv_get_cross_product_vec(float *cgcross, float compass[3], float grav[3]); + + void mlMatrixVectorMult(long matrix[9], const long vecIn[3], long *vecOut); + +#ifdef __cplusplus +} +#endif +#endif // INVENSENSE_INV_MATH_FUNC_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mlinclude.h b/bsp/boards/mimsy2-cc2538/mlinclude.h new file mode 100644 index 0000000000..2cdac0a7c3 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mlinclude.h @@ -0,0 +1,38 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +#ifndef INV_INCLUDE_H__ +#define INV_INCLUDE_H__ + +#define INVENSENSE_FUNC_START typedef int invensensePutFunctionCallsHere + +#ifdef COVERAGE +#include "utestCommon.h" +#endif +#ifdef PROFILE +#include "profile.h" +#endif + +#ifdef WIN32 +#ifdef COVERAGE + +extern int functionEnterLog(const char *file, const char *func); +extern int functionExitLog(const char *file, const char *func); + +#undef INVENSENSE_FUNC_START +#define INVENSENSE_FUNC_START __pragma(message(__FILE__ "|"__FUNCTION__ )) \ + int dslkQjDsd = functionEnterLog(__FILE__, __FUNCTION__) +#endif // COVERAGE +#endif // WIN32 + +#ifdef PROFILE +#undef INVENSENSE_FUNC_START +#define INVENSENSE_FUNC_START int dslkQjDsd = profileEnter(__FILE__, __FUNCTION__) +#define return if ( profileExit(__FILE__, __FUNCTION__) ) return +#endif // PROFILE + +// #define return if ( functionExitLog(__FILE__, __FUNCTION__) ) return + +#endif //INV_INCLUDE_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/data_builder.c b/bsp/boards/mimsy2-cc2538/mllite/data_builder.c new file mode 100644 index 0000000000..8dfffb21bc --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/data_builder.c @@ -0,0 +1,1263 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/** + * @defgroup Data_Builder data_builder + * @brief Motion Library - Data Builder + * Constructs and Creates the data for MPL + * + * @{ + * @file data_builder.c + * @brief Data Builder. + */ + +#undef MPL_LOG_NDEBUG +#define MPL_LOG_NDEBUG 0 /* Use 0 to turn on MPL_LOGV output */ + +#include + +#include "ml_math_func.h" +#include "data_builder.h" +#include "mlmath.h" +#include "storage_manager.h" +#include "message_layer.h" +#include "results_holder.h" + +#include "log.h" +#undef MPL_LOG_TAG +#define MPL_LOG_TAG "MPL" + +typedef inv_error_t (*inv_process_cb_func)(struct inv_sensor_cal_t *data); + +struct process_t { + inv_process_cb_func func; + int priority; + int data_required; +}; + +struct inv_db_save_t { + /** Compass Bias in Chip Frame in Hardware units scaled by 2^16 */ + long compass_bias[3]; + /** Gyro Bias in Chip Frame in Hardware units scaled by 2^16 */ + long gyro_bias[3]; + /** Temperature when *gyro_bias was stored. */ + long gyro_temp; + /** Flag to indicate temperature compensation that biases where stored. */ + int gyro_bias_tc_set; + /** Accel Bias in Chip Frame in Hardware units scaled by 2^16 */ + long accel_bias[3]; + /** Temperature when accel bias was stored. */ + long accel_temp; + long gyro_temp_slope[3]; + /** Sensor Accuracy */ + int gyro_accuracy; + int accel_accuracy; + int compass_accuracy; +}; + +struct inv_data_builder_t { + int num_cb; + struct process_t process[INV_MAX_DATA_CB]; + struct inv_db_save_t save; + int compass_disturbance; +#ifdef INV_PLAYBACK_DBG + int debug_mode; + int last_mode; + FILE *file; +#endif +}; + +void inv_apply_calibration(struct inv_single_sensor_t *sensor, const long *bias); +static void inv_set_contiguous(void); + +static struct inv_data_builder_t inv_data_builder; +static struct inv_sensor_cal_t sensors; + +/** Change this key if the data being stored by this file changes */ +#define INV_DB_SAVE_KEY 53395 + +#ifdef INV_PLAYBACK_DBG + +/** Turn on data logging to allow playback of same scenario at a later time. +* @param[in] file File to write to, must be open. +*/ +void inv_turn_on_data_logging(FILE *file) +{ + MPL_LOGV("input data logging started\n"); + inv_data_builder.file = file; + inv_data_builder.debug_mode = RD_RECORD; +} + +/** Turn off data logging to allow playback of same scenario at a later time. +* File passed to inv_turn_on_data_logging() must be closed after calling this. +*/ +void inv_turn_off_data_logging() +{ + MPL_LOGV("input data logging stopped\n"); + inv_data_builder.debug_mode = RD_NO_DEBUG; + inv_data_builder.file = NULL; +} +#endif + +/** This function receives the data that was stored in non-volatile memory between power off */ +static inv_error_t inv_db_load_func(const unsigned char *data) +{ + memcpy(&inv_data_builder.save, data, sizeof(inv_data_builder.save)); + // copy in the saved accuracy in the actual sensors accuracy + sensors.gyro.accuracy = inv_data_builder.save.gyro_accuracy; + sensors.accel.accuracy = inv_data_builder.save.accel_accuracy; + sensors.compass.accuracy = inv_data_builder.save.compass_accuracy; + // TODO + if (sensors.compass.accuracy == 3) { + inv_set_compass_bias_found(1); + } + return INV_SUCCESS; +} + +/** This function returns the data to be stored in non-volatile memory between power off */ +static inv_error_t inv_db_save_func(unsigned char *data) +{ + memcpy(data, &inv_data_builder.save, sizeof(inv_data_builder.save)); + return INV_SUCCESS; +} + +/** Initialize the data builder +*/ +inv_error_t inv_init_data_builder(void) +{ + /* TODO: Hardcode temperature scale/offset here. */ + memset(&inv_data_builder, 0, sizeof(inv_data_builder)); + memset(&sensors, 0, sizeof(sensors)); + + // disable the soft iron transform process + inv_reset_compass_soft_iron_matrix(); + + return inv_register_load_store(inv_db_load_func, inv_db_save_func, + sizeof(inv_data_builder.save), + INV_DB_SAVE_KEY); +} + +/** Gyro sensitivity. +* @return A scale factor to convert device units to degrees per second scaled by 2^16 +* such that degrees_per_second = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum rate * 2^15. +*/ +long inv_get_gyro_sensitivity() +{ + return sensors.gyro.sensitivity; +} + +/** Accel sensitivity. +* @return A scale factor to convert device units to g's scaled by 2^16 +* such that g_s = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum accel value in g's * 2^15. +*/ +long inv_get_accel_sensitivity(void) +{ + return sensors.accel.sensitivity; +} + +/** Compass sensitivity. +* @return A scale factor to convert device units to micro Tesla scaled by 2^16 +* such that uT = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum uT * 2^15. +*/ +long inv_get_compass_sensitivity(void) +{ + return sensors.compass.sensitivity; +} + +/** Sets orientation and sensitivity field for a sensor. +* @param[out] sensor Structure to apply settings to +* @param[in] orientation Orientation description of how part is mounted. +* @param[in] sensitivity A Scale factor to convert from hardware units to +* standard units (dps, uT, g). +*/ +void set_sensor_orientation_and_scale(struct inv_single_sensor_t *sensor, + int orientation, long sensitivity) +{ + sensor->sensitivity = sensitivity; + sensor->orientation = orientation; +} + +/** Sets the Orientation and Sensitivity of the gyro data. +* @param[in] orientation A scalar defining the transformation from chip mounting +* to the body frame. The function inv_orientation_matrix_to_scalar() +* can convert the transformation matrix to this scalar and describes the +* scalar in further detail. +* @param[in] sensitivity A scale factor to convert device units to degrees per second scaled by 2^16 +* such that degrees_per_second = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum rate * 2^15. +*/ +void inv_set_gyro_orientation_and_scale(int orientation, long sensitivity) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_G_ORIENT; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&orientation, sizeof(orientation), 1, inv_data_builder.file); + fwrite(&sensitivity, sizeof(sensitivity), 1, inv_data_builder.file); + } +#endif + set_sensor_orientation_and_scale(&sensors.gyro, orientation, + sensitivity); +} + +/** Set Gyro Sample rate in micro seconds. +* @param[in] sample_rate_us Set Gyro Sample rate in us +*/ +void inv_set_gyro_sample_rate(long sample_rate_us) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_G_SAMPLE_RATE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); + } +#endif + sensors.gyro.sample_rate_us = sample_rate_us; + sensors.gyro.sample_rate_ms = sample_rate_us / 1000; + if (sensors.gyro.bandwidth == 0) { + sensors.gyro.bandwidth = (int)(1000000L / sample_rate_us); + } +} + +/** Set Accel Sample rate in micro seconds. +* @param[in] sample_rate_us Set Accel Sample rate in us +*/ +void inv_set_accel_sample_rate(long sample_rate_us) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_A_SAMPLE_RATE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); + } +#endif + sensors.accel.sample_rate_us = sample_rate_us; + sensors.accel.sample_rate_ms = sample_rate_us / 1000; + if (sensors.accel.bandwidth == 0) { + sensors.accel.bandwidth = (int)(1000000L / sample_rate_us); + } +} + +/** Set Compass Sample rate in micro seconds. +* @param[in] sample_rate_us Set Gyro Sample rate in micro seconds. +*/ +void inv_set_compass_sample_rate(long sample_rate_us) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_C_SAMPLE_RATE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); + } +#endif + sensors.compass.sample_rate_us = sample_rate_us; + sensors.compass.sample_rate_ms = sample_rate_us / 1000; + if (sensors.compass.bandwidth == 0) { + sensors.compass.bandwidth = (int)(1000000L / sample_rate_us); + } +} + +void inv_get_gyro_sample_rate_ms(long *sample_rate_ms) +{ + *sample_rate_ms = sensors.gyro.sample_rate_ms; +} + +void inv_get_accel_sample_rate_ms(long *sample_rate_ms) +{ + *sample_rate_ms = sensors.accel.sample_rate_ms; +} + +void inv_get_compass_sample_rate_ms(long *sample_rate_ms) +{ + *sample_rate_ms = sensors.compass.sample_rate_ms; +} + +/** Set Quat Sample rate in micro seconds. +* @param[in] sample_rate_us Set Quat Sample rate in us +*/ +void inv_set_quat_sample_rate(long sample_rate_us) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_Q_SAMPLE_RATE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); + } +#endif + sensors.quat.sample_rate_us = sample_rate_us; + sensors.quat.sample_rate_ms = sample_rate_us / 1000; +} + +/** Set Gyro Bandwidth in Hz +* @param[in] bandwidth_hz Gyro bandwidth in Hz +*/ +void inv_set_gyro_bandwidth(int bandwidth_hz) +{ + sensors.gyro.bandwidth = bandwidth_hz; +} + +/** Set Accel Bandwidth in Hz +* @param[in] bandwidth_hz Gyro bandwidth in Hz +*/ +void inv_set_accel_bandwidth(int bandwidth_hz) +{ + sensors.accel.bandwidth = bandwidth_hz; +} + +/** Set Compass Bandwidth in Hz +* @param[in] bandwidth_hz Gyro bandwidth in Hz +*/ +void inv_set_compass_bandwidth(int bandwidth_hz) +{ + sensors.compass.bandwidth = bandwidth_hz; +} + +/** Helper function stating whether the compass is on or off. + * @return TRUE if compass if on, 0 if compass if off +*/ +int inv_get_compass_on() +{ + return (sensors.compass.status & INV_SENSOR_ON) == INV_SENSOR_ON; +} + +/** Helper function stating whether the gyro is on or off. + * @return TRUE if gyro if on, 0 if gyro if off +*/ +int inv_get_gyro_on() +{ + return (sensors.gyro.status & INV_SENSOR_ON) == INV_SENSOR_ON; +} + +/** Helper function stating whether the acceleromter is on or off. + * @return TRUE if accel if on, 0 if accel if off +*/ +int inv_get_accel_on() +{ + return (sensors.accel.status & INV_SENSOR_ON) == INV_SENSOR_ON; +} + +/** Get last timestamp across all 3 sensors that are on. +* This find out which timestamp has the largest value for sensors that are on. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_time_t inv_get_last_timestamp() +{ + inv_time_t timestamp = 0; + if (sensors.accel.status & INV_SENSOR_ON) { + timestamp = sensors.accel.timestamp; + } + if (sensors.gyro.status & INV_SENSOR_ON) { + if (timestamp < sensors.gyro.timestamp) { + timestamp = sensors.gyro.timestamp; + } + } + if (sensors.compass.status & INV_SENSOR_ON) { + if (timestamp < sensors.compass.timestamp) { + timestamp = sensors.compass.timestamp; + } + } + if (sensors.temp.status & INV_SENSOR_ON) { + if (timestamp < sensors.temp.timestamp) + timestamp = sensors.temp.timestamp; + } + return timestamp; +} + +/** Sets the orientation and sensitivity of the gyro data. +* @param[in] orientation A scalar defining the transformation from chip mounting +* to the body frame. The function inv_orientation_matrix_to_scalar() +* can convert the transformation matrix to this scalar and describes the +* scalar in further detail. +* @param[in] sensitivity A scale factor to convert device units to g's +* such that g's = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum g_value * 2^15. +*/ +void inv_set_accel_orientation_and_scale(int orientation, long sensitivity) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_A_ORIENT; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&orientation, sizeof(orientation), 1, inv_data_builder.file); + fwrite(&sensitivity, sizeof(sensitivity), 1, inv_data_builder.file); + } +#endif + set_sensor_orientation_and_scale(&sensors.accel, orientation, + sensitivity); +} + +/** Sets the Orientation and Sensitivity of the gyro data. +* @param[in] orientation A scalar defining the transformation from chip mounting +* to the body frame. The function inv_orientation_matrix_to_scalar() +* can convert the transformation matrix to this scalar and describes the +* scalar in further detail. +* @param[in] sensitivity A scale factor to convert device units to uT +* such that uT = device_units * sensitivity / 2^30. Typically +* it works out to be the maximum uT_value * 2^15. +*/ +void inv_set_compass_orientation_and_scale(int orientation, long sensitivity) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_C_ORIENT; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&orientation, sizeof(orientation), 1, inv_data_builder.file); + fwrite(&sensitivity, sizeof(sensitivity), 1, inv_data_builder.file); + } +#endif + set_sensor_orientation_and_scale(&sensors.compass, orientation, sensitivity); +} + +void inv_matrix_vector_mult(const long *A, const long *x, long *y) +{ + y[0] = inv_q30_mult(A[0], x[0]) + inv_q30_mult(A[1], x[1]) + inv_q30_mult(A[2], x[2]); + y[1] = inv_q30_mult(A[3], x[0]) + inv_q30_mult(A[4], x[1]) + inv_q30_mult(A[5], x[2]); + y[2] = inv_q30_mult(A[6], x[0]) + inv_q30_mult(A[7], x[1]) + inv_q30_mult(A[8], x[2]); +} + +/** Takes raw data stored in the sensor, removes bias, and converts it to +* calibrated data in the body frame. Also store raw data for body frame. +* @param[in,out] sensor structure to modify +* @param[in] bias bias in the mounting frame, in hardware units scaled by +* 2^16. Length 3. +*/ +void inv_apply_calibration(struct inv_single_sensor_t *sensor, const long *bias) +{ + long raw32[3]; + + // Convert raw to calibrated + raw32[0] = (long)sensor->raw[0] << 15; + raw32[1] = (long)sensor->raw[1] << 15; + raw32[2] = (long)sensor->raw[2] << 15; + + inv_convert_to_body_with_scale(sensor->orientation, sensor->sensitivity << 1, raw32, sensor->raw_scaled); + + raw32[0] -= bias[0] >> 1; + raw32[1] -= bias[1] >> 1; + raw32[2] -= bias[2] >> 1; + + inv_convert_to_body_with_scale(sensor->orientation, sensor->sensitivity << 1, raw32, sensor->calibrated); + + sensor->status |= INV_CALIBRATED; +} + +/** Returns the current bias for the compass +* @param[out] bias Compass bias in hardware units scaled by 2^16. In mounting frame. +* Length 3. +*/ +void inv_get_compass_bias(long *bias) +{ + if (bias != NULL) { + memcpy(bias, inv_data_builder.save.compass_bias, sizeof(inv_data_builder.save.compass_bias)); + } +} + +void inv_set_compass_bias(const long *bias, int accuracy) +{ + if (memcmp(inv_data_builder.save.compass_bias, bias, sizeof(inv_data_builder.save.compass_bias))) { + memcpy(inv_data_builder.save.compass_bias, bias, sizeof(inv_data_builder.save.compass_bias)); + inv_apply_calibration(&sensors.compass, inv_data_builder.save.compass_bias); + } + sensors.compass.accuracy = accuracy; + inv_data_builder.save.compass_accuracy = accuracy; + inv_set_message(INV_MSG_NEW_CB_EVENT, INV_MSG_NEW_CB_EVENT, 0); +} + +/** Set the state of a compass disturbance +* @param[in] dist 1=disturbance, 0=no disturbance +*/ +void inv_set_compass_disturbance(int dist) +{ + inv_data_builder.compass_disturbance = dist; +} + +int inv_get_compass_disturbance(void) { + return inv_data_builder.compass_disturbance; +} +/** Sets the accel bias. +* @param[in] bias Accel bias, length 3. In HW units scaled by 2^16 in body frame +* @param[in] accuracy Accuracy rating from 0 to 3, with 3 being most accurate. +*/ +void inv_set_accel_bias(const long *bias, int accuracy) +{ + if (bias) { + if (memcmp(inv_data_builder.save.accel_bias, bias, sizeof(inv_data_builder.save.accel_bias))) { + memcpy(inv_data_builder.save.accel_bias, bias, sizeof(inv_data_builder.save.accel_bias)); + inv_apply_calibration(&sensors.accel, inv_data_builder.save.accel_bias); + } + } + sensors.accel.accuracy = accuracy; + inv_data_builder.save.accel_accuracy = accuracy; + inv_set_message(INV_MSG_NEW_AB_EVENT, INV_MSG_NEW_AB_EVENT, 0); +} + +/** Sets the accel accuracy. +* @param[in] accuracy Accuracy rating from 0 to 3, with 3 being most accurate. +*/ +void inv_set_accel_accuracy(int accuracy) +{ + sensors.accel.accuracy = accuracy; + inv_data_builder.save.accel_accuracy = accuracy; + inv_set_message(INV_MSG_NEW_AB_EVENT, INV_MSG_NEW_AB_EVENT, 0); +} + +/** Sets the accel bias with control over which axis. +* @param[in] bias Accel bias, length 3. In HW units scaled by 2^16 in body frame +* @param[in] accuracy Accuracy rating from 0 to 3, with 3 being most accurate. +* @param[in] mask Mask to select axis to apply bias set. +*/ +void inv_set_accel_bias_mask(const long *bias, int accuracy, int mask) +{ + if (bias) { + if (mask & 1){ + inv_data_builder.save.accel_bias[0] = bias[0]; + } + if (mask & 2){ + inv_data_builder.save.accel_bias[1] = bias[1]; + } + if (mask & 4){ + inv_data_builder.save.accel_bias[2] = bias[2]; + } + + inv_apply_calibration(&sensors.accel, inv_data_builder.save.accel_bias); + } + sensors.accel.accuracy = accuracy; + inv_data_builder.save.accel_accuracy = accuracy; + inv_set_message(INV_MSG_NEW_AB_EVENT, INV_MSG_NEW_AB_EVENT, 0); +} + + +/** Sets the gyro bias +* @param[in] bias Gyro bias in hardware units scaled by 2^16. In chip mounting frame. +* Length 3. +* @param[in] accuracy Accuracy of bias. 0 = least accurate, 3 = most accurate. +*/ +void inv_set_gyro_bias(const long *bias, int accuracy) +{ + if (bias != NULL) { + if (memcmp(inv_data_builder.save.gyro_bias, bias, sizeof(inv_data_builder.save.gyro_bias))) { + memcpy(inv_data_builder.save.gyro_bias, bias, sizeof(inv_data_builder.save.gyro_bias)); + inv_apply_calibration(&sensors.gyro, inv_data_builder.save.gyro_bias); + } + } + sensors.gyro.accuracy = accuracy; + inv_data_builder.save.gyro_accuracy = accuracy; + + /* TODO: What should we do if there's no temperature data? */ + if (sensors.temp.calibrated[0]) + inv_data_builder.save.gyro_temp = sensors.temp.calibrated[0]; + else + /* Set to 27 deg C for now until we've got a better solution. */ + inv_data_builder.save.gyro_temp = 1769472L; + inv_set_message(INV_MSG_NEW_GB_EVENT, INV_MSG_NEW_GB_EVENT, 0); + + /* TODO: this flag works around the synchronization problem seen with using + the user-exposed message layer to signal the temperature compensation + module that gyro biases were set. + A better, cleaner method is certainly needed. */ + inv_data_builder.save.gyro_bias_tc_set = true; +} + +/** + * @internal + * @brief Return whether gyro biases were set to signal the temperature + * compensation algorithm that it can collect a data point to build + * the temperature slope while in no motion state. + * The flag clear automatically after is read. + * @return true if the flag was set, indicating gyro biases were set. + * false if the flag was not set. + */ +int inv_get_gyro_bias_tc_set(void) +{ + int flag = (inv_data_builder.save.gyro_bias_tc_set == true); + inv_data_builder.save.gyro_bias_tc_set = false; + return flag; +} + +/* TODO: Add this information to inv_sensor_cal_t */ +/** + * Get the gyro biases and temperature record from MPL + * @param[in] bias + * Gyro bias in hardware units scaled by 2^16. + * In chip mounting frame. + * Length 3. + * @param[in] temp + * Tempearature in degrees C. + */ +void inv_get_gyro_bias(long *bias, long *temp) +{ + if (bias != NULL) + memcpy(bias, inv_data_builder.save.gyro_bias, + sizeof(inv_data_builder.save.gyro_bias)); + if (temp != NULL) + temp[0] = inv_data_builder.save.gyro_temp; +} + +/** Get Accel Bias +* @param[out] bias Accel bias where +* @param[out] temp Temperature where 1 C = 2^16 +*/ +void inv_get_accel_bias(long *bias, long *temp) +{ + if (bias != NULL) + memcpy(bias, inv_data_builder.save.accel_bias, + sizeof(inv_data_builder.save.accel_bias)); + if (temp != NULL) + temp[0] = inv_data_builder.save.accel_temp; +} + +/** + * Record new accel data for use when inv_execute_on_data() is called + * @param[in] accel accel data. + * Length 3. + * Calibrated data is in m/s^2 scaled by 2^16 in body frame. + * Raw data is in device units in chip mounting frame. + * @param[in] status + * Lower 2 bits are the accuracy, with 0 being inaccurate, and 3 + * being most accurate. + * The upper bit INV_CALIBRATED, is set if the data was calibrated + * outside MPL and it is not set if the data being passed is raw. + * Raw data should be in device units, typically in a 16-bit range. + * @param[in] timestamp + * Monotonic time stamp, for Android it's in nanoseconds. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_build_accel(const long *accel, int status, inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_ACCEL; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(accel, sizeof(accel[0]), 3, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + + if ((status & INV_CALIBRATED) == 0) { + sensors.accel.raw[0] = (short)accel[0]; + sensors.accel.raw[1] = (short)accel[1]; + sensors.accel.raw[2] = (short)accel[2]; + sensors.accel.status |= INV_RAW_DATA; + inv_apply_calibration(&sensors.accel, inv_data_builder.save.accel_bias); + } else { + sensors.accel.calibrated[0] = accel[0]; + sensors.accel.calibrated[1] = accel[1]; + sensors.accel.calibrated[2] = accel[2]; + sensors.accel.status |= INV_CALIBRATED; + sensors.accel.accuracy = status & 3; + inv_data_builder.save.accel_accuracy = status & 3; + } + sensors.accel.status |= INV_NEW_DATA | INV_SENSOR_ON; + sensors.accel.timestamp_prev = sensors.accel.timestamp; + sensors.accel.timestamp = timestamp; + + return INV_SUCCESS; +} + +/** Record new gyro data and calls inv_execute_on_data() if previous +* sample has not been processed. +* @param[in] gyro Data is in device units. Length 3. +* @param[in] timestamp Monotonic time stamp, for Android it's in nanoseconds. +* @param[out] executed Set to 1 if data processing was done. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_build_gyro(const short *gyro, inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_GYRO; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(gyro, sizeof(gyro[0]), 3, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + + memcpy(sensors.gyro.raw, gyro, 3 * sizeof(short)); + sensors.gyro.status |= INV_NEW_DATA | INV_RAW_DATA | INV_SENSOR_ON; + sensors.gyro.timestamp_prev = sensors.gyro.timestamp; + sensors.gyro.timestamp = timestamp; + inv_apply_calibration(&sensors.gyro, inv_data_builder.save.gyro_bias); + + return INV_SUCCESS; +} + +/** Record new compass data for use when inv_execute_on_data() is called +* @param[in] compass Compass data, if it was calibrated outside MPL, the units are uT scaled by 2^16. +* Length 3. +* @param[in] status Lower 2 bits are the accuracy, with 0 being inaccurate, and 3 being most accurate. +* The upper bit INV_CALIBRATED, is set if the data was calibrated outside MPL and it is +* not set if the data being passed is raw. Raw data should be in device units, typically +* in a 16-bit range. +* @param[in] timestamp Monotonic time stamp, for Android it's in nanoseconds. +* @param[out] executed Set to 1 if data processing was done. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_build_compass(const long *compass, int status, + inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_COMPASS; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(compass, sizeof(compass[0]), 3, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + + if ((status & INV_CALIBRATED) == 0) { + long data[3]; + inv_set_compass_soft_iron_input_data(compass); + inv_get_compass_soft_iron_output_data(data); + sensors.compass.raw[0] = (short)data[0]; + sensors.compass.raw[1] = (short)data[1]; + sensors.compass.raw[2] = (short)data[2]; + inv_apply_calibration(&sensors.compass, inv_data_builder.save.compass_bias); + sensors.compass.status |= INV_RAW_DATA; + } else { + sensors.compass.calibrated[0] = compass[0]; + sensors.compass.calibrated[1] = compass[1]; + sensors.compass.calibrated[2] = compass[2]; + sensors.compass.status |= INV_CALIBRATED; + sensors.compass.accuracy = status & 3; + inv_data_builder.save.compass_accuracy = status & 3; + } + sensors.compass.timestamp_prev = sensors.compass.timestamp; + sensors.compass.timestamp = timestamp; + sensors.compass.status |= INV_NEW_DATA | INV_SENSOR_ON; + + return INV_SUCCESS; +} + +/** Record new temperature data for use when inv_execute_on_data() is called. + * @param[in] temp Temperature data in q16 format. + * @param[in] timestamp Monotonic time stamp; for Android it's in + * nanoseconds. +* @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_build_temp(const long temp, inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_TEMPERATURE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(&temp, sizeof(temp), 1, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + sensors.temp.calibrated[0] = temp; + sensors.temp.status |= INV_NEW_DATA | INV_RAW_DATA | INV_SENSOR_ON; + sensors.temp.timestamp_prev = sensors.temp.timestamp; + sensors.temp.timestamp = timestamp; + /* TODO: Apply scale, remove offset. */ + + return INV_SUCCESS; +} +/** quaternion data +* @param[in] quat Quaternion data. 2^30 = 1.0 or 2^14=1 for 16-bit data. +* Real part first. Length 4. +* @param[in] status number of axis, 16-bit or 32-bit +* @param[in] timestamp +* @param[in] timestamp Monotonic time stamp; for Android it's in +* nanoseconds. +* @param[out] executed Set to 1 if data processing was done. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_build_quat(const long *quat, int status, inv_time_t timestamp) +{ +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_QUAT; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + fwrite(quat, sizeof(quat[0]), 4, inv_data_builder.file); + fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); + } +#endif + + memcpy(sensors.quat.raw, quat, sizeof(sensors.quat.raw)); + sensors.quat.timestamp = timestamp; + sensors.quat.status |= INV_NEW_DATA | INV_RAW_DATA | INV_SENSOR_ON; + sensors.quat.status |= (INV_BIAS_APPLIED & status); + + return INV_SUCCESS; +} + +/** This should be called when the accel has been turned off. This is so +* that we will know if the data is contiguous. +*/ +void inv_accel_was_turned_off() +{ + sensors.accel.status = 0; +} + +/** This should be called when the compass has been turned off. This is so +* that we will know if the data is contiguous. +*/ +void inv_compass_was_turned_off() +{ + sensors.compass.status = 0; +} + +/** This should be called when the quaternion data from the DMP has been turned off. This is so +* that we will know if the data is contiguous. +*/ +void inv_quaternion_sensor_was_turned_off(void) +{ + sensors.quat.status = 0; +} + +/** This should be called when the gyro has been turned off. This is so +* that we will know if the data is contiguous. +*/ +void inv_gyro_was_turned_off() +{ + sensors.gyro.status = 0; +} + +/** This should be called when the temperature sensor has been turned off. + * This is so that we will know if the data is contiguous. + */ +void inv_temperature_was_turned_off() +{ + sensors.temp.status = 0; +} + +/** Registers to receive a callback when there is new sensor data. +* @internal +* @param[in] func Function pointer to receive callback when there is new sensor data +* @param[in] priority Lower priority numbers receive a callback before larger numbers. All priority +* numbers must be unique. +* @param[in] sensor_type Sets the type of data that triggers the callback. Must be non-zero. May be +* a combination. INV_ACCEL_NEW = accel data, INV_GYRO_NEW = +* gyro data, INV_MAG_NEW = compass data. So passing in +* INV_ACCEL_NEW | INV_MAG_NEW, a +* callback would be generated if there was new magnetomer data OR new accel data. +*/ +inv_error_t inv_register_data_cb( + inv_error_t (*func)(struct inv_sensor_cal_t *data), + int priority, int sensor_type) +{ + inv_error_t result = INV_SUCCESS; + int kk, nn; + + // Make sure we haven't registered this function already + // Or used the same priority + for (kk = 0; kk < inv_data_builder.num_cb; ++kk) { + if ((inv_data_builder.process[kk].func == func) || + (inv_data_builder.process[kk].priority == priority)) { + return INV_ERROR_INVALID_PARAMETER; //fixme give a warning + } + } + + // Make sure we have not filled up our number of allowable callbacks + if (inv_data_builder.num_cb <= INV_MAX_DATA_CB - 1) { + kk = 0; + if (inv_data_builder.num_cb != 0) { + // set kk to be where this new callback goes in the array + while ((kk < inv_data_builder.num_cb) && + (inv_data_builder.process[kk].priority < priority)) { + kk++; + } + if (kk != inv_data_builder.num_cb) { + // We need to move the others + for (nn = inv_data_builder.num_cb; nn > kk; --nn) { + inv_data_builder.process[nn] = + inv_data_builder.process[nn - 1]; + } + } + } + // Add new callback + inv_data_builder.process[kk].func = func; + inv_data_builder.process[kk].priority = priority; + inv_data_builder.process[kk].data_required = sensor_type; + inv_data_builder.num_cb++; + } else { + MPL_LOGE("Unable to add feature callback as too many were already registered\n"); + result = INV_ERROR_MEMORY_EXAUSTED; + } + + return result; +} + +/** Unregisters the callback that happens when new sensor data is received. +* @internal +* @param[in] func Function pointer to receive callback when there is new sensor data +* @param[in] priority Lower priority numbers receive a callback before larger numbers. All priority +* numbers must be unique. +* @param[in] sensor_type Sets the type of data that triggers the callback. Must be non-zero. May be +* a combination. INV_ACCEL_NEW = accel data, INV_GYRO_NEW = +* gyro data, INV_MAG_NEW = compass data. So passing in +* INV_ACCEL_NEW | INV_MAG_NEW, a +* callback would be generated if there was new magnetomer data OR new accel data. +*/ +inv_error_t inv_unregister_data_cb( + inv_error_t (*func)(struct inv_sensor_cal_t *data)) +{ + int kk, nn; + + for (kk = 0; kk < inv_data_builder.num_cb; ++kk) { + if (inv_data_builder.process[kk].func == func) { + // Delete this callback + for (nn = kk + 1; nn < inv_data_builder.num_cb; ++nn) { + inv_data_builder.process[nn - 1] = + inv_data_builder.process[nn]; + } + inv_data_builder.num_cb--; + return INV_SUCCESS; + } + } + + return INV_SUCCESS; // We did not find the callback +} + +/** After at least one of inv_build_gyro(), inv_build_accel(), or +* inv_build_compass() has been called, this function should be called. +* It will process the data it has received and update all the internal states +* and features that have been turned on. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_execute_on_data(void) +{ + inv_error_t result, first_error; + int kk; + int mode; + +#ifdef INV_PLAYBACK_DBG + if (inv_data_builder.debug_mode == RD_RECORD) { + int type = PLAYBACK_DBG_TYPE_EXECUTE; + fwrite(&type, sizeof(type), 1, inv_data_builder.file); + } +#endif + // Determine what new data we have + mode = 0; + if (sensors.gyro.status & INV_NEW_DATA) + mode |= INV_GYRO_NEW; + if (sensors.accel.status & INV_NEW_DATA) + mode |= INV_ACCEL_NEW; + if (sensors.compass.status & INV_NEW_DATA) + mode |= INV_MAG_NEW; + if (sensors.temp.status & INV_NEW_DATA) + mode |= INV_TEMP_NEW; + if (sensors.quat.status & INV_NEW_DATA) + mode |= INV_QUAT_NEW; + + first_error = INV_SUCCESS; + + for (kk = 0; kk < inv_data_builder.num_cb; ++kk) { + if (mode & inv_data_builder.process[kk].data_required) { + result = inv_data_builder.process[kk].func(&sensors); + if (result && !first_error) { + first_error = result; + } + } + } + + inv_set_contiguous(); + + return first_error; +} + +/** Cleans up status bits after running all the callbacks. It sets the contiguous flag. +* +*/ +static void inv_set_contiguous(void) +{ + inv_time_t current_time = 0; + if (sensors.gyro.status & INV_NEW_DATA) { + sensors.gyro.status |= INV_CONTIGUOUS; + current_time = sensors.gyro.timestamp; + } + if (sensors.accel.status & INV_NEW_DATA) { + sensors.accel.status |= INV_CONTIGUOUS; + current_time = MAX(current_time, sensors.accel.timestamp); + } + if (sensors.compass.status & INV_NEW_DATA) { + sensors.compass.status |= INV_CONTIGUOUS; + current_time = MAX(current_time, sensors.compass.timestamp); + } + if (sensors.temp.status & INV_NEW_DATA) { + sensors.temp.status |= INV_CONTIGUOUS; + current_time = MAX(current_time, sensors.temp.timestamp); + } + if (sensors.quat.status & INV_NEW_DATA) { + sensors.quat.status |= INV_CONTIGUOUS; + current_time = MAX(current_time, sensors.quat.timestamp); + } + +#if 0 + /* See if sensors are still on. These should be turned off by inv_*_was_turned_off() + * type functions. This is just in case that breaks down. We make sure + * all the data is within 2 seconds of the newest piece of data*/ + if (inv_delta_time_ms(current_time, sensors.gyro.timestamp) >= 2000) + inv_gyro_was_turned_off(); + if (inv_delta_time_ms(current_time, sensors.accel.timestamp) >= 2000) + inv_accel_was_turned_off(); + if (inv_delta_time_ms(current_time, sensors.compass.timestamp) >= 2000) + inv_compass_was_turned_off(); + /* TODO: Temperature might not need to be read this quickly. */ + if (inv_delta_time_ms(current_time, sensors.temp.timestamp) >= 2000) + inv_temperature_was_turned_off(); +#endif + + /* clear bits */ + sensors.gyro.status &= ~INV_NEW_DATA; + sensors.accel.status &= ~INV_NEW_DATA; + sensors.compass.status &= ~INV_NEW_DATA; + sensors.temp.status &= ~INV_NEW_DATA; + sensors.quat.status &= ~INV_NEW_DATA; +} + +/** Gets a whole set of accel data including data, accuracy and timestamp. + * @param[out] data Accel Data where 1g = 2^16 + * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. + * @param[out] timestamp The timestamp of the data sample. +*/ +void inv_get_accel_set(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + if (data != NULL) { + memcpy(data, sensors.accel.calibrated, sizeof(sensors.accel.calibrated)); + } + if (timestamp != NULL) { + *timestamp = sensors.accel.timestamp; + } + if (accuracy != NULL) { + *accuracy = sensors.accel.accuracy; + } +} + +/** Gets a whole set of gyro data including data, accuracy and timestamp. + * @param[out] data Gyro Data where 1 dps = 2^16 + * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. + * @param[out] timestamp The timestamp of the data sample. +*/ +void inv_get_gyro_set(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + memcpy(data, sensors.gyro.calibrated, sizeof(sensors.gyro.calibrated)); + if (timestamp != NULL) { + *timestamp = sensors.gyro.timestamp; + } + if (accuracy != NULL) { + *accuracy = sensors.gyro.accuracy; + } +} + +/** Gets a whole set of gyro raw data including data, accuracy and timestamp. + * @param[out] data Gyro Data where 1 dps = 2^16 + * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. + * @param[out] timestamp The timestamp of the data sample. +*/ +void inv_get_gyro_set_raw(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + memcpy(data, sensors.gyro.raw_scaled, sizeof(sensors.gyro.raw_scaled)); + if (timestamp != NULL) { + *timestamp = sensors.gyro.timestamp; + } + if (accuracy != NULL) { + *accuracy = sensors.gyro.accuracy; + } +} + +/** Get's latest gyro data. +* @param[out] gyro Gyro Data, Length 3. 1 dps = 2^16. +*/ +void inv_get_gyro(long *gyro) +{ + memcpy(gyro, sensors.gyro.calibrated, sizeof(sensors.gyro.calibrated)); +} + +/** Gets a whole set of compass data including data, accuracy and timestamp. + * @param[out] data Compass Data where 1 uT = 2^16 + * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. + * @param[out] timestamp The timestamp of the data sample. +*/ +void inv_get_compass_set(long *data, int8_t *accuracy, inv_time_t *timestamp) +{ + memcpy(data, sensors.compass.calibrated, sizeof(sensors.compass.calibrated)); + if (timestamp != NULL) { + *timestamp = sensors.compass.timestamp; + } + if (accuracy != NULL) { + if (inv_data_builder.compass_disturbance) + *accuracy = 0; + else + *accuracy = sensors.compass.accuracy; + } +} + +/** Gets a whole set of temperature data including data, accuracy and timestamp. + * @param[out] data Temperature data where 1 degree C = 2^16 + * @param[out] accuracy 0 to 3, where 3 is most accurate. + * @param[out] timestamp The timestamp of the data sample. + */ +void inv_get_temp_set(long *data, int *accuracy, inv_time_t *timestamp) +{ + data[0] = sensors.temp.calibrated[0]; + if (timestamp) + *timestamp = sensors.temp.timestamp; + if (accuracy) + *accuracy = sensors.temp.accuracy; +} + +/** Returns accuracy of gyro. + * @return Accuracy of gyro with 0 being not accurate, and 3 being most accurate. +*/ +int inv_get_gyro_accuracy(void) +{ + return sensors.gyro.accuracy; +} + +/** Returns accuracy of compass. + * @return Accuracy of compass with 0 being not accurate, and 3 being most accurate. +*/ +int inv_get_mag_accuracy(void) +{ + if (inv_data_builder.compass_disturbance) + return 0; + return sensors.compass.accuracy; +} + +/** Returns accuracy of accel. + * @return Accuracy of accel with 0 being not accurate, and 3 being most accurate. +*/ +int inv_get_accel_accuracy(void) +{ + return sensors.accel.accuracy; +} + +inv_error_t inv_get_gyro_orient(int *orient) +{ + *orient = sensors.gyro.orientation; + return 0; +} + +inv_error_t inv_get_accel_orient(int *orient) +{ + *orient = sensors.accel.orientation; + return 0; +} + +/*======================================================================*/ +/* compass soft iron module */ +/*======================================================================*/ + +/** Gets the 3x3 compass transform matrix in 32 bit Q30 fixed point format. + * @param[out] the pointer of the 3x3 matrix in Q30 format +*/ +void inv_get_compass_soft_iron_matrix_d(long *matrix) { + int i; + for (i=0; i<9; i++) { + matrix[i] = sensors.soft_iron.matrix_d[i]; + } +} + +/** Sets the 3x3 compass transform matrix in 32 bit Q30 fixed point format. + * @param[in] the pointer of the 3x3 matrix in Q30 format +*/ +void inv_set_compass_soft_iron_matrix_d(long *matrix) { + int i; + for (i=0; i<9; i++) { + // set the floating point matrix + sensors.soft_iron.matrix_d[i] = matrix[i]; + // convert to Q30 format + sensors.soft_iron.matrix_f[i] = inv_q30_to_float(matrix[i]); + } +} +/** Gets the 3x3 compass transform matrix in 32 bit floating point format. + * @param[out] the pointer of the 3x3 matrix in floating point format +*/ +void inv_get_compass_soft_iron_matrix_f(float *matrix) { + int i; + for (i=0; i<9; i++) { + matrix[i] = sensors.soft_iron.matrix_f[i]; + } +} +/** Sets the 3x3 compass transform matrix in 32 bit floating point format. + * @param[in] the pointer of the 3x3 matrix in floating point format +*/ +void inv_set_compass_soft_iron_matrix_f(float *matrix) { + int i; + for (i=0; i<9; i++) { + // set the floating point matrix + sensors.soft_iron.matrix_f[i] = matrix[i]; + // convert to Q30 format + sensors.soft_iron.matrix_d[i] = (long )(matrix[i]*ROT_MATRIX_SCALE_LONG); + } +} + +/** This subroutine gets the fixed point Q30 compass data after the soft iron transformation. + * @param[out] the pointer of the 3x1 vector compass data in MPL format +*/ +void inv_get_compass_soft_iron_output_data(long *data) { + int i; + for (i=0; i<3; i++) { + data[i] = sensors.soft_iron.trans[i]; + } +} +/** This subroutine gets the fixed point Q30 compass data before the soft iron transformation. + * @param[out] the pointer of the 3x1 vector compass data in MPL format +*/ +void inv_get_compass_soft_iron_input_data(long *data) { + int i; + for (i=0; i<3; i++) { + data[i] = sensors.soft_iron.raw[i]; + } +} +/** This subroutine sets the compass raw data for the soft iron transformation. + * @param[int] the pointer of the 3x1 vector compass raw data in MPL format +*/ +void inv_set_compass_soft_iron_input_data(const long *data) { + int i; + for (i=0; i<3; i++) { + sensors.soft_iron.raw[i] = data[i]; + } + if (sensors.soft_iron.enable == 1) { + mlMatrixVectorMult(sensors.soft_iron.matrix_d, data, sensors.soft_iron.trans); + } else { + for (i=0; i<3; i++) { + sensors.soft_iron.trans[i] = data[i]; + } + } +} + +/** This subroutine resets the the soft iron transformation to unity matrix and + * disable the soft iron transformation process by default. +*/ +void inv_reset_compass_soft_iron_matrix(void) { + int i; + for (i=0; i<9; i++) { + sensors.soft_iron.matrix_f[i] = 0.0f; + } + + memset(&sensors.soft_iron.matrix_d,0,sizeof(sensors.soft_iron.matrix_d)); + + for (i=0; i<3; i++) { + // set the floating point matrix + sensors.soft_iron.matrix_f[i*4] = 1.0; + // set the fixed point matrix + sensors.soft_iron.matrix_d[i*4] = ROT_MATRIX_SCALE_LONG; + } + + inv_disable_compass_soft_iron_matrix(); +} + +/** This subroutine enables the the soft iron transformation process. +*/ +void inv_enable_compass_soft_iron_matrix(void) { + sensors.soft_iron.enable = 1; +} + +/** This subroutine disables the the soft iron transformation process. +*/ +void inv_disable_compass_soft_iron_matrix(void) { + sensors.soft_iron.enable = 0; +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/data_builder.h b/bsp/boards/mimsy2-cc2538/mllite/data_builder.h new file mode 100644 index 0000000000..4c22767fd0 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/data_builder.h @@ -0,0 +1,259 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" + +#ifndef INV_DATA_BUILDER_H__ +#define INV_DATA_BUILDER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +// Uncomment this flag to enable playback debug and record or playback scenarios +//#define INV_PLAYBACK_DBG + +/** This is a new sample of accel data */ +#define INV_ACCEL_NEW 1 +/** This is a new sample of gyro data */ +#define INV_GYRO_NEW 2 +/** This is a new sample of compass data */ +#define INV_MAG_NEW 4 +/** This is a new sample of temperature data */ +#define INV_TEMP_NEW 8 +/** This is a new sample of quaternion data */ +#define INV_QUAT_NEW 16 + +/** Set if the data is contiguous. Typically not set if a sample was skipped */ +#define INV_CONTIGUOUS 16 +/** Set if the calibrated data has been solved for */ +#define INV_CALIBRATED 32 +/* INV_NEW_DATA set for a new set of data, cleared if not available. */ +#define INV_NEW_DATA 64 +/* Set if raw data exists */ +#define INV_RAW_DATA 128 +/* Set if the sensor is on */ +#define INV_SENSOR_ON 256 +/* Set if quaternion has bias correction applied */ +#define INV_BIAS_APPLIED 512 + +#define INV_PRIORITY_MOTION_NO_MOTION 100 +#define INV_PRIORITY_GYRO_TC 150 +#define INV_PRIORITY_QUATERNION_GYRO_ACCEL 200 +#define INV_PRIORITY_QUATERNION_NO_GYRO 250 +#define INV_PRIORITY_MAGNETIC_DISTURBANCE 300 +#define INV_PRIORITY_HEADING_FROM_GYRO 350 +#define INV_PRIORITY_COMPASS_BIAS_W_GYRO 375 +#define INV_PRIORITY_COMPASS_VECTOR_CAL 400 +#define INV_PRIORITY_COMPASS_ADV_BIAS 500 +#define INV_PRIORITY_9_AXIS_FUSION 600 +#define INV_PRIORITY_QUATERNION_ADJUST_9_AXIS 700 +#define INV_PRIORITY_QUATERNION_ACCURACY 750 +#define INV_PRIORITY_RESULTS_HOLDER 800 +#define INV_PRIORITY_INUSE_AUTO_CALIBRATION 850 +#define INV_PRIORITY_HAL_OUTPUTS 900 +#define INV_PRIORITY_GLYPH 950 +#define INV_PRIORITY_SHAKE 975 +#define INV_PRIORITY_SM 1000 + +struct inv_single_sensor_t { + /** Orientation Descriptor. Describes how to go from the mounting frame to the body frame when + * the rotation matrix could be thought of only having elements of 0,1,-1. + * 2 bits are used to describe the column of the 1 or -1 and the 3rd bit is used for the sign. + * Bit 8 is sign of +/- 1 in third row. Bit 6-7 is column of +/-1 in third row. + * Bit 5 is sign of +/- 1 in second row. Bit 3-4 is column of +/-1 in second row. + * Bit 2 is sign of +/- 1 in first row. Bit 0-1 is column of +/-1 in first row. + */ + int orientation; + /** The raw data in raw data units in the mounting frame */ + short raw[3]; + /** Raw data in body frame */ + long raw_scaled[3]; + /** Calibrated data */ + long calibrated[3]; + long sensitivity; + /** Sample rate in microseconds */ + long sample_rate_us; + long sample_rate_ms; + /** INV_CONTIGUOUS is set for contiguous data. Will not be set if there was a sample + * skipped due to power savings turning off this sensor. + * INV_NEW_DATA set for a new set of data, cleared if not available. + * INV_CALIBRATED_SET if calibrated data has been solved for */ + int status; + /** 0 to 3 for how well sensor data and biases are known. 3 is most accurate. */ + int accuracy; + inv_time_t timestamp; + inv_time_t timestamp_prev; + /** Bandwidth in Hz */ + int bandwidth; +}; +struct inv_quat_sensor_t { + long raw[4]; + /** INV_CONTIGUOUS is set for contiguous data. Will not be set if there was a sample + * skipped due to power savings turning off this sensor. + * INV_NEW_DATA set for a new set of data, cleared if not available. + * INV_CALIBRATED_SET if calibrated data has been solved for */ + int status; + inv_time_t timestamp; + long sample_rate_us; + long sample_rate_ms; +}; + +struct inv_soft_iron_t { + long raw[3]; + long trans[3]; + long matrix_d[9]; // Q30 format fixed point. The dynamic range is (-2.0 to 2.0); + float matrix_f[9]; + + int enable; +}; + +struct inv_sensor_cal_t { + struct inv_single_sensor_t gyro; + struct inv_single_sensor_t accel; + struct inv_single_sensor_t compass; + struct inv_single_sensor_t temp; + struct inv_quat_sensor_t quat; + struct inv_soft_iron_t soft_iron; + /** Combinations of INV_GYRO_NEW, INV_ACCEL_NEW, INV_MAG_NEW to indicate + * which data is a new sample as these data points may have different sample rates. + */ + int status; +}; + +// Useful for debug record and playback +typedef enum { + RD_NO_DEBUG, + RD_RECORD, + RD_PLAYBACK +} rd_dbg_mode; + +typedef enum { + PLAYBACK_DBG_TYPE_GYRO, + PLAYBACK_DBG_TYPE_ACCEL, + PLAYBACK_DBG_TYPE_COMPASS, + PLAYBACK_DBG_TYPE_TEMPERATURE, + PLAYBACK_DBG_TYPE_EXECUTE, + PLAYBACK_DBG_TYPE_A_ORIENT, + PLAYBACK_DBG_TYPE_G_ORIENT, + PLAYBACK_DBG_TYPE_C_ORIENT, + PLAYBACK_DBG_TYPE_A_SAMPLE_RATE, + PLAYBACK_DBG_TYPE_C_SAMPLE_RATE, + PLAYBACK_DBG_TYPE_G_SAMPLE_RATE, + PLAYBACK_DBG_TYPE_GYRO_OFF, + PLAYBACK_DBG_TYPE_ACCEL_OFF, + PLAYBACK_DBG_TYPE_COMPASS_OFF, + PLAYBACK_DBG_TYPE_Q_SAMPLE_RATE, + PLAYBACK_DBG_TYPE_QUAT + +} inv_rd_dbg_states; + +/** Maximum number of data callbacks that are supported. Safe to increase if needed.*/ +#define INV_MAX_DATA_CB 20 + +#ifdef INV_PLAYBACK_DBG +#include +void inv_turn_on_data_logging(FILE *file); +void inv_turn_off_data_logging(); +#endif + +void inv_set_gyro_orientation_and_scale(int orientation, long sensitivity); +void inv_set_accel_orientation_and_scale(int orientation, + long sensitivity); +void inv_set_compass_orientation_and_scale(int orientation, + long sensitivity); +void inv_set_gyro_sample_rate(long sample_rate_us); +void inv_set_compass_sample_rate(long sample_rate_us); +void inv_set_quat_sample_rate(long sample_rate_us); +void inv_set_accel_sample_rate(long sample_rate_us); +void inv_set_gyro_bandwidth(int bandwidth_hz); +void inv_set_accel_bandwidth(int bandwidth_hz); +void inv_set_compass_bandwidth(int bandwidth_hz); + +void inv_get_gyro_sample_rate_ms(long *sample_rate_ms); +void inv_get_accel_sample_rate_ms(long *sample_rate_ms); +void inv_get_compass_sample_rate_ms(long *sample_rate_ms); + +inv_error_t inv_register_data_cb(inv_error_t (*func) + (struct inv_sensor_cal_t * data), int priority, + int sensor_type); +inv_error_t inv_unregister_data_cb(inv_error_t (*func) + (struct inv_sensor_cal_t * data)); + +inv_error_t inv_build_gyro(const short *gyro, inv_time_t timestamp); +inv_error_t inv_build_compass(const long *compass, int status, + inv_time_t timestamp); +inv_error_t inv_build_accel(const long *accel, int status, + inv_time_t timestamp); +inv_error_t inv_build_temp(const long temp, inv_time_t timestamp); +inv_error_t inv_build_quat(const long *quat, int status, inv_time_t timestamp); +inv_error_t inv_execute_on_data(void); + +void inv_get_compass_bias(long *bias); + +void inv_set_compass_bias(const long *bias, int accuracy); +void inv_set_compass_disturbance(int dist); +void inv_set_gyro_bias(const long *bias, int accuracy); +void inv_set_accel_bias(const long *bias, int accuracy); +void inv_set_accel_accuracy(int accuracy); +void inv_set_accel_bias_mask(const long *bias, int accuracy, int mask); + +void inv_get_compass_soft_iron_matrix_d(long *matrix); +void inv_set_compass_soft_iron_matrix_d(long *matrix); + +void inv_get_compass_soft_iron_matrix_f(float *matrix); +void inv_set_compass_soft_iron_matrix_f(float *matrix); + +void inv_get_compass_soft_iron_output_data(long *data); +void inv_get_compass_soft_iron_input_data(long *data); +void inv_set_compass_soft_iron_input_data(const long *data); + +void inv_reset_compass_soft_iron_matrix(void); +void inv_enable_compass_soft_iron_matrix(void); +void inv_disable_compass_soft_iron_matrix(void); + +void inv_get_gyro_bias(long *bias, long *temp); +void inv_get_accel_bias(long *bias, long *temp); + +void inv_gyro_was_turned_off(void); +void inv_accel_was_turned_off(void); +void inv_compass_was_turned_off(void); +void inv_quaternion_sensor_was_turned_off(void); +inv_error_t inv_init_data_builder(void); +long inv_get_gyro_sensitivity(void); +long inv_get_accel_sensitivity(void); +long inv_get_compass_sensitivity(void); + +void inv_get_accel_set(long *data, int8_t *accuracy, inv_time_t * timestamp); +void inv_get_gyro_set(long *data, int8_t *accuracy, inv_time_t * timestamp); +void inv_get_gyro_set_raw(long *data, int8_t *accuracy, inv_time_t * timestamp); +void inv_get_compass_set(long *data, int8_t *accuracy, inv_time_t * timestamp); + +void inv_get_gyro(long *gyro); + +int inv_get_gyro_accuracy(void); +int inv_get_accel_accuracy(void); +int inv_get_mag_accuracy(void); + +int inv_get_compass_on(void); +int inv_get_gyro_on(void); +int inv_get_accel_on(void); + +inv_time_t inv_get_last_timestamp(void); +int inv_get_compass_disturbance(void); + +//New DMP Cal Functions +inv_error_t inv_get_gyro_orient(int *orient); +inv_error_t inv_get_accel_orient(int *orient); + +// internal +int inv_get_gyro_bias_tc_set(void); + +#ifdef __cplusplus +} +#endif + +#endif /* INV_DATA_BUILDER_H__ */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/hal_outputs.c b/bsp/boards/mimsy2-cc2538/mllite/hal_outputs.c new file mode 100644 index 0000000000..3b5f946a9a --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/hal_outputs.c @@ -0,0 +1,486 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/** + * @defgroup HAL_Outputs hal_outputs + * @brief Motion Library - HAL Outputs + * Sets up common outputs for HAL + * + * @{ + * @file hal_outputs.c + * @brief HAL Outputs. + */ + +#include + +#include "hal_outputs.h" +#include "log.h" +#include "ml_math_func.h" +#include "mlmath.h" +#include "start_manager.h" +#include "data_builder.h" +#include "results_holder.h" + +struct hal_output_t { + int accuracy_mag; /**< Compass accuracy */ +// int accuracy_gyro; /**< Gyro Accuracy */ +// int accuracy_accel; /**< Accel Accuracy */ + int accuracy_quat; /**< quat Accuracy */ + + inv_time_t nav_timestamp; + inv_time_t gam_timestamp; +// inv_time_t accel_timestamp; + inv_time_t mag_timestamp; + long nav_quat[4]; + int gyro_status; + int accel_status; + int compass_status; + int nine_axis_status; + inv_biquad_filter_t lp_filter[3]; + float compass_float[3]; +}; + +static struct hal_output_t hal_out; + +/** Acceleration (m/s^2) in body frame. +* @param[out] values Acceleration in m/s^2 includes gravity. So while not in motion, it +* should return a vector of magnitude near 9.81 m/s^2 +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_accel(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_accelerometer(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + int status; + /* Converts fixed point to m/s^2. Fixed point has 1g = 2^16. + * So this 9.80665 / 2^16 */ +#define ACCEL_CONVERSION 0.000149637603759766f + long accel[3]; + inv_get_accel_set(accel, accuracy, timestamp); + values[0] = accel[0] * ACCEL_CONVERSION; + values[1] = accel[1] * ACCEL_CONVERSION; + values[2] = accel[2] * ACCEL_CONVERSION; + if (hal_out.accel_status & INV_NEW_DATA) + status = 1; + else + status = 0; + return status; +} + +/** Linear Acceleration (m/s^2) in Body Frame. +* @param[out] values Linear Acceleration in body frame, length 3, (m/s^2). May show +* accel biases while at rest. +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_accel(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_linear_acceleration(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + long gravity[3], accel[3]; + + inv_get_accel_set(accel, accuracy, timestamp); + inv_get_gravity(gravity); + accel[0] -= gravity[0] >> 14; + accel[1] -= gravity[1] >> 14; + accel[2] -= gravity[2] >> 14; + values[0] = accel[0] * ACCEL_CONVERSION; + values[1] = accel[1] * ACCEL_CONVERSION; + values[2] = accel[2] * ACCEL_CONVERSION; + + return 1; +} + +/** Gravity vector (m/s^2) in Body Frame. +* @param[out] values Gravity vector in body frame, length 3, (m/s^2) +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_accel(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_gravity(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + long gravity[3]; + + *accuracy = (int8_t) hal_out.accuracy_quat; + *timestamp = hal_out.nav_timestamp; + inv_get_gravity(gravity); + values[0] = (gravity[0] >> 14) * ACCEL_CONVERSION; + values[1] = (gravity[1] >> 14) * ACCEL_CONVERSION; + values[2] = (gravity[2] >> 14) * ACCEL_CONVERSION; + + return 1; +} + +/* Converts fixed point to rad/sec. Fixed point has 1 dps = 2^16. + * So this is: pi / 2^16 / 180 */ +#define GYRO_CONVERSION 2.66316109007924e-007f + +/** Gyroscope calibrated data (rad/s) in body frame. +* @param[out] values Rotation Rate in rad/sec. +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_gyro(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_gyroscope(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + long gyro[3]; + int status; + + inv_get_gyro_set(gyro, accuracy, timestamp); + values[0] = gyro[0] * GYRO_CONVERSION; + values[1] = gyro[1] * GYRO_CONVERSION; + values[2] = gyro[2] * GYRO_CONVERSION; + if (hal_out.gyro_status & INV_NEW_DATA) + status = 1; + else + status = 0; + return status; +} + +/** Gyroscope raw data (rad/s) in body frame. +* @param[out] values Rotation Rate in rad/sec. +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to +* inv_build_gyro(). +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_gyroscope_raw(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + long gyro[3]; + int status; + + inv_get_gyro_set_raw(gyro, accuracy, timestamp); + values[0] = gyro[0] * GYRO_CONVERSION; + values[1] = gyro[1] * GYRO_CONVERSION; + values[2] = gyro[2] * GYRO_CONVERSION; + if (hal_out.gyro_status & INV_NEW_DATA) + status = 1; + else + status = 0; + return status; +} + +/** +* This corresponds to Sensor.TYPE_ROTATION_VECTOR. +* The rotation vector represents the orientation of the device as a combination +* of an angle and an axis, in which the device has rotated through an angle @f$\theta@f$ +* around an axis {x, y, z}.
+* The three elements of the rotation vector are +* {x*sin(@f$\theta@f$/2), y*sin(@f$\theta@f$/2), z*sin(@f$\theta@f$/2)}, such that the magnitude of the rotation +* vector is equal to sin(@f$\theta@f$/2), and the direction of the rotation vector is +* equal to the direction of the axis of rotation. +* +* The three elements of the rotation vector are equal to the last three components of a unit quaternion +* {x*sin(@f$\theta@f$/2), y*sin(@f$\theta@f$/2), z*sin(@f$\theta@f$/2)>. The 4th element is cos(@f$\theta@f$/2). +* +* Elements of the rotation vector are unitless. The x,y and z axis are defined in the same way as the acceleration sensor. +* The reference coordinate system is defined as a direct orthonormal basis, where: + + -X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points East). + -Y is tangential to the ground at the device's current location and points towards the magnetic North Pole. + -Z points towards the sky and is perpendicular to the ground. +* @param[out] values Length 4. +* @param[out] accuracy Accuracy 0 to 3, 3 = most accurate +* @param[out] timestamp Timestamp. In (ns) for Android. +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_rotation_vector(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + *accuracy = (int8_t) hal_out.accuracy_quat; + *timestamp = hal_out.nav_timestamp; + + if (hal_out.nav_quat[0] >= 0) { + values[0] = hal_out.nav_quat[1] * INV_TWO_POWER_NEG_30; + values[1] = hal_out.nav_quat[2] * INV_TWO_POWER_NEG_30; + values[2] = hal_out.nav_quat[3] * INV_TWO_POWER_NEG_30; + values[3] = hal_out.nav_quat[0] * INV_TWO_POWER_NEG_30; + } else { + values[0] = -hal_out.nav_quat[1] * INV_TWO_POWER_NEG_30; + values[1] = -hal_out.nav_quat[2] * INV_TWO_POWER_NEG_30; + values[2] = -hal_out.nav_quat[3] * INV_TWO_POWER_NEG_30; + values[3] = -hal_out.nav_quat[0] * INV_TWO_POWER_NEG_30; + } + values[4] = inv_get_heading_confidence_interval(); + + return hal_out.nine_axis_status; +} + +/** Compass data (uT) in body frame. +* @param[out] values Compass data in (uT), length 3. May be calibrated by having +* biases removed and sensitivity adjusted +* @param[out] accuracy Accuracy 0 to 3, 3 = most accurate +* @param[out] timestamp Timestamp. In (ns) for Android. +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_magnetic_field(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + int status; + /* Converts fixed point to uT. Fixed point has 1 uT = 2^16. + * So this is: 1 / 2^16*/ +//#define COMPASS_CONVERSION 1.52587890625e-005f + int i; + + *timestamp = hal_out.mag_timestamp; + *accuracy = (int8_t) hal_out.accuracy_mag; + + for (i=0; i<3; i++) { + values[i] = hal_out.compass_float[i]; + } + if (hal_out.compass_status & INV_NEW_DATA) + status = 1; + else + status = 0; + hal_out.compass_status = 0; + return status; +} + +static void inv_get_rotation(float r[3][3]) +{ + long rot[9]; + float conv = 1.f / (1L<<30); + + inv_quaternion_to_rotation(hal_out.nav_quat, rot); + r[0][0] = rot[0]*conv; + r[0][1] = rot[1]*conv; + r[0][2] = rot[2]*conv; + r[1][0] = rot[3]*conv; + r[1][1] = rot[4]*conv; + r[1][2] = rot[5]*conv; + r[2][0] = rot[6]*conv; + r[2][1] = rot[7]*conv; + r[2][2] = rot[8]*conv; +} + +static void google_orientation(float *g) +{ + float rad2deg = (float)(180.0 / M_PI); + float R[3][3]; + + inv_get_rotation(R); + + g[0] = atan2f(-R[1][0], R[0][0]) * rad2deg; + g[1] = atan2f(-R[2][1], R[2][2]) * rad2deg; + g[2] = asinf ( R[2][0]) * rad2deg; + if (g[0] < 0) + g[0] += 360; +} + + +/** This corresponds to Sensor.TYPE_ORIENTATION. All values are angles in degrees. +* @param[out] values Length 3, Degrees.
+* - values[0]: Azimuth, angle between the magnetic north direction +* and the y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South, 270=West
+* - values[1]: Pitch, rotation around x-axis (-180 to 180), with positive values +* when the z-axis moves toward the y-axis.
+* - values[2]: Roll, rotation around y-axis (-90 to 90), with positive +* values when the x-axis moves toward the z-axis.
+* +* @note This definition is different from yaw, pitch and roll used in aviation +* where the X axis is along the long side of the plane (tail to nose). +* Note: This sensor type exists for legacy reasons, please use getRotationMatrix() +* in conjunction with remapCoordinateSystem() and getOrientation() to compute +* these values instead. +* Important note: For historical reasons the roll angle is positive in the +* clockwise direction (mathematically speaking, it should be positive in +* the counter-clockwise direction). +* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate. +* @param[out] timestamp The timestamp for this sensor. +* @return Returns 1 if the data was updated or 0 if it was not updated. +*/ +int inv_get_sensor_type_orientation(float *values, int8_t *accuracy, + inv_time_t * timestamp) +{ + *accuracy = (int8_t) hal_out.accuracy_quat; + *timestamp = hal_out.nav_timestamp; + + google_orientation(values); + + return hal_out.nine_axis_status; +} + +/** Main callback to generate HAL outputs. Typically not called by library users. +* @param[in] sensor_cal Input variable to take sensor data whenever there is new +* sensor data. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_generate_hal_outputs(struct inv_sensor_cal_t *sensor_cal) +{ + int use_sensor = 0; + long sr = 1000; + long compass[3]; + int8_t accuracy; + int i; + (void) sensor_cal; + + inv_get_quaternion_set(hal_out.nav_quat, &hal_out.accuracy_quat, + &hal_out.nav_timestamp); + hal_out.gyro_status = sensor_cal->gyro.status; + hal_out.accel_status = sensor_cal->accel.status; + hal_out.compass_status = sensor_cal->compass.status; + + // Find the highest sample rate and tie generating 9-axis to that one. + if (sensor_cal->gyro.status & INV_SENSOR_ON) { + sr = sensor_cal->gyro.sample_rate_ms; + use_sensor = 0; + } + if ((sensor_cal->accel.status & INV_SENSOR_ON) && (sr > sensor_cal->accel.sample_rate_ms)) { + sr = sensor_cal->accel.sample_rate_ms; + use_sensor = 1; + } + if ((sensor_cal->compass.status & INV_SENSOR_ON) && (sr > sensor_cal->compass.sample_rate_ms)) { + sr = sensor_cal->compass.sample_rate_ms; + use_sensor = 2; + } + if ((sensor_cal->quat.status & INV_SENSOR_ON) && (sr > sensor_cal->quat.sample_rate_ms)) { + sr = sensor_cal->quat.sample_rate_ms; + use_sensor = 3; + } + + // Only output 9-axis if all 9 sensors are on. + if (sensor_cal->quat.status & INV_SENSOR_ON) { + // If quaternion sensor is on, gyros are not required as quaternion already has that part + if ((sensor_cal->accel.status & sensor_cal->compass.status & INV_SENSOR_ON) == 0) { + use_sensor = -1; + } + } else { + if ((sensor_cal->gyro.status & sensor_cal->accel.status & sensor_cal->compass.status & INV_SENSOR_ON) == 0) { + use_sensor = -1; + } + } + + switch (use_sensor) { + case 0: + hal_out.nine_axis_status = (sensor_cal->gyro.status & INV_NEW_DATA) ? 1 : 0; + hal_out.nav_timestamp = sensor_cal->gyro.timestamp; + break; + case 1: + hal_out.nine_axis_status = (sensor_cal->accel.status & INV_NEW_DATA) ? 1 : 0; + hal_out.nav_timestamp = sensor_cal->accel.timestamp; + break; + case 2: + hal_out.nine_axis_status = (sensor_cal->compass.status & INV_NEW_DATA) ? 1 : 0; + hal_out.nav_timestamp = sensor_cal->compass.timestamp; + break; + case 3: + hal_out.nine_axis_status = (sensor_cal->quat.status & INV_NEW_DATA) ? 1 : 0; + hal_out.nav_timestamp = sensor_cal->quat.timestamp; + break; + default: + hal_out.nine_axis_status = 0; // Don't output quaternion related info + break; + } + + /* Converts fixed point to uT. Fixed point has 1 uT = 2^16. + * So this is: 1 / 2^16*/ + #define COMPASS_CONVERSION 1.52587890625e-005f + + inv_get_compass_set(compass, &accuracy, &(hal_out.mag_timestamp) ); + hal_out.accuracy_mag = (int ) accuracy; + + for (i=0; i<3; i++) { + if ((sensor_cal->compass.status & (INV_NEW_DATA | INV_CONTIGUOUS)) == + INV_NEW_DATA ) { + // set the state variables to match output with input + inv_calc_state_to_match_output(&hal_out.lp_filter[i], (float ) compass[i]); + } + + if ((sensor_cal->compass.status & (INV_NEW_DATA | INV_RAW_DATA)) == + (INV_NEW_DATA | INV_RAW_DATA) ) { + + hal_out.compass_float[i] = inv_biquad_filter_process(&hal_out.lp_filter[i], + (float ) compass[i]) * COMPASS_CONVERSION; + + } else if ((sensor_cal->compass.status & INV_NEW_DATA) == INV_NEW_DATA ) { + hal_out.compass_float[i] = (float ) compass[i] * COMPASS_CONVERSION; + } + + } + return INV_SUCCESS; +} + +/** Turns off generation of HAL outputs. +* @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_stop_hal_outputs(void) +{ + inv_error_t result; + result = inv_unregister_data_cb(inv_generate_hal_outputs); + return result; +} + +/** Turns on generation of HAL outputs. This should be called after inv_stop_hal_outputs() +* to turn generation of HAL outputs back on. It is automatically called by inv_enable_hal_outputs(). +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_start_hal_outputs(void) +{ + inv_error_t result; + result = + inv_register_data_cb(inv_generate_hal_outputs, + INV_PRIORITY_HAL_OUTPUTS, + INV_GYRO_NEW | INV_ACCEL_NEW | INV_MAG_NEW); + return result; +} +/* file name: lowPassFilterCoeff_1_6.c */ +float compass_low_pass_filter_coeff[5] = +{+2.000000000000f, +1.000000000000f, -1.279632424998f, +0.477592250073f, +0.049489956269f}; + +/** Initializes hal outputs class. This is called automatically by the +* enable function. It may be called any time the feature is enabled, but +* is typically not needed to be called by outside callers. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_init_hal_outputs(void) +{ + int i; + memset(&hal_out, 0, sizeof(hal_out)); + for (i=0; i<3; i++) { + inv_init_biquad_filter(&hal_out.lp_filter[i], compass_low_pass_filter_coeff); + } + + return INV_SUCCESS; +} + +/** Turns on creation and storage of HAL type results. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_enable_hal_outputs(void) +{ + inv_error_t result; + + // don't need to check the result for inv_init_hal_outputs + // since it's always INV_SUCCESS + inv_init_hal_outputs(); + + result = inv_register_mpl_start_notification(inv_start_hal_outputs); + return result; +} + +/** Turns off creation and storage of HAL type results. +*/ +inv_error_t inv_disable_hal_outputs(void) +{ + inv_error_t result; + + inv_stop_hal_outputs(); // Ignore error if we have already stopped this + result = inv_unregister_mpl_start_notification(inv_start_hal_outputs); + return result; +} + +/** + * @} + */ diff --git a/bsp/boards/mimsy2-cc2538/mllite/hal_outputs.h b/bsp/boards/mimsy2-cc2538/mllite/hal_outputs.h new file mode 100644 index 0000000000..a899beb04b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/hal_outputs.h @@ -0,0 +1,45 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" + +#ifndef INV_HAL_OUTPUTS_H__ +#define INV_HAL_OUTPUTS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + int inv_get_sensor_type_orientation(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_accelerometer(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_gyroscope(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_gyroscope_raw(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_magnetic_field(float *values, int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_rotation_vector(float *values, int8_t *accuracy, + inv_time_t * timestamp); + + int inv_get_sensor_type_linear_acceleration(float *values, + int8_t *accuracy, + inv_time_t * timestamp); + int inv_get_sensor_type_gravity(float *values, int8_t *accuracy, + inv_time_t * timestamp); + + inv_error_t inv_enable_hal_outputs(void); + inv_error_t inv_disable_hal_outputs(void); + inv_error_t inv_init_hal_outputs(void); + inv_error_t inv_start_hal_outputs(void); + inv_error_t inv_stop_hal_outputs(void); + +#ifdef __cplusplus +} +#endif + +#endif // INV_HAL_OUTPUTS_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/invensense.h b/bsp/boards/mimsy2-cc2538/mllite/invensense.h new file mode 100644 index 0000000000..3453ed9615 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/invensense.h @@ -0,0 +1,28 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ + +/** + * Main header file for Invensense's basic library. + */ + +#include "data_builder.h" +#include "hal_outputs.h" +#include "message_layer.h" +#include "mlmath.h" +#include "ml_math_func.h" +#include "mpl.h" +#include "results_holder.h" +#include "start_manager.h" +#include "storage_manager.h" +#include "log.h" +#include "mlinclude.h" +//#include "..\HAL\include\mlos.h" \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/message_layer.c b/bsp/boards/mimsy2-cc2538/mllite/message_layer.c new file mode 100644 index 0000000000..d266d80ff7 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/message_layer.c @@ -0,0 +1,59 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @defgroup Message_Layer message_layer + * @brief Motion Library - Message Layer + * Holds Low Occurance messages + * + * @{ + * @file message_layer.c + * @brief Holds Low Occurance Messages. + */ +#include "message_layer.h" +#include "log.h" + +struct message_holder_t { + long message; +}; + +static struct message_holder_t mh; + +/** Sets a message. +* @param[in] set The flags to set. +* @param[in] clear Before setting anything this will clear these messages, +* which is useful for mutually exclusive messages such +* a motion or no motion message. +* @param[in] level Level of the messages. It starts at 0, and may increase +* in the future to allow more messages if the bit storage runs out. +*/ +void inv_set_message(long set, long clear, int level) +{ + if (level == 0) { + mh.message &= ~clear; + mh.message |= set; + } +} + +/** Returns Message Flags for Level 0 Messages. +* Levels are to allow expansion of more messages in the future. +* @param[in] clear If set, will clear the message. Typically this will be set +* for one reader, so that you don't get the same message over and over. +* @return bit field to corresponding message. +*/ +long inv_get_message_level_0(int clear) +{ + long msg; + msg = mh.message; + if (clear) { + mh.message = 0; + } + return msg; +} + +/** + * @} + */ diff --git a/bsp/boards/mimsy2-cc2538/mllite/message_layer.h b/bsp/boards/mimsy2-cc2538/mllite/message_layer.h new file mode 100644 index 0000000000..e6d90d5357 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/message_layer.h @@ -0,0 +1,35 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INV_MESSAGE_LAYER_H__ +#define INV_MESSAGE_LAYER_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* Level 0 Type Messages */ + /** A motion event has occured */ +#define INV_MSG_MOTION_EVENT (0x01) + /** A no motion event has occured */ +#define INV_MSG_NO_MOTION_EVENT (0x02) + /** A setting of the gyro bias has occured */ +#define INV_MSG_NEW_GB_EVENT (0x04) + /** A setting of the compass bias has occured */ +#define INV_MSG_NEW_CB_EVENT (0x08) + /** A setting of the accel bias has occured */ +#define INV_MSG_NEW_AB_EVENT (0x10) + + void inv_set_message(long set, long clear, int level); + long inv_get_message_level_0(int clear); + +#ifdef __cplusplus +} +#endif + +#endif // INV_MESSAGE_LAYER_H__ diff --git a/bsp/boards/mimsy2-cc2538/mllite/ml_math_func.c b/bsp/boards/mimsy2-cc2538/mllite/ml_math_func.c new file mode 100644 index 0000000000..7f1c5d6e48 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/ml_math_func.c @@ -0,0 +1,781 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ + +/** + * @defgroup ML_MATH_FUNC ml_math_func + * @brief Motion Library - Math Functions + * Common math functions the Motion Library + * + * @{ + * @file ml_math_func.c + * @brief Math Functions. + */ + +#include "mlmath.h" +#include "ml_math_func.h" +#include "mlinclude.h" +#include +#include + +#ifdef EMPL +#define TABLE_SIZE (256) + +/* TODO: If memory becomes a big issue, we can just store the data for a single + * quadrant and transform the inputs and outputs of the lookup functions. + */ +const float sin_lookup[TABLE_SIZE] = { + 0.000000f, 0.024541f, 0.049068f, 0.073565f, 0.098017f, 0.122411f, 0.146730f, 0.170962f, + 0.195090f, 0.219101f, 0.242980f, 0.266713f, 0.290285f, 0.313682f, 0.336890f, 0.359895f, + 0.382683f, 0.405241f, 0.427555f, 0.449611f, 0.471397f, 0.492898f, 0.514103f, 0.534998f, + 0.555570f, 0.575808f, 0.595699f, 0.615232f, 0.634393f, 0.653173f, 0.671559f, 0.689541f, + 0.707107f, 0.724247f, 0.740951f, 0.757209f, 0.773010f, 0.788346f, 0.803208f, 0.817585f, + 0.831470f, 0.844854f, 0.857729f, 0.870087f, 0.881921f, 0.893224f, 0.903989f, 0.914210f, + 0.923880f, 0.932993f, 0.941544f, 0.949528f, 0.956940f, 0.963776f, 0.970031f, 0.975702f, + 0.980785f, 0.985278f, 0.989177f, 0.992480f, 0.995185f, 0.997290f, 0.998795f, 0.999699f, + 1.000000f, 0.999699f, 0.998795f, 0.997290f, 0.995185f, 0.992480f, 0.989177f, 0.985278f, + 0.980785f, 0.975702f, 0.970031f, 0.963776f, 0.956940f, 0.949528f, 0.941544f, 0.932993f, + 0.923880f, 0.914210f, 0.903989f, 0.893224f, 0.881921f, 0.870087f, 0.857729f, 0.844854f, + 0.831470f, 0.817585f, 0.803208f, 0.788346f, 0.773010f, 0.757209f, 0.740951f, 0.724247f, + 0.707107f, 0.689541f, 0.671559f, 0.653173f, 0.634393f, 0.615232f, 0.595699f, 0.575808f, + 0.555570f, 0.534998f, 0.514103f, 0.492898f, 0.471397f, 0.449611f, 0.427555f, 0.405241f, + 0.382683f, 0.359895f, 0.336890f, 0.313682f, 0.290285f, 0.266713f, 0.242980f, 0.219101f, + 0.195091f, 0.170962f, 0.146731f, 0.122411f, 0.098017f, 0.073565f, 0.049068f, 0.024541f, + 0.000000f, -0.024541f, -0.049067f, -0.073564f, -0.098017f, -0.122411f, -0.146730f, -0.170962f, + -0.195090f, -0.219101f, -0.242980f, -0.266713f, -0.290284f, -0.313682f, -0.336890f, -0.359895f, + -0.382683f, -0.405241f, -0.427555f, -0.449611f, -0.471397f, -0.492898f, -0.514103f, -0.534997f, + -0.555570f, -0.575808f, -0.595699f, -0.615231f, -0.634393f, -0.653173f, -0.671559f, -0.689540f, + -0.707107f, -0.724247f, -0.740951f, -0.757209f, -0.773010f, -0.788346f, -0.803207f, -0.817585f, + -0.831469f, -0.844853f, -0.857729f, -0.870087f, -0.881921f, -0.893224f, -0.903989f, -0.914210f, + -0.923880f, -0.932993f, -0.941544f, -0.949528f, -0.956940f, -0.963776f, -0.970031f, -0.975702f, + -0.980785f, -0.985278f, -0.989176f, -0.992480f, -0.995185f, -0.997290f, -0.998795f, -0.999699f, + -1.000000f, -0.999699f, -0.998795f, -0.997290f, -0.995185f, -0.992480f, -0.989177f, -0.985278f, + -0.980785f, -0.975702f, -0.970031f, -0.963776f, -0.956940f, -0.949528f, -0.941544f, -0.932993f, + -0.923880f, -0.914210f, -0.903989f, -0.893224f, -0.881921f, -0.870087f, -0.857729f, -0.844854f, + -0.831470f, -0.817585f, -0.803208f, -0.788347f, -0.773011f, -0.757209f, -0.740951f, -0.724247f, + -0.707107f, -0.689541f, -0.671559f, -0.653173f, -0.634394f, -0.615232f, -0.595699f, -0.575808f, + -0.555570f, -0.534998f, -0.514103f, -0.492898f, -0.471397f, -0.449612f, -0.427555f, -0.405241f, + -0.382684f, -0.359895f, -0.336890f, -0.313682f, -0.290285f, -0.266713f, -0.242981f, -0.219102f, + -0.195091f, -0.170962f, -0.146731f, -0.122411f, -0.098017f, -0.073565f, -0.049068f, -0.024542f +}; + +float inv_sinf(float x) +{ + int index = (unsigned int)((x * (TABLE_SIZE>>1)) / 3.14159f) % TABLE_SIZE; + return sin_lookup[index]; +} + +float inv_cosf(float x) +{ + int index = ((unsigned int)((x * (TABLE_SIZE>>1)) / 3.14159f) + (TABLE_SIZE>>2)) % TABLE_SIZE; + return sin_lookup[index]; +} +#endif + +/** @internal + * Does the cross product of compass by gravity, then converts that + * to the world frame using the quaternion, then computes the angle that + * is made. + * + * @param[in] compass Compass Vector (Body Frame), length 3 + * @param[in] grav Gravity Vector (Body Frame), length 3 + * @param[in] quat Quaternion, Length 4 + * @return Angle Cross Product makes after quaternion rotation. + */ +float inv_compass_angle(const long *compass, const long *grav, const long *quat) +{ + long cgcross[4], q1[4], q2[4], qi[4]; + float angW; + + // Compass cross Gravity + cgcross[0] = 0L; + cgcross[1] = inv_q30_mult(compass[1], grav[2]) - inv_q30_mult(compass[2], grav[1]); + cgcross[2] = inv_q30_mult(compass[2], grav[0]) - inv_q30_mult(compass[0], grav[2]); + cgcross[3] = inv_q30_mult(compass[0], grav[1]) - inv_q30_mult(compass[1], grav[0]); + + // Now convert cross product into world frame + inv_q_mult(quat, cgcross, q1); + inv_q_invert(quat, qi); + inv_q_mult(q1, qi, q2); + + // Protect against atan2 of 0,0 + if ((q2[2] == 0L) && (q2[1] == 0L)) + return 0.f; + + // This is the unfiltered heading correction + angW = -atan2f(inv_q30_to_float(q2[2]), inv_q30_to_float(q2[1])); + return angW; +} + +/** + * @brief The gyro data magnitude squared : + * (1 degree per second)^2 = 2^6 = 2^GYRO_MAG_SQR_SHIFT. + * @param[in] gyro Gyro data scaled with 1 dps = 2^16 + * @return the computed magnitude squared output of the gyroscope. + */ +unsigned long inv_get_gyro_sum_of_sqr(const long *gyro) +{ + unsigned long gmag = 0; + long temp; + int kk; + + for (kk = 0; kk < 3; ++kk) { + temp = gyro[kk] >> (16 - (GYRO_MAG_SQR_SHIFT / 2)); + gmag += temp * temp; + } + + return gmag; +} + +/** Performs a multiply and shift by 29. These are good functions to write in assembly on + * with devices with small memory where you want to get rid of the long long which some + * assemblers don't handle well + * @param[in] a + * @param[in] b + * @return ((long long)a*b)>>29 +*/ +long inv_q29_mult(long a, long b) +{ +#ifdef EMPL_NO_64BIT + long result; + result = (long)((float)a * b / (1L << 29)); + return result; +#else + long long temp; + long result; + temp = (long long)a * b; + result = (long)(temp >> 29); + return result; +#endif +} + +/** Performs a multiply and shift by 30. These are good functions to write in assembly on + * with devices with small memory where you want to get rid of the long long which some + * assemblers don't handle well + * @param[in] a + * @param[in] b + * @return ((long long)a*b)>>30 +*/ +long inv_q30_mult(long a, long b) +{ +#ifdef EMPL_NO_64BIT + long result; + result = (long)((float)a * b / (1L << 30)); + return result; +#else + long long temp; + long result; + temp = (long long)a * b; + result = (long)(temp >> 30); + return result; +#endif +} + +#ifndef EMPL_NO_64BIT +long inv_q30_div(long a, long b) +{ + long long temp; + long result; + temp = (((long long)a) << 30) / b; + result = (long)temp; + return result; +} +#endif + +/** Performs a multiply and shift by shift. These are good functions to write + * in assembly on with devices with small memory where you want to get rid of + * the long long which some assemblers don't handle well + * @param[in] a First multicand + * @param[in] b Second multicand + * @param[in] shift Shift amount after multiplying + * @return ((long long)a*b)<> shift); + return result; +} +#endif + +/** Performs a fixed point quaternion multiply. +* @param[in] q1 First Quaternion Multicand, length 4. 1.0 scaled +* to 2^30 +* @param[in] q2 Second Quaternion Multicand, length 4. 1.0 scaled +* to 2^30 +* @param[out] qProd Product after quaternion multiply. Length 4. +* 1.0 scaled to 2^30. +*/ +void inv_q_mult(const long *q1, const long *q2, long *qProd) +{ + INVENSENSE_FUNC_START; + qProd[0] = inv_q30_mult(q1[0], q2[0]) - inv_q30_mult(q1[1], q2[1]) - + inv_q30_mult(q1[2], q2[2]) - inv_q30_mult(q1[3], q2[3]); + + qProd[1] = inv_q30_mult(q1[0], q2[1]) + inv_q30_mult(q1[1], q2[0]) + + inv_q30_mult(q1[2], q2[3]) - inv_q30_mult(q1[3], q2[2]); + + qProd[2] = inv_q30_mult(q1[0], q2[2]) - inv_q30_mult(q1[1], q2[3]) + + inv_q30_mult(q1[2], q2[0]) + inv_q30_mult(q1[3], q2[1]); + + qProd[3] = inv_q30_mult(q1[0], q2[3]) + inv_q30_mult(q1[1], q2[2]) - + inv_q30_mult(q1[2], q2[1]) + inv_q30_mult(q1[3], q2[0]); +} + +/** Performs a fixed point quaternion addition. +* @param[in] q1 First Quaternion term, length 4. 1.0 scaled +* to 2^30 +* @param[in] q2 Second Quaternion term, length 4. 1.0 scaled +* to 2^30 +* @param[out] qSum Sum after quaternion summation. Length 4. +* 1.0 scaled to 2^30. +*/ +void inv_q_add(long *q1, long *q2, long *qSum) +{ + INVENSENSE_FUNC_START; + qSum[0] = q1[0] + q2[0]; + qSum[1] = q1[1] + q2[1]; + qSum[2] = q1[2] + q2[2]; + qSum[3] = q1[3] + q2[3]; +} + +void inv_vector_normalize(long *vec, int length) +{ + INVENSENSE_FUNC_START; + double normSF = 0; + int ii; + for (ii = 0; ii < length; ii++) { + normSF += + inv_q30_to_double(vec[ii]) * inv_q30_to_double(vec[ii]); + } + if (normSF > 0) { + normSF = 1 / sqrt(normSF); + for (ii = 0; ii < length; ii++) { + vec[ii] = (int)((double)vec[ii] * normSF); + } + } else { + vec[0] = 1073741824L; + for (ii = 1; ii < length; ii++) { + vec[ii] = 0; + } + } +} + +void inv_q_normalize(long *q) +{ + INVENSENSE_FUNC_START; + inv_vector_normalize(q, 4); +} + +void inv_q_invert(const long *q, long *qInverted) +{ + INVENSENSE_FUNC_START; + qInverted[0] = q[0]; + qInverted[1] = -q[1]; + qInverted[2] = -q[2]; + qInverted[3] = -q[3]; +} + +double quaternion_to_rotation_angle(const long *quat) { + double quat0 = (double )quat[0] / 1073741824; + if (quat0 > 1.0f) { + quat0 = 1.0; + } else if (quat0 < -1.0f) { + quat0 = -1.0; + } + + return acos(quat0)*2*180/M_PI; +} + +/** Rotates a 3-element vector by Rotation defined by Q +*/ +void inv_q_rotate(const long *q, const long *in, long *out) +{ + long q_temp1[4], q_temp2[4]; + long in4[4], out4[4]; + + // Fixme optimize + in4[0] = 0; + memcpy(&in4[1], in, 3 * sizeof(long)); + inv_q_mult(q, in4, q_temp1); + inv_q_invert(q, q_temp2); + inv_q_mult(q_temp1, q_temp2, out4); + memcpy(out, &out4[1], 3 * sizeof(long)); +} + +void inv_q_multf(const float *q1, const float *q2, float *qProd) +{ + INVENSENSE_FUNC_START; + qProd[0] = + (q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]); + qProd[1] = + (q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]); + qProd[2] = + (q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]); + qProd[3] = + (q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0]); +} + +void inv_q_addf(const float *q1, const float *q2, float *qSum) +{ + INVENSENSE_FUNC_START; + qSum[0] = q1[0] + q2[0]; + qSum[1] = q1[1] + q2[1]; + qSum[2] = q1[2] + q2[2]; + qSum[3] = q1[3] + q2[3]; +} + +void inv_q_normalizef(float *q) +{ + INVENSENSE_FUNC_START; + float normSF = 0; + float xHalf = 0; + normSF = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + if (normSF < 2) { + xHalf = 0.5f * normSF; + normSF = normSF * (1.5f - xHalf * normSF * normSF); + normSF = normSF * (1.5f - xHalf * normSF * normSF); + normSF = normSF * (1.5f - xHalf * normSF * normSF); + normSF = normSF * (1.5f - xHalf * normSF * normSF); + q[0] *= normSF; + q[1] *= normSF; + q[2] *= normSF; + q[3] *= normSF; + } else { + q[0] = 1.0; + q[1] = 0.0; + q[2] = 0.0; + q[3] = 0.0; + } + normSF = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); +} + +/** Performs a length 4 vector normalization with a square root. +* @param[in,out] q vector to normalize. Returns [1,0,0,0] is magnitude is zero. +*/ +void inv_q_norm4(float *q) +{ + float mag; + mag = sqrtf(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + if (mag) { + q[0] /= mag; + q[1] /= mag; + q[2] /= mag; + q[3] /= mag; + } else { + q[0] = 1.f; + q[1] = 0.f; + q[2] = 0.f; + q[3] = 0.f; + } +} + +void inv_q_invertf(const float *q, float *qInverted) +{ + INVENSENSE_FUNC_START; + qInverted[0] = q[0]; + qInverted[1] = -q[1]; + qInverted[2] = -q[2]; + qInverted[3] = -q[3]; +} + +/** + * Converts a quaternion to a rotation matrix. + * @param[in] quat 4-element quaternion in fixed point. One is 2^30. + * @param[out] rot Rotation matrix in fixed point. One is 2^30. The + * First 3 elements of the rotation matrix, represent + * the first row of the matrix. Rotation matrix multiplied + * by a 3 element column vector transform a vector from Body + * to World. + */ +void inv_quaternion_to_rotation(const long *quat, long *rot) +{ + rot[0] = + inv_q29_mult(quat[1], quat[1]) + inv_q29_mult(quat[0], + quat[0]) - + 1073741824L; + rot[1] = + inv_q29_mult(quat[1], quat[2]) - inv_q29_mult(quat[3], quat[0]); + rot[2] = + inv_q29_mult(quat[1], quat[3]) + inv_q29_mult(quat[2], quat[0]); + rot[3] = + inv_q29_mult(quat[1], quat[2]) + inv_q29_mult(quat[3], quat[0]); + rot[4] = + inv_q29_mult(quat[2], quat[2]) + inv_q29_mult(quat[0], + quat[0]) - + 1073741824L; + rot[5] = + inv_q29_mult(quat[2], quat[3]) - inv_q29_mult(quat[1], quat[0]); + rot[6] = + inv_q29_mult(quat[1], quat[3]) - inv_q29_mult(quat[2], quat[0]); + rot[7] = + inv_q29_mult(quat[2], quat[3]) + inv_q29_mult(quat[1], quat[0]); + rot[8] = + inv_q29_mult(quat[3], quat[3]) + inv_q29_mult(quat[0], + quat[0]) - + 1073741824L; +} + +/** + * Converts a quaternion to a rotation vector. A rotation vector is + * a method to represent a 4-element quaternion vector in 3-elements. + * To get the quaternion from the 3-elements, The last 3-elements of + * the quaternion will be the given rotation vector. The first element + * of the quaternion will be the positive value that will be required + * to make the magnitude of the quaternion 1.0 or 2^30 in fixed point units. + * @param[in] quat 4-element quaternion in fixed point. One is 2^30. + * @param[out] rot Rotation vector in fixed point. One is 2^30. + */ +void inv_quaternion_to_rotation_vector(const long *quat, long *rot) +{ + rot[0] = quat[1]; + rot[1] = quat[2]; + rot[2] = quat[3]; + + if (quat[0] < 0.0) { + rot[0] = -rot[0]; + rot[1] = -rot[1]; + rot[2] = -rot[2]; + } +} + +/** Converts a 32-bit long to a big endian byte stream */ +unsigned char *inv_int32_to_big8(long x, unsigned char *big8) +{ + big8[0] = (unsigned char)((x >> 24) & 0xff); + big8[1] = (unsigned char)((x >> 16) & 0xff); + big8[2] = (unsigned char)((x >> 8) & 0xff); + big8[3] = (unsigned char)(x & 0xff); + return big8; +} + +/** Converts a big endian byte stream into a 32-bit long */ +long inv_big8_to_int32(const unsigned char *big8) +{ + long x; + x = ((long)big8[0] << 24) | ((long)big8[1] << 16) | ((long)big8[2] << 8) + | ((long)big8[3]); + return x; +} + +/** Converts a big endian byte stream into a 16-bit integer (short) */ +short inv_big8_to_int16(const unsigned char *big8) +{ + short x; + x = ((short)big8[0] << 8) | ((short)big8[1]); + return x; +} + +/** Converts a little endian byte stream into a 16-bit integer (short) */ +short inv_little8_to_int16(const unsigned char *little8) +{ + short x; + x = ((short)little8[1] << 8) | ((short)little8[0]); + return x; +} + +/** Converts a 16-bit short to a big endian byte stream */ +unsigned char *inv_int16_to_big8(short x, unsigned char *big8) +{ + big8[0] = (unsigned char)((x >> 8) & 0xff); + big8[1] = (unsigned char)(x & 0xff); + return big8; +} + +void inv_matrix_det_inc(float *a, float *b, int *n, int x, int y) +{ + int k, l, i, j; + for (i = 0, k = 0; i < *n; i++, k++) { + for (j = 0, l = 0; j < *n; j++, l++) { + if (i == x) + i++; + if (j == y) + j++; + *(b + 6 * k + l) = *(a + 6 * i + j); + } + } + *n = *n - 1; +} + +void inv_matrix_det_incd(double *a, double *b, int *n, int x, int y) +{ + int k, l, i, j; + for (i = 0, k = 0; i < *n; i++, k++) { + for (j = 0, l = 0; j < *n; j++, l++) { + if (i == x) + i++; + if (j == y) + j++; + *(b + 6 * k + l) = *(a + 6 * i + j); + } + } + *n = *n - 1; +} + +float inv_matrix_det(float *p, int *n) +{ + float d[6][6], sum = 0; + int i, j, m; + m = *n; + if (*n == 2) + return (*p ** (p + 7) - *(p + 1) ** (p + 6)); + for (i = 0, j = 0; j < m; j++) { + *n = m; + inv_matrix_det_inc(p, &d[0][0], n, i, j); + sum = + sum + *(p + 6 * i + j) * SIGNM(i + + j) * + inv_matrix_det(&d[0][0], n); + } + + return (sum); +} + +double inv_matrix_detd(double *p, int *n) +{ + double d[6][6], sum = 0; + int i, j, m; + m = *n; + if (*n == 2) + return (*p ** (p + 7) - *(p + 1) ** (p + 6)); + for (i = 0, j = 0; j < m; j++) { + *n = m; + inv_matrix_det_incd(p, &d[0][0], n, i, j); + sum = + sum + *(p + 6 * i + j) * SIGNM(i + + j) * + inv_matrix_detd(&d[0][0], n); + } + + return (sum); +} + +/** Wraps angle from (-M_PI,M_PI] + * @param[in] ang Angle in radians to wrap + * @return Wrapped angle from (-M_PI,M_PI] + */ +float inv_wrap_angle(float ang) +{ + if (ang > M_PI) + return ang - 2 * (float)M_PI; + else if (ang <= -(float)M_PI) + return ang + 2 * (float)M_PI; + else + return ang; +} + +/** Finds the minimum angle difference ang1-ang2 such that difference + * is between [-M_PI,M_PI] + * @param[in] ang1 + * @param[in] ang2 + * @return angle difference ang1-ang2 + */ +float inv_angle_diff(float ang1, float ang2) +{ + float d; + ang1 = inv_wrap_angle(ang1); + ang2 = inv_wrap_angle(ang2); + d = ang1 - ang2; + if (d > M_PI) + d -= 2 * (float)M_PI; + else if (d < -(float)M_PI) + d += 2 * (float)M_PI; + return d; +} + +/** bernstein hash, derived from public domain source */ +uint32_t inv_checksum(const unsigned char *str, int len) +{ + uint32_t hash = 5381; + int i, c; + + for (i = 0; i < len; i++) { + c = *(str + i); + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + } + + return hash; +} + +static unsigned short inv_row_2_scale(const signed char *row) +{ + unsigned short b; + + if (row[0] > 0) + b = 0; + else if (row[0] < 0) + b = 4; + else if (row[1] > 0) + b = 1; + else if (row[1] < 0) + b = 5; + else if (row[2] > 0) + b = 2; + else if (row[2] < 0) + b = 6; + else + b = 7; // error + return b; +} + + +/** Converts an orientation matrix made up of 0,+1,and -1 to a scalar representation. +* @param[in] mtx Orientation matrix to convert to a scalar. +* @return Description of orientation matrix. The lowest 2 bits (0 and 1) represent the column the one is on for the +* first row, with the bit number 2 being the sign. The next 2 bits (3 and 4) represent +* the column the one is on for the second row with bit number 5 being the sign. +* The next 2 bits (6 and 7) represent the column the one is on for the third row with +* bit number 8 being the sign. In binary the identity matrix would therefor be: +* 010_001_000 or 0x88 in hex. +*/ +unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx) +{ + + unsigned short scalar; + + /* + XYZ 010_001_000 Identity Matrix + XZY 001_010_000 + YXZ 010_000_001 + YZX 000_010_001 + ZXY 001_000_010 + ZYX 000_001_010 + */ + + scalar = inv_row_2_scale(mtx); + scalar |= inv_row_2_scale(mtx + 3) << 3; + scalar |= inv_row_2_scale(mtx + 6) << 6; + + + return scalar; +} + +/** Uses the scalar orientation value to convert from chip frame to body frame +* @param[in] orientation A scalar that represent how to go from chip to body frame +* @param[in] input Input vector, length 3 +* @param[out] output Output vector, length 3 +*/ +void inv_convert_to_body(unsigned short orientation, const long *input, long *output) +{ + output[0] = input[orientation & 0x03] * SIGNSET(orientation & 0x004); + output[1] = input[(orientation>>3) & 0x03] * SIGNSET(orientation & 0x020); + output[2] = input[(orientation>>6) & 0x03] * SIGNSET(orientation & 0x100); +} + +/** Uses the scalar orientation value to convert from body frame to chip frame +* @param[in] orientation A scalar that represent how to go from chip to body frame +* @param[in] input Input vector, length 3 +* @param[out] output Output vector, length 3 +*/ +void inv_convert_to_chip(unsigned short orientation, const long *input, long *output) +{ + output[orientation & 0x03] = input[0] * SIGNSET(orientation & 0x004); + output[(orientation>>3) & 0x03] = input[1] * SIGNSET(orientation & 0x020); + output[(orientation>>6) & 0x03] = input[2] * SIGNSET(orientation & 0x100); +} + + +/** Uses the scalar orientation value to convert from chip frame to body frame and +* apply appropriate scaling. +* @param[in] orientation A scalar that represent how to go from chip to body frame +* @param[in] sensitivity Sensitivity scale +* @param[in] input Input vector, length 3 +* @param[out] output Output vector, length 3 +*/ +void inv_convert_to_body_with_scale(unsigned short orientation, long sensitivity, const long *input, long *output) +{ + output[0] = inv_q30_mult(input[orientation & 0x03] * + SIGNSET(orientation & 0x004), sensitivity); + output[1] = inv_q30_mult(input[(orientation>>3) & 0x03] * + SIGNSET(orientation & 0x020), sensitivity); + output[2] = inv_q30_mult(input[(orientation>>6) & 0x03] * + SIGNSET(orientation & 0x100), sensitivity); +} + +/** find a norm for a vector +* @param[in] a vector [3x1] +* @param[out] output the norm of the input vector +*/ +double inv_vector_norm(const float *x) +{ + return sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]); +} + +void inv_init_biquad_filter(inv_biquad_filter_t *pFilter, float *pBiquadCoeff) { + int i; + // initial state to zero + pFilter->state[0] = 0; + pFilter->state[1] = 0; + + // set up coefficients + for (i=0; i<5; i++) { + pFilter->c[i] = pBiquadCoeff[i]; + } +} + +void inv_calc_state_to_match_output(inv_biquad_filter_t *pFilter, float input) +{ + pFilter->input = input; + pFilter->output = input; + pFilter->state[0] = input / (1 + pFilter->c[2] + pFilter->c[3]); + pFilter->state[1] = pFilter->state[0]; +} + +float inv_biquad_filter_process(inv_biquad_filter_t *pFilter, float input) { + float stateZero; + + pFilter->input = input; + // calculate the new state; + stateZero = pFilter->input - pFilter->c[2]*pFilter->state[0] + - pFilter->c[3]*pFilter->state[1]; + + pFilter->output = stateZero + pFilter->c[0]*pFilter->state[0] + + pFilter->c[1]*pFilter->state[1]; + + // update the output and state + pFilter->output = pFilter->output * pFilter->c[4]; + pFilter->state[1] = pFilter->state[0]; + pFilter->state[0] = stateZero; + return pFilter->output; +} + +void inv_get_cross_product_vec(float *cgcross, float compass[3], float grav[3]) { + + cgcross[0] = (float)compass[1] * grav[2] - (float)compass[2] * grav[1]; + cgcross[1] = (float)compass[2] * grav[0] - (float)compass[0] * grav[2]; + cgcross[2] = (float)compass[0] * grav[1] - (float)compass[1] * grav[0]; +} + +void mlMatrixVectorMult(long matrix[9], const long vecIn[3], long *vecOut) { + // matrix format + // [ 0 3 6; + // 1 4 7; + // 2 5 8] + + // vector format: [0 1 2]^T; + int i, j; + long temp; + + for (i=0; i<3; i++) { + temp = 0; + for (j=0; j<3; j++) { + temp += inv_q30_mult(matrix[i+j*3], vecIn[j]); + } + vecOut[i] = temp; + } +} + + +/** + * @} + */ diff --git a/bsp/boards/mimsy2-cc2538/mllite/ml_math_func.h b/bsp/boards/mimsy2-cc2538/mllite/ml_math_func.h new file mode 100644 index 0000000000..66d271b0f9 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/ml_math_func.h @@ -0,0 +1,132 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INVENSENSE_INV_MATH_FUNC_H__ +#define INVENSENSE_INV_MATH_FUNC_H__ + +#include "mltypes.h" + +#define GYRO_MAG_SQR_SHIFT 6 +#define NUM_ROTATION_MATRIX_ELEMENTS (9) +#define ROT_MATRIX_SCALE_LONG (1073741824L) +#define ROT_MATRIX_SCALE_FLOAT (1073741824.0f) +#define ROT_MATRIX_LONG_TO_FLOAT( longval ) \ + ((float) ((longval) / ROT_MATRIX_SCALE_FLOAT )) +#define SIGNM(k)((int)(k)&1?-1:1) +#define SIGNSET(x) ((x) ? -1 : +1) + +#define INV_TWO_POWER_NEG_30 9.313225746154785e-010f + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct { + float state[4]; + float c[5]; + float input; + float output; + } inv_biquad_filter_t; + + static inline float inv_q30_to_float(long q30) + { + return (float) q30 / ((float)(1L << 30)); + } + + static inline double inv_q30_to_double(long q30) + { + return (double) q30 / ((double)(1L << 30)); + } + + static inline float inv_q16_to_float(long q16) + { + return (float) q16 / (1L << 16); + } + + static inline double inv_q16_to_double(long q16) + { + return (double) q16 / (1L << 16); + } + + + + + long inv_q29_mult(long a, long b); + long inv_q30_mult(long a, long b); + + /* UMPL_ELIMINATE_64BIT Notes: + * An alternate implementation using float instead of long long accudoublemulators + * is provided for q29_mult and q30_mult. + * When long long accumulators are used and an alternate implementation is not + * available, we eliminate the entire function and header with a macro. + */ +#ifndef UMPL_ELIMINATE_64BIT + long inv_q30_div(long a, long b); + long inv_q_shift_mult(long a, long b, int shift); +#endif + + void inv_q_mult(const long *q1, const long *q2, long *qProd); + void inv_q_add(long *q1, long *q2, long *qSum); + void inv_q_normalize(long *q); + void inv_q_invert(const long *q, long *qInverted); + void inv_q_multf(const float *q1, const float *q2, float *qProd); + void inv_q_addf(const float *q1, const float *q2, float *qSum); + void inv_q_normalizef(float *q); + void inv_q_norm4(float *q); + void inv_q_invertf(const float *q, float *qInverted); + void inv_quaternion_to_rotation(const long *quat, long *rot); + unsigned char *inv_int32_to_big8(long x, unsigned char *big8); + long inv_big8_to_int32(const unsigned char *big8); + short inv_big8_to_int16(const unsigned char *big8); + short inv_little8_to_int16(const unsigned char *little8); + unsigned char *inv_int16_to_big8(short x, unsigned char *big8); + float inv_matrix_det(float *p, int *n); + void inv_matrix_det_inc(float *a, float *b, int *n, int x, int y); + double inv_matrix_detd(double *p, int *n); + void inv_matrix_det_incd(double *a, double *b, int *n, int x, int y); + float inv_wrap_angle(float ang); + float inv_angle_diff(float ang1, float ang2); + void inv_quaternion_to_rotation_vector(const long *quat, long *rot); + unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx); + void inv_convert_to_body(unsigned short orientation, const long *input, long *output); + void inv_convert_to_chip(unsigned short orientation, const long *input, long *output); + void inv_convert_to_body_with_scale(unsigned short orientation, long sensitivity, const long *input, long *output); + void inv_q_rotate(const long *q, const long *in, long *out); + void inv_vector_normalize(long *vec, int length); + uint32_t inv_checksum(const unsigned char *str, int len); + float inv_compass_angle(const long *compass, const long *grav, + const long *quat); + unsigned long inv_get_gyro_sum_of_sqr(const long *gyro); + +#ifdef EMPL + float inv_sinf(float x); + float inv_cosf(float x); + /* eMPL timestamps are assumed to be in milliseconds. */ + static inline long inv_delta_time_ms(inv_time_t t1, inv_time_t t2) + { + return (long)((t1 - t2)); + } +#else + static inline long inv_delta_time_ms(inv_time_t t1, inv_time_t t2) + { + return (long)((t1 - t2) / 1000000L); + } +#endif + + double quaternion_to_rotation_angle(const long *quat); + double inv_vector_norm(const float *x); + + void inv_init_biquad_filter(inv_biquad_filter_t *pFilter, float *pBiquadCoeff); + float inv_biquad_filter_process(inv_biquad_filter_t *pFilter, float input); + void inv_calc_state_to_match_output(inv_biquad_filter_t *pFilter, float input); + void inv_get_cross_product_vec(float *cgcross, float compass[3], float grav[3]); + + void mlMatrixVectorMult(long matrix[9], const long vecIn[3], long *vecOut); + +#ifdef __cplusplus +} +#endif +#endif // INVENSENSE_INV_MATH_FUNC_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/mlmath.c b/bsp/boards/mimsy2-cc2538/mllite/mlmath.c new file mode 100644 index 0000000000..dc39fabf1b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/mlmath.c @@ -0,0 +1,68 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/******************************************************************************* + * + * $Id: mlmath.c 5629 2011-06-11 03:13:08Z mcaramello $ + * + *******************************************************************************/ + +#include + +double ml_asin(double x) +{ + return asin(x); +} + +double ml_atan(double x) +{ + return atan(x); +} + +double ml_atan2(double x, double y) +{ + return atan2(x, y); +} + +double ml_log(double x) +{ + return log(x); +} + +double ml_sqrt(double x) +{ + return sqrt(x); +} + +double ml_ceil(double x) +{ + return ceil(x); +} + +double ml_floor(double x) +{ + return floor(x); +} + +double ml_cos(double x) +{ + return cos(x); +} + +double ml_sin(double x) +{ + return sin(x); +} + +double ml_acos(double x) +{ + return acos(x); +} + +double ml_pow(double x, double y) +{ + return pow(x, y); +} \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/mpl.c b/bsp/boards/mimsy2-cc2538/mllite/mpl.c new file mode 100644 index 0000000000..300cf03811 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/mpl.c @@ -0,0 +1,72 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @defgroup MPL mpl + * @brief Motion Library - Start Point + * Initializes MPL. + * + * @{ + * @file mpl.c + * @brief MPL start point. + */ + +#include "storage_manager.h" +#include "log.h" +#include "mpl.h" +#include "start_manager.h" +#include "data_builder.h" +#include "results_holder.h" +#include "mlinclude.h" + +/** + * @brief Initializes the MPL. Should be called first and once + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_init_mpl(void) +{ + inv_init_storage_manager(); + + /* initialize the start callback manager */ + INV_ERROR_CHECK(inv_init_start_manager()); + + /* initialize the data builder */ + INV_ERROR_CHECK(inv_init_data_builder()); + + INV_ERROR_CHECK(inv_enable_results_holder()); + + return INV_SUCCESS; +} + +const char ml_ver[] = "InvenSense MA 5.1.2"; + +/** + * @brief used to get the MPL version. + * @param version a string where the MPL version gets stored. + * @return INV_SUCCESS if successful or a non-zero error code otherwise. + */ +inv_error_t inv_get_version(char **version) +{ + INVENSENSE_FUNC_START; + /* cast out the const */ + *version = (char *)&ml_ver; + return INV_SUCCESS; +} + +/** + * @brief Starts the MPL. Typically called after inv_init_mpl() or after a + * inv_stop_mpl() to start the MPL back up an running. + * @return INV_SUCCESS if successful or a non-zero error code otherwise. + */ +inv_error_t inv_start_mpl(void) +{ + INV_ERROR_CHECK(inv_execute_mpl_start_notification()); + return INV_SUCCESS; +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/mpl.h b/bsp/boards/mimsy2-cc2538/mllite/mpl.h new file mode 100644 index 0000000000..71d3a58176 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/mpl.h @@ -0,0 +1,24 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" + +#ifndef INV_MPL_H__ +#define INV_MPL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_init_mpl(void); +inv_error_t inv_start_mpl(void); +inv_error_t inv_get_version(char **version); + +#ifdef __cplusplus +} +#endif + +#endif // INV_MPL_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/results_holder.c b/bsp/boards/mimsy2-cc2538/mllite/results_holder.c new file mode 100644 index 0000000000..f999d0214d --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/results_holder.c @@ -0,0 +1,522 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @defgroup Results_Holder results_holder + * @brief Motion Library - Results Holder + * Holds the data for MPL + * + * @{ + * @file results_holder.c + * @brief Results Holder for HAL. + */ + +#include + +#include "results_holder.h" +#include "ml_math_func.h" +#include "mlmath.h" +#include "start_manager.h" +#include "data_builder.h" +#include "message_layer.h" +#include "log.h" + +// These 2 status bits are used to control when the 9 axis quaternion is updated +#define INV_COMPASS_CORRECTION_SET 1 +#define INV_6_AXIS_QUAT_SET 2 + +struct results_t { + long nav_quat[4]; + long gam_quat[4]; + inv_time_t nav_timestamp; + inv_time_t gam_timestamp; + long local_field[3]; /**< local earth's magnetic field */ + long mag_scale[3]; /**< scale factor to apply to magnetic field reading */ + long compass_correction[4]; /**< quaternion going from gyro,accel quaternion to 9 axis */ + int acc_state; /**< Describes accel state */ + int got_accel_bias; /**< Flag describing if accel bias is known */ + long compass_bias_error[3]; /**< Error Squared */ + unsigned char motion_state; + unsigned int motion_state_counter; /**< Incremented for each no motion event in a row */ + long compass_count; /**< compass state internal counter */ + int got_compass_bias; /**< Flag describing if compass bias is known */ + int large_mag_field; /**< Flag describing if there is a large magnetic field */ + int compass_state; /**< Internal compass state */ + long status; + struct inv_sensor_cal_t *sensor; + float quat_confidence_interval; +}; +static struct results_t rh; + +/** @internal +* Store a quaternion more suitable for gaming. This quaternion is often determined +* using only gyro and accel. +* @param[in] quat Length 4, Quaternion scaled by 2^30 +*/ +void inv_store_gaming_quaternion(const long *quat, inv_time_t timestamp) +{ + rh.status |= INV_6_AXIS_QUAT_SET; + memcpy(&rh.gam_quat, quat, sizeof(rh.gam_quat)); + rh.gam_timestamp = timestamp; +} + +/** @internal +* Sets the quaternion adjustment from 6 axis (accel, gyro) to 9 axis quaternion. +* @param[in] data Quaternion Adjustment +* @param[in] timestamp Timestamp of when this is valid +*/ +void inv_set_compass_correction(const long *data, inv_time_t timestamp) +{ + rh.status |= INV_COMPASS_CORRECTION_SET; + memcpy(rh.compass_correction, data, sizeof(rh.compass_correction)); + rh.nav_timestamp = timestamp; +} + +/** @internal +* Gets the quaternion adjustment from 6 axis (accel, gyro) to 9 axis quaternion. +* @param[out] data Quaternion Adjustment +* @param[out] timestamp Timestamp of when this is valid +*/ +void inv_get_compass_correction(long *data, inv_time_t *timestamp) +{ + memcpy(data, rh.compass_correction, sizeof(rh.compass_correction)); + *timestamp = rh.nav_timestamp; +} + +/** Returns non-zero if there is a large magnetic field. See inv_set_large_mag_field() for setting this variable. + * @return Returns non-zero if there is a large magnetic field. + */ +int inv_get_large_mag_field() +{ + return rh.large_mag_field; +} + +/** Set to non-zero if there as a large magnetic field. See inv_get_large_mag_field() for getting this variable. + * @param[in] state value to set for magnetic field strength. Should be non-zero if it is large. + */ +void inv_set_large_mag_field(int state) +{ + rh.large_mag_field = state; +} + +/** Gets the accel state set by inv_set_acc_state() + * @return accel state. + */ +int inv_get_acc_state() +{ + return rh.acc_state; +} + +/** Sets the accel state. See inv_get_acc_state() to get the value. + * @param[in] state value to set accel state to. + */ +void inv_set_acc_state(int state) +{ + rh.acc_state = state; + return; +} + +/** Returns the motion state +* @param[out] cntr Number of previous times a no motion event has occured in a row. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +int inv_get_motion_state(unsigned int *cntr) +{ + *cntr = rh.motion_state_counter; + return rh.motion_state; +} + +/** Sets the motion state + * @param[in] state motion state where INV_NO_MOTION is not moving + * and INV_MOTION is moving. + */ +void inv_set_motion_state(unsigned char state) +{ + long set; + if (state == rh.motion_state) { + if (state == INV_NO_MOTION) { + rh.motion_state_counter++; + } else { + rh.motion_state_counter = 0; + } + return; + } + rh.motion_state_counter = 0; + rh.motion_state = state; + /* Equivalent to set = state, but #define's may change. */ + if (state == INV_MOTION) + set = INV_MSG_MOTION_EVENT; + else + set = INV_MSG_NO_MOTION_EVENT; + inv_set_message(set, (INV_MSG_MOTION_EVENT | INV_MSG_NO_MOTION_EVENT), 0); +} + +/** Sets the local earth's magnetic field +* @param[in] data Local earth's magnetic field in uT scaled by 2^16. +* Length = 3. Y typically points north, Z typically points down in +* northern hemisphere and up in southern hemisphere. +*/ +void inv_set_local_field(const long *data) +{ + memcpy(rh.local_field, data, sizeof(rh.local_field)); +} + +/** Gets the local earth's magnetic field +* @param[out] data Local earth's magnetic field in uT scaled by 2^16. +* Length = 3. Y typically points north, Z typically points down in +* northern hemisphere and up in southern hemisphere. +*/ +void inv_get_local_field(long *data) +{ + memcpy(data, rh.local_field, sizeof(rh.local_field)); +} + +/** Sets the compass sensitivity + * @param[in] data Length 3, sensitivity for each compass axis + * scaled such that 1.0 = 2^30. + */ +void inv_set_mag_scale(const long *data) +{ + memcpy(rh.mag_scale, data, sizeof(rh.mag_scale)); +} + +/** Gets the compass sensitivity + * @param[out] data Length 3, sensitivity for each compass axis + * scaled such that 1.0 = 2^30. + */ +void inv_get_mag_scale(long *data) +{ + memcpy(data, rh.mag_scale, sizeof(rh.mag_scale)); +} + +/** Gets gravity vector + * @param[out] data gravity vector in body frame scaled such that 1.0 = 2^30. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_get_gravity(long *data) +{ + data[0] = + inv_q29_mult(rh.nav_quat[1], rh.nav_quat[3]) - inv_q29_mult(rh.nav_quat[2], rh.nav_quat[0]); + data[1] = + inv_q29_mult(rh.nav_quat[2], rh.nav_quat[3]) + inv_q29_mult(rh.nav_quat[1], rh.nav_quat[0]); + data[2] = + (inv_q29_mult(rh.nav_quat[3], rh.nav_quat[3]) + inv_q29_mult(rh.nav_quat[0], rh.nav_quat[0])) - + 1073741824L; + + return INV_SUCCESS; +} + +/** Returns a quaternion based only on gyro and accel. + * @param[out] data 6-axis gyro and accel quaternion scaled such that 1.0 = 2^30. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_get_6axis_quaternion(long *data) +{ + memcpy(data, rh.gam_quat, sizeof(rh.gam_quat)); + return INV_SUCCESS; +} + +/** Returns a quaternion. + * @param[out] data 9-axis quaternion scaled such that 1.0 = 2^30. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_get_quaternion(long *data) +{ + if (rh.status & (INV_COMPASS_CORRECTION_SET | INV_6_AXIS_QUAT_SET)) { + inv_q_mult(rh.compass_correction, rh.gam_quat, rh.nav_quat); + rh.status &= ~(INV_COMPASS_CORRECTION_SET | INV_6_AXIS_QUAT_SET); + } + memcpy(data, rh.nav_quat, sizeof(rh.nav_quat)); + return INV_SUCCESS; +} + +/** Returns a quaternion. + * @param[out] data 9-axis quaternion. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_get_quaternion_float(float *data) +{ + long ldata[4]; + inv_error_t result = inv_get_quaternion(ldata); + data[0] = inv_q30_to_float(ldata[0]); + data[1] = inv_q30_to_float(ldata[1]); + data[2] = inv_q30_to_float(ldata[2]); + data[3] = inv_q30_to_float(ldata[3]); + return result; +} + +/** Returns a quaternion with accuracy and timestamp. + * @param[out] data 9-axis quaternion scaled such that 1.0 = 2^30. + * @param[out] accuracy Accuracy of quaternion, 0-3, where 3 is most accurate. + * @param[out] timestamp Timestamp of this quaternion in nanoseconds + */ +void inv_get_quaternion_set(long *data, int *accuracy, inv_time_t *timestamp) +{ + inv_get_quaternion(data); + *timestamp = inv_get_last_timestamp(); + if (inv_get_compass_on()) { + *accuracy = inv_get_mag_accuracy(); + } else if (inv_get_gyro_on()) { + *accuracy = inv_get_gyro_accuracy(); + }else if (inv_get_accel_on()) { + *accuracy = inv_get_accel_accuracy(); + } else { + *accuracy = 0; + } +} + +/** Callback that gets called everytime there is new data. It is + * registered by inv_start_results_holder(). + * @param[in] sensor_cal New sensor data to process. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_generate_results(struct inv_sensor_cal_t *sensor_cal) +{ + rh.sensor = sensor_cal; + return INV_SUCCESS; +} + +/** Function to turn on this module. This is automatically called by + * inv_enable_results_holder(). Typically not called by users. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_start_results_holder(void) +{ + inv_register_data_cb(inv_generate_results, INV_PRIORITY_RESULTS_HOLDER, + INV_GYRO_NEW | INV_ACCEL_NEW | INV_MAG_NEW); + return INV_SUCCESS; +} + +/** Initializes results holder. This is called automatically by the +* enable function inv_enable_results_holder(). It may be called any time the feature is enabled, but +* is typically not needed to be called by outside callers. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_init_results_holder(void) +{ + memset(&rh, 0, sizeof(rh)); + rh.mag_scale[0] = 1L<<30; + rh.mag_scale[1] = 1L<<30; + rh.mag_scale[2] = 1L<<30; + rh.compass_correction[0] = 1L<<30; + rh.gam_quat[0] = 1L<<30; + rh.nav_quat[0] = 1L<<30; + rh.quat_confidence_interval = (float)M_PI; + return INV_SUCCESS; +} + +/** Turns on storage of results. +*/ +inv_error_t inv_enable_results_holder() +{ + inv_error_t result; + result = inv_init_results_holder(); + if ( result ) { + return result; + } + + result = inv_register_mpl_start_notification(inv_start_results_holder); + return result; +} + +/** Sets state of if we know the accel bias. + * @return return 1 if we know the accel bias, 0 if not. + * it is set with inv_set_accel_bias_found() + */ +int inv_got_accel_bias() +{ + return rh.got_accel_bias; +} + +/** Sets whether we know the accel bias + * @param[in] state Set to 1 if we know the accel bias. + * Can be retrieved with inv_got_accel_bias() + */ +void inv_set_accel_bias_found(int state) +{ + rh.got_accel_bias = state; +} + +/** Sets state of if we know the compass bias. + * @return return 1 if we know the compass bias, 0 if not. + * it is set with inv_set_compass_bias_found() + */ +int inv_got_compass_bias() +{ + return rh.got_compass_bias; +} + +/** Sets whether we know the compass bias + * @param[in] state Set to 1 if we know the compass bias. + * Can be retrieved with inv_got_compass_bias() + */ +void inv_set_compass_bias_found(int state) +{ + rh.got_compass_bias = state; +} + +/** Sets the compass state. + * @param[in] state Compass state. It can be retrieved with inv_get_compass_state(). + */ +void inv_set_compass_state(int state) +{ + rh.compass_state = state; +} + +/** Get's the compass state + * @return the compass state that was set with inv_set_compass_state() + */ +int inv_get_compass_state() +{ + return rh.compass_state; +} + +/** Set compass bias error. See inv_get_compass_bias_error() + * @param[in] bias_error Set's how accurate we know the compass bias. It is the + * error squared. + */ +void inv_set_compass_bias_error(const long *bias_error) +{ + memcpy(rh.compass_bias_error, bias_error, sizeof(rh.compass_bias_error)); +} + +/** Get's compass bias error. See inv_set_compass_bias_error() for setting. + * @param[out] bias_error Accuracy as to how well the compass bias is known. It is the error squared. + */ +void inv_get_compass_bias_error(long *bias_error) +{ + memcpy(bias_error, rh.compass_bias_error, sizeof(rh.compass_bias_error)); +} + +/** + * @brief Returns 3-element vector of accelerometer data in body frame + * with gravity removed + * @param[out] data 3-element vector of accelerometer data in body frame + * with gravity removed + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_linear_accel(long *data) +{ + long gravity[3]; + + if (data != NULL) + { + inv_get_accel_set(data, NULL, NULL); + inv_get_gravity(gravity); + data[0] -= gravity[0] >> 14; + data[1] -= gravity[1] >> 14; + data[2] -= gravity[2] >> 14; + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** + * @brief Returns 3-element vector of accelerometer data in body frame + * @param[out] data 3-element vector of accelerometer data in body frame + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_accel(long *data) +{ + if (data != NULL) { + inv_get_accel_set(data, NULL, NULL); + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** + * @brief Returns 3-element vector of accelerometer float data + * @param[out] data 3-element vector of accelerometer float data + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_accel_float(float *data) +{ + long tdata[3]; + unsigned char i; + + if (data != NULL && !inv_get_accel(tdata)) { + for (i = 0; i < 3; ++i) { + data[i] = ((float)tdata[i] / (1L << 16)); + } + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** + * @brief Returns 3-element vector of gyro float data + * @param[out] data 3-element vector of gyro float data + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_gyro_float(float *data) +{ + long tdata[3]; + unsigned char i; + + if (data != NULL) { + inv_get_gyro_set(tdata, NULL, NULL); + for (i = 0; i < 3; ++i) { + data[i] = ((float)tdata[i] / (1L << 16)); + } + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** Set 9 axis 95% heading confidence interval for quaternion +* @param[in] ci Confidence interval in radians. +*/ +void inv_set_heading_confidence_interval(float ci) +{ + rh.quat_confidence_interval = ci; +} + +/** Get 9 axis 95% heading confidence interval for quaternion +* @return Confidence interval in radians. +*/ +float inv_get_heading_confidence_interval(void) +{ + return rh.quat_confidence_interval; +} + +/** + * @brief Returns 3-element vector of linear accel float data + * @param[out] data 3-element vector of linear aceel float data + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_linear_accel_float(float *data) +{ + long tdata[3]; + unsigned char i; + + if (data != NULL && !inv_get_linear_accel(tdata)) { + for (i = 0; i < 3; ++i) { + data[i] = ((float)tdata[i] / (1L << 16)); + } + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/results_holder.h b/bsp/boards/mimsy2-cc2538/mllite/results_holder.h new file mode 100644 index 0000000000..1261f91a35 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/results_holder.h @@ -0,0 +1,81 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" + +#ifndef INV_RESULTS_HOLDER_H__ +#define INV_RESULTS_HOLDER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define INV_MOTION 0x0001 +#define INV_NO_MOTION 0x0002 + + /**************************************************************************/ + /* The value of inv_get_gyro_sum_of_sqr is scaled such the (1 dps)^2 = */ + /* 2^GYRO_MAG_SQR_SHIFT. This number must be >=0 and even. */ + /* The value of inv_accel_sum_of_sqr is scaled such that (1g)^2 = */ + /* 2^ACC_MAG_SQR_SHIFT */ + /**************************************************************************/ +#define ACC_MAG_SQR_SHIFT 16 + +void inv_store_gaming_quaternion(const long *quat, inv_time_t timestamp); + +// States +#define SF_NORMAL 0 +#define SF_UNCALIBRATED 1 +#define SF_STARTUP_SETTLE 2 +#define SF_FAST_SETTLE 3 +#define SF_DISTURBANCE 4 +#define SF_SLOW_SETTLE 5 + +int inv_get_acc_state(void); +void inv_set_acc_state(int state); +int inv_get_motion_state(unsigned int *cntr); +void inv_set_motion_state(unsigned char state); +inv_error_t inv_get_gravity(long *data); +inv_error_t inv_get_6axis_quaternion(long *data); +inv_error_t inv_get_quaternion(long *data); +inv_error_t inv_get_quaternion_float(float *data); +void inv_get_quaternion_set(long *data, int *accuracy, inv_time_t *timestamp); + +inv_error_t inv_enable_results_holder(void); +inv_error_t inv_init_results_holder(void); + +/* Magnetic Field Parameters*/ +void inv_set_local_field(const long *data); +void inv_get_local_field(long *data); +void inv_set_mag_scale(const long *data); +void inv_get_mag_scale(long *data); +void inv_set_compass_correction(const long *data, inv_time_t timestamp); +void inv_get_compass_correction(long *data, inv_time_t *timestamp); +int inv_got_compass_bias(void); +void inv_set_compass_bias_found(int state); +int inv_get_large_mag_field(void); +void inv_set_large_mag_field(int state); +void inv_set_compass_state(int state); +int inv_get_compass_state(void); +void inv_set_compass_bias_error(const long *bias_error); +void inv_get_compass_bias_error(long *bias_error); +inv_error_t inv_get_linear_accel(long *data); +inv_error_t inv_get_accel(long *data); +inv_error_t inv_get_accel_float(float *data); +inv_error_t inv_get_gyro_float(float *data); +inv_error_t inv_get_linear_accel_float(float *data); +void inv_set_heading_confidence_interval(float ci); +float inv_get_heading_confidence_interval(void); + +int inv_got_accel_bias(void); +void inv_set_accel_bias_found(int state); + + +#ifdef __cplusplus +} +#endif + +#endif // INV_RESULTS_HOLDER_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/start_manager.c b/bsp/boards/mimsy2-cc2538/mllite/start_manager.c new file mode 100644 index 0000000000..67a8a95f24 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/start_manager.c @@ -0,0 +1,105 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ +/** + * @defgroup Start_Manager start_manager + * @brief Motion Library - Start Manager + * Start Manager + * + * @{ + * @file start_manager.c + * @brief This handles all the callbacks when inv_start_mpl() is called. + */ + + +#include +#include "log.h" +#include "start_manager.h" + +typedef inv_error_t (*inv_start_cb_func)(); +struct inv_start_cb_t { + int num_cb; + inv_start_cb_func start_cb[INV_MAX_START_CB]; +}; + +static struct inv_start_cb_t inv_start_cb; + +/** Initilize the start manager. Typically called by inv_start_mpl(); +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_init_start_manager(void) +{ + memset(&inv_start_cb, 0, sizeof(inv_start_cb)); + return INV_SUCCESS; +} + +/** Removes a callback from start notification +* @param[in] start_cb function to remove from start notification +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_unregister_mpl_start_notification(inv_error_t (*start_cb)(void)) +{ + int kk; + + for (kk=0; kk= INV_MAX_START_CB) + return INV_ERROR_INVALID_PARAMETER; + + inv_start_cb.start_cb[inv_start_cb.num_cb] = start_cb; + inv_start_cb.num_cb++; + return INV_SUCCESS; +} + +/** Callback all the functions that want to be notified when inv_start_mpl() was +* called. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_execute_mpl_start_notification(void) +{ + inv_error_t result,first_error; + int kk; + + first_error = INV_SUCCESS; + + for (kk = 0; kk < inv_start_cb.num_cb; ++kk) { + result = inv_start_cb.start_cb[kk](); + if (result && (first_error == INV_SUCCESS)) { + first_error = result; + } + } + return first_error; +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/start_manager.h b/bsp/boards/mimsy2-cc2538/mllite/start_manager.h new file mode 100644 index 0000000000..ecb1ab9574 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/start_manager.h @@ -0,0 +1,27 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INV_START_MANAGER_H__ +#define INV_START_MANAGER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mltypes.h" + +/** Max number of start callbacks we can handle. */ +#define INV_MAX_START_CB 20 + +inv_error_t inv_init_start_manager(void); +inv_error_t inv_register_mpl_start_notification(inv_error_t (*start_cb)(void)); +inv_error_t inv_execute_mpl_start_notification(void); +inv_error_t inv_unregister_mpl_start_notification(inv_error_t (*start_cb)(void)); + +#ifdef __cplusplus +} +#endif +#endif // INV_START_MANAGER_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/storage_manager.c b/bsp/boards/mimsy2-cc2538/mllite/storage_manager.c new file mode 100644 index 0000000000..3528731a50 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/storage_manager.c @@ -0,0 +1,204 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/** + * @defgroup Storage_Manager storage_manager + * @brief Motion Library - Stores Data for functions. + * + * + * @{ + * @file storage_manager.c + * @brief Load and Store Manager. + */ + +#include + +#include "storage_manager.h" +#include "log.h" +#include "ml_math_func.h" +#include "mlmath.h" + +/* Must be changed if the format of storage changes */ +#define DEFAULT_KEY 29681 + +typedef inv_error_t (*load_func_t)(const unsigned char *data); +typedef inv_error_t (*save_func_t)(unsigned char *data); +/** Max number of entites that can be stored */ +#define NUM_STORAGE_BOXES 20 + +struct data_header_t { + long size; + uint32_t checksum; + unsigned int key; +}; + +struct data_storage_t { + int num; /**< Number of differnt save entities */ + size_t total_size; /**< Size in bytes to store non volatile data */ + load_func_t load[NUM_STORAGE_BOXES]; /**< Callback to load data */ + save_func_t save[NUM_STORAGE_BOXES]; /**< Callback to save data */ + struct data_header_t hd[NUM_STORAGE_BOXES]; /**< Header info for each entity */ +}; +static struct data_storage_t ds; + +/** Should be called once before using any of the storage methods. Typically +* called first by inv_init_mpl().*/ +void inv_init_storage_manager() +{ + memset(&ds, 0, sizeof(ds)); + ds.total_size = sizeof(struct data_header_t); +} + +/** Used to register your mechanism to load and store non-volative data. This should typical be +* called during the enable function for your feature. +* @param[in] load_func function pointer you will use to receive data that was stored for you. +* @param[in] save_func function pointer you will use to save any data you want saved to +* non-volatile memory between runs. +* @param[in] size The size in bytes of the amount of data you want loaded and saved. +* @param[in] key The key associated with your data type should be unique across MPL. +* The key should change when your type of data for storage changes. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_register_load_store(inv_error_t (*load_func)(const unsigned char *data), + inv_error_t (*save_func)(unsigned char *data), size_t size, unsigned int key) +{ + int kk; + // Check if this has been registered already + for (kk=0; kk= NUM_STORAGE_BOXES) { + return INV_ERROR_INVALID_PARAMETER; + } + // Add to list + ds.hd[ds.num].key = key; + ds.hd[ds.num].size = size; + ds.load[ds.num] = load_func; + ds.save[ds.num] = save_func; + ds.total_size += size + sizeof(struct data_header_t); + ds.num++; + + return INV_SUCCESS; +} + +/** Returns the memory size needed to perform a store +* @param[out] size Size in bytes of memory needed to store. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_get_mpl_state_size(size_t *size) +{ + *size = ds.total_size; + return INV_SUCCESS; +} + +/** @internal + * Finds key in ds.hd[] array and returns location + * @return location where key exists in array, -1 if not found. + */ +static int inv_find_entry(unsigned int key) +{ + int kk; + for (kk=0; kkkey != DEFAULT_KEY) + return INV_ERROR_CALIBRATION_LOAD; // Key changed or data corruption + len = MIN(hd->size, len); + len = hd->size; + len -= sizeof(struct data_header_t); + data += sizeof(struct data_header_t); + checksum = inv_checksum(data, len); + if (checksum != hd->checksum) + return INV_ERROR_CALIBRATION_LOAD; // Data corruption + + while (len > (long)sizeof(struct data_header_t)) { + hd = (struct data_header_t *)data; + entry = inv_find_entry(hd->key); + data += sizeof(struct data_header_t); + len -= sizeof(struct data_header_t); + if (entry >= 0 && len >= hd->size) { + if (hd->size == ds.hd[entry].size) { + checksum = inv_checksum(data, hd->size); + if (checksum == hd->checksum) { + ds.load[entry](data); + } else { + return INV_ERROR_CALIBRATION_LOAD; + } + } + } + len -= hd->size; + if (len >= 0) + data = data + hd->size; + } + + return INV_SUCCESS; +} + +/** This function fills up a block of memory to be stored in non-volatile memory. +* @param[out] data Place to store data, size of sz, must be at least size +* returned by inv_get_mpl_state_size() +* @param[in] sz Size of data. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_save_mpl_states(unsigned char *data, size_t sz) +{ + unsigned char *cur; + int kk; + struct data_header_t *hd; + + if (sz >= ds.total_size) { + cur = data + sizeof(struct data_header_t); + for (kk = 0; kk < ds.num; ++kk) { + hd = (struct data_header_t *)cur; + cur += sizeof(struct data_header_t); + ds.save[kk](cur); + hd->checksum = inv_checksum(cur, ds.hd[kk].size); + hd->size = ds.hd[kk].size; + hd->key = ds.hd[kk].key; + cur += ds.hd[kk].size; + } + } else { + return INV_ERROR_CALIBRATION_LOAD; + } + + hd = (struct data_header_t *)data; + hd->checksum = inv_checksum(data + sizeof(struct data_header_t), + ds.total_size - sizeof(struct data_header_t)); + hd->key = DEFAULT_KEY; + hd->size = ds.total_size; + + return INV_SUCCESS; +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mllite/storage_manager.h b/bsp/boards/mimsy2-cc2538/mllite/storage_manager.h new file mode 100644 index 0000000000..e3dfe52dba --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mllite/storage_manager.h @@ -0,0 +1,32 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" +#include "stdlib.h" + + +#ifndef INV_STORAGE_MANAGER_H__ +#define INV_STORAGE_MANAGER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_register_load_store( + inv_error_t (*load_func)(const unsigned char *data), + inv_error_t (*save_func)(unsigned char *data), + size_t size, unsigned int key); +void inv_init_storage_manager(void); + +inv_error_t inv_get_mpl_state_size(size_t *size); +inv_error_t inv_load_mpl_states(const unsigned char *data, size_t len); +inv_error_t inv_save_mpl_states(unsigned char *data, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* INV_STORAGE_MANAGER_H__ */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mlmath.c b/bsp/boards/mimsy2-cc2538/mlmath.c new file mode 100644 index 0000000000..b0f07eb1fb --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mlmath.c @@ -0,0 +1,68 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/******************************************************************************* + * + * $Id: mlmath.c 5629 2011-06-11 03:13:08Z mcaramello $ + * + *******************************************************************************/ + +#include "math.h" + +double ml_asin(double x) +{ + return asin(x); +} + +double ml_atan(double x) +{ + return atan(x); +} + +double ml_atan2(double x, double y) +{ + return atan2(x, y); +} + +double ml_log(double x) +{ + return log(x); +} + +double ml_sqrt(double x) +{ + return sqrt(x); +} + +double ml_ceil(double x) +{ + return ceil(x); +} + +double ml_floor(double x) +{ + return floor(x); +} + +double ml_cos(double x) +{ + return cos(x); +} + +double ml_sin(double x) +{ + return sin(x); +} + +double ml_acos(double x) +{ + return acos(x); +} + +double ml_pow(double x, double y) +{ + return pow(x, y); +} diff --git a/bsp/boards/mimsy2-cc2538/mlmath.h b/bsp/boards/mimsy2-cc2538/mlmath.h new file mode 100644 index 0000000000..e9059aec78 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mlmath.h @@ -0,0 +1,95 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +/******************************************************************************* + * + * $Id: mlmath.h 5629 2011-06-11 03:13:08Z mcaramello $ + * + *******************************************************************************/ + +#ifndef _ML_MATH_H_ +#define _ML_MATH_H_ + +#ifndef MLMATH +// This define makes Microsoft pickup things like M_PI +#define _USE_MATH_DEFINES +#include + +#ifdef WIN32 +// Microsoft doesn't follow standards +#define round(x)(((double)((long long)((x)>0?(x)+.5:(x)-.5)))) +#define roundf(x)(((float )((long long)((x)>0?(x)+.5f:(x)-.5f)))) +#endif + +//#else // MLMATH + +#ifdef __cplusplus +extern "C" { +#endif +/* MPL needs below functions */ +double ml_asin(double); +double ml_atan(double); +double ml_atan2(double, double); +double ml_log(double); +double ml_sqrt(double); +double ml_ceil(double); +double ml_floor(double); +double ml_cos(double); +double ml_sin(double); +double ml_acos(double); +#ifdef __cplusplus +} // extern "C" +#endif + +/* + * We rename functions here to provide the hook for other + * customized math functions. + */ +#define sqrt(x) ml_sqrt(x) +#define log(x) ml_log(x) +#define asin(x) ml_asin(x) +#define atan(x) ml_atan(x) +#define atan2(x,y) ml_atan2(x,y) +#define ceil(x) ml_ceil(x) +#define floor(x) ml_floor(x) +#define fabs(x) (((x)<0)?-(x):(x)) +#define round(x) (((double)((long long)((x)>0?(x)+.5:(x)-.5)))) +#define roundf(x) (((float )((long long)((x)>0?(x)+.5f:(x)-.5f)))) +#define cos(x) ml_cos(x) +#define sin(x) ml_sin(x) +#define acos(x) ml_acos(x) + +#define pow(x,y) ml_pow(x,y) + +#ifdef LINUX +/* stubs for float version of math functions */ +#define cosf(x) ml_cos(x) +#define sinf(x) ml_sin(x) +#define atan2f(x,y) ml_atan2(x,y) +#define sqrtf(x) ml_sqrt(x) +#endif + + + +#endif // MLMATH + +#ifndef M_PI +#define M_PI 3.14159265358979 +#endif + +#ifndef ABS +#define ABS(x) (((x)>=0)?(x):-(x)) +#endif + +#ifndef MIN +#define MIN(x,y) (((x)<(y))?(x):(y)) +#endif + +#ifndef MAX +#define MAX(x,y) (((x)>(y))?(x):(y)) +#endif + +/*---------------------------*/ +#endif /* !_ML_MATH_H_ */ diff --git a/bsp/boards/mimsy2-cc2538/mlos.h b/bsp/boards/mimsy2-cc2538/mlos.h new file mode 100644 index 0000000000..bee573d0e1 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mlos.h @@ -0,0 +1,103 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +#ifndef _MLOS_H +#define _MLOS_H + +#ifndef __KERNEL__ +#include +#endif + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(LINUX) || defined(__KERNEL__) +typedef unsigned int HANDLE; +#endif + + /* ------------ */ + /* - Defines. - */ + /* ------------ */ + + /* - MLOSCreateFile defines. - */ + +#define MLOS_GENERIC_READ ((unsigned int)0x80000000) +#define MLOS_GENERIC_WRITE ((unsigned int)0x40000000) +#define MLOS_FILE_SHARE_READ ((unsigned int)0x00000001) +#define MLOS_FILE_SHARE_WRITE ((unsigned int)0x00000002) +#define MLOS_OPEN_EXISTING ((unsigned int)0x00000003) + + /* ---------- */ + /* - Enums. - */ + /* ---------- */ + + /* --------------- */ + /* - Structures. - */ + /* --------------- */ + + /* --------------------- */ + /* - Function p-types. - */ + /* --------------------- */ + +#ifndef __KERNEL__ +#include + void *inv_malloc(unsigned int numBytes); + inv_error_t inv_free(void *ptr); + inv_error_t inv_create_mutex(HANDLE *mutex); + inv_error_t inv_lock_mutex(HANDLE mutex); + inv_error_t inv_unlock_mutex(HANDLE mutex); + FILE *inv_fopen(char *filename); + void inv_fclose(FILE *fp); + + inv_error_t inv_destroy_mutex(HANDLE handle); + + void inv_sleep(int mSecs); +#ifdef EMPL + inv_error_t inv_get_tick_count(inv_time_t *timestamp); +#else + inv_time_t inv_get_tick_count(void); +#endif + + + /* Kernel implmentations */ +#define GFP_KERNEL (0x70) + static inline void *kmalloc(size_t size, + unsigned int gfp_flags) + { + (void)gfp_flags; + return inv_malloc((unsigned int)size); + } + static inline void *kzalloc(size_t size, unsigned int gfp_flags) + { + void *tmp = inv_malloc((unsigned int)size); + (void)gfp_flags; + if (tmp) + memset(tmp, 0, size); + return tmp; + } + static inline void kfree(void *ptr) + { + inv_free(ptr); + } + static inline void msleep(long msecs) + { + inv_sleep(msecs); + } + static inline void udelay(unsigned long usecs) + { + inv_sleep((usecs + 999) / 1000); + } +#else +#include +#endif + +#ifdef __cplusplus +} +#endif +#endif /* _MLOS_H */ diff --git a/bsp/boards/mimsy2-cc2538/mltypes.h b/bsp/boards/mimsy2-cc2538/mltypes.h new file mode 100644 index 0000000000..ccb34d4e37 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mltypes.h @@ -0,0 +1,262 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +/** + * @defgroup MLERROR + * @brief Motion Library - Error definitions. + * Definition of the error codes used within the MPL and + * returned to the user. + * Every function tries to return a meaningful error code basing + * on the occuring error condition. The error code is numeric. + * + * The available error codes and their associated values are: + * - (0) INV_SUCCESS + * - (32) INV_ERROR + * - (22 / EINVAL) INV_ERROR_INVALID_PARAMETER + * - (1 / EPERM) INV_ERROR_FEATURE_NOT_ENABLED + * - (36) INV_ERROR_FEATURE_NOT_IMPLEMENTED + * - (38) INV_ERROR_DMP_NOT_STARTED + * - (39) INV_ERROR_DMP_STARTED + * - (40) INV_ERROR_NOT_OPENED + * - (41) INV_ERROR_OPENED + * - (19 / ENODEV) INV_ERROR_INVALID_MODULE + * - (12 / ENOMEM) INV_ERROR_MEMORY_EXAUSTED + * - (44) INV_ERROR_DIVIDE_BY_ZERO + * - (45) INV_ERROR_ASSERTION_FAILURE + * - (46) INV_ERROR_FILE_OPEN + * - (47) INV_ERROR_FILE_READ + * - (48) INV_ERROR_FILE_WRITE + * - (49) INV_ERROR_INVALID_CONFIGURATION + * - (52) INV_ERROR_SERIAL_CLOSED + * - (53) INV_ERROR_SERIAL_OPEN_ERROR + * - (54) INV_ERROR_SERIAL_READ + * - (55) INV_ERROR_SERIAL_WRITE + * - (56) INV_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED + * - (57) INV_ERROR_SM_TRANSITION + * - (58) INV_ERROR_SM_IMPROPER_STATE + * - (62) INV_ERROR_FIFO_OVERFLOW + * - (63) INV_ERROR_FIFO_FOOTER + * - (64) INV_ERROR_FIFO_READ_COUNT + * - (65) INV_ERROR_FIFO_READ_DATA + * - (72) INV_ERROR_MEMORY_SET + * - (82) INV_ERROR_LOG_MEMORY_ERROR + * - (83) INV_ERROR_LOG_OUTPUT_ERROR + * - (92) INV_ERROR_OS_BAD_PTR + * - (93) INV_ERROR_OS_BAD_HANDLE + * - (94) INV_ERROR_OS_CREATE_FAILED + * - (95) INV_ERROR_OS_LOCK_FAILED + * - (102) INV_ERROR_COMPASS_DATA_OVERFLOW + * - (103) INV_ERROR_COMPASS_DATA_UNDERFLOW + * - (104) INV_ERROR_COMPASS_DATA_NOT_READY + * - (105) INV_ERROR_COMPASS_DATA_ERROR + * - (107) INV_ERROR_CALIBRATION_LOAD + * - (108) INV_ERROR_CALIBRATION_STORE + * - (109) INV_ERROR_CALIBRATION_LEN + * - (110) INV_ERROR_CALIBRATION_CHECKSUM + * - (111) INV_ERROR_ACCEL_DATA_OVERFLOW + * - (112) INV_ERROR_ACCEL_DATA_UNDERFLOW + * - (113) INV_ERROR_ACCEL_DATA_NOT_READY + * - (114) INV_ERROR_ACCEL_DATA_ERROR + * + * The available warning codes and their associated values are: + * - (115) INV_WARNING_MOTION_RACE + * - (116) INV_WARNING_QUAT_TRASHED + * + * @{ + * @file mltypes.h + * @} + */ + +#ifndef MLTYPES_H +#define MLTYPES_H + +#ifdef __KERNEL__ +#include +#include +#else +#include "stdint_invensense.h" +#include +#endif +#include + +#ifndef REMOVE_INV_ERROR_T +/*--------------------------- + * ML Types + *--------------------------*/ + +/** + * @struct inv_error_t mltypes.h "mltypes" + * @brief The MPL Error Code return type. + * + * @code + * typedef unsigned char inv_error_t; + * @endcode + */ +//typedef unsigned char inv_error_t; +typedef int inv_error_t; +#endif + +#if defined EMPL +typedef unsigned long inv_time_t; +#else +typedef unsigned long long inv_time_t; +#endif + +#if defined EMPL || (!defined __GNUC__ && !defined __KERNEL__) +typedef int8_t __s8; +typedef int16_t __s16; +typedef int32_t __s32; + +typedef uint8_t __u8; +typedef uint16_t __u16; +typedef uint32_t __u32; + +#ifndef EMPL_NO_64BIT +typedef int64_t __s64; +typedef uint64_t __u64; +#endif +#elif !defined __KERNEL__ +#include +#endif + +#if defined EMPL_TARGET_MSP430 +#include +#endif + +#ifndef __cplusplus +#ifndef __KERNEL__ +#ifndef EMPL_TARGET_UC3L0 +//typedef int_fast8_t bool; +#endif + +#ifndef false +#define false 0 +#endif + +#ifndef true +#define true 1 +#endif + +#endif +#endif + +/*--------------------------- + * ML Defines + *--------------------------*/ + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef __KERNEL__ +#ifndef ARRAY_SIZE +/* Dimension of an array */ +#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0])) +#endif +#endif +/* - ML Errors. - */ +#define ERROR_NAME(x) (#x) +#define ERROR_CHECK_FIRST(first, x) \ + { if (INV_SUCCESS == first) first = x; } + +#define INV_SUCCESS (0) +/* Generic Error code. Proprietary Error Codes only */ +#define INV_ERROR_BASE (0x20) +#define INV_ERROR (INV_ERROR_BASE) + +#ifndef EINVAL +#define EINVAL (22) +#endif + +#ifndef ENOMEM +#define ENOMEM (12) +#endif + +#ifndef EPERM +#define EPERM (1) +#endif + + + +/* Compatibility and other generic error codes */ +#define INV_ERROR_INVALID_PARAMETER (EINVAL) +#define INV_ERROR_FEATURE_NOT_ENABLED (EPERM) +#define INV_ERROR_FEATURE_NOT_IMPLEMENTED (INV_ERROR_BASE + 4) +#define INV_ERROR_DMP_NOT_STARTED (INV_ERROR_BASE + 6) +#define INV_ERROR_DMP_STARTED (INV_ERROR_BASE + 7) +#define INV_ERROR_NOT_OPENED (INV_ERROR_BASE + 8) +#define INV_ERROR_OPENED (INV_ERROR_BASE + 9) +#define INV_ERROR_INVALID_MODULE (ENODEV) +#define INV_ERROR_MEMORY_EXAUSTED (ENOMEM) +#define INV_ERROR_DIVIDE_BY_ZERO (INV_ERROR_BASE + 12) +#define INV_ERROR_ASSERTION_FAILURE (INV_ERROR_BASE + 13) +#define INV_ERROR_FILE_OPEN (INV_ERROR_BASE + 14) +#define INV_ERROR_FILE_READ (INV_ERROR_BASE + 15) +#define INV_ERROR_FILE_WRITE (INV_ERROR_BASE + 16) +#define INV_ERROR_INVALID_CONFIGURATION (INV_ERROR_BASE + 17) +#define INV_ERROR_NOT_AUTHORIZED (INV_ERROR_BASE + 18) + +/* Serial Communication */ +#define INV_ERROR_SERIAL_CLOSED (INV_ERROR_BASE + 20) +#define INV_ERROR_SERIAL_OPEN_ERROR (INV_ERROR_BASE + 21) +#define INV_ERROR_SERIAL_READ (INV_ERROR_BASE + 22) +#define INV_ERROR_SERIAL_WRITE (INV_ERROR_BASE + 23) +#define INV_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED (INV_ERROR_BASE + 24) + +/* SM = State Machine */ +#define INV_ERROR_SM_TRANSITION (INV_ERROR_BASE + 25) +#define INV_ERROR_SM_IMPROPER_STATE (INV_ERROR_BASE + 26) + +/* Fifo */ +#define INV_ERROR_FIFO_OVERFLOW (INV_ERROR_BASE + 30) +#define INV_ERROR_FIFO_FOOTER (INV_ERROR_BASE + 31) +#define INV_ERROR_FIFO_READ_COUNT (INV_ERROR_BASE + 32) +#define INV_ERROR_FIFO_READ_DATA (INV_ERROR_BASE + 33) + +/* Memory & Registers, Set & Get */ +#define INV_ERROR_MEMORY_SET (INV_ERROR_BASE + 40) + +#define INV_ERROR_LOG_MEMORY_ERROR (INV_ERROR_BASE + 50) +#define INV_ERROR_LOG_OUTPUT_ERROR (INV_ERROR_BASE + 51) + +/* OS interface errors */ +#define INV_ERROR_OS_BAD_PTR (INV_ERROR_BASE + 60) +#define INV_ERROR_OS_BAD_HANDLE (INV_ERROR_BASE + 61) +#define INV_ERROR_OS_CREATE_FAILED (INV_ERROR_BASE + 62) +#define INV_ERROR_OS_LOCK_FAILED (INV_ERROR_BASE + 63) + +/* Compass errors */ +#define INV_ERROR_COMPASS_DATA_OVERFLOW (INV_ERROR_BASE + 70) +#define INV_ERROR_COMPASS_DATA_UNDERFLOW (INV_ERROR_BASE + 71) +#define INV_ERROR_COMPASS_DATA_NOT_READY (INV_ERROR_BASE + 72) +#define INV_ERROR_COMPASS_DATA_ERROR (INV_ERROR_BASE + 73) + +/* Load/Store calibration */ +#define INV_ERROR_CALIBRATION_LOAD (INV_ERROR_BASE + 75) +#define INV_ERROR_CALIBRATION_STORE (INV_ERROR_BASE + 76) +#define INV_ERROR_CALIBRATION_LEN (INV_ERROR_BASE + 77) +#define INV_ERROR_CALIBRATION_CHECKSUM (INV_ERROR_BASE + 78) + +/* Accel errors */ +#define INV_ERROR_ACCEL_DATA_OVERFLOW (INV_ERROR_BASE + 79) +#define INV_ERROR_ACCEL_DATA_UNDERFLOW (INV_ERROR_BASE + 80) +#define INV_ERROR_ACCEL_DATA_NOT_READY (INV_ERROR_BASE + 81) +#define INV_ERROR_ACCEL_DATA_ERROR (INV_ERROR_BASE + 82) + +/* No Motion Warning States */ +#define INV_WARNING_MOTION_RACE (INV_ERROR_BASE + 83) +#define INV_WARNING_QUAT_TRASHED (INV_ERROR_BASE + 84) +#define INV_WARNING_GYRO_MAG (INV_ERROR_BASE + 85) + +#define INV_WARNING_SEMAPHORE_TIMEOUT (INV_ERROR_BASE + 86) + + +/* For Linux coding compliance */ +#ifndef __KERNEL__ +#define EXPORT_SYMBOL(x) +#endif + +#endif /* MLTYPES_H */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/motion_no_motion.h b/bsp/boards/mimsy2-cc2538/motion_no_motion.h new file mode 100644 index 0000000000..d94e003c60 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/motion_no_motion.h @@ -0,0 +1,28 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INV_MOTION_NO_MOTION_H__ +#define INV_MOTION_NO_MOTION_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_motion_no_motion(void); +inv_error_t inv_disable_motion_no_motion(void); +inv_error_t inv_init_motion_no_motion(void); +inv_error_t inv_start_motion_no_motion(void); +inv_error_t inv_stop_motion_no_motion(void); + +inv_error_t inv_set_no_motion_time(long time_ms); + +#ifdef __cplusplus +} +#endif + +#endif // INV_MOTION_NO_MOTION_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl.c b/bsp/boards/mimsy2-cc2538/mpl.c new file mode 100644 index 0000000000..300cf03811 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl.c @@ -0,0 +1,72 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +/** + * @defgroup MPL mpl + * @brief Motion Library - Start Point + * Initializes MPL. + * + * @{ + * @file mpl.c + * @brief MPL start point. + */ + +#include "storage_manager.h" +#include "log.h" +#include "mpl.h" +#include "start_manager.h" +#include "data_builder.h" +#include "results_holder.h" +#include "mlinclude.h" + +/** + * @brief Initializes the MPL. Should be called first and once + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_init_mpl(void) +{ + inv_init_storage_manager(); + + /* initialize the start callback manager */ + INV_ERROR_CHECK(inv_init_start_manager()); + + /* initialize the data builder */ + INV_ERROR_CHECK(inv_init_data_builder()); + + INV_ERROR_CHECK(inv_enable_results_holder()); + + return INV_SUCCESS; +} + +const char ml_ver[] = "InvenSense MA 5.1.2"; + +/** + * @brief used to get the MPL version. + * @param version a string where the MPL version gets stored. + * @return INV_SUCCESS if successful or a non-zero error code otherwise. + */ +inv_error_t inv_get_version(char **version) +{ + INVENSENSE_FUNC_START; + /* cast out the const */ + *version = (char *)&ml_ver; + return INV_SUCCESS; +} + +/** + * @brief Starts the MPL. Typically called after inv_init_mpl() or after a + * inv_stop_mpl() to start the MPL back up an running. + * @return INV_SUCCESS if successful or a non-zero error code otherwise. + */ +inv_error_t inv_start_mpl(void) +{ + INV_ERROR_CHECK(inv_execute_mpl_start_notification()); + return INV_SUCCESS; +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl.h b/bsp/boards/mimsy2-cc2538/mpl.h new file mode 100644 index 0000000000..71d3a58176 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl.h @@ -0,0 +1,24 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" + +#ifndef INV_MPL_H__ +#define INV_MPL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_init_mpl(void); +inv_error_t inv_start_mpl(void); +inv_error_t inv_get_version(char **version); + +#ifdef __cplusplus +} +#endif + +#endif // INV_MPL_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl/accel_auto_cal.h b/bsp/boards/mimsy2-cc2538/mpl/accel_auto_cal.h new file mode 100644 index 0000000000..cb69d65726 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/accel_auto_cal.h @@ -0,0 +1,38 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/******************************************************************************* + * + * $Id$ + * + ******************************************************************************/ + +#ifndef MLDMP_ACCEL_AUTO_CALIBRATION_H__ +#define MLDMP_ACCEL_AUTO_CALIBRATION_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_in_use_auto_calibration(void); +inv_error_t inv_disable_in_use_auto_calibration(void); +inv_error_t inv_stop_in_use_auto_calibration(void); +inv_error_t inv_start_in_use_auto_calibration(void); +inv_error_t inv_in_use_auto_calibration_is_enabled(unsigned char *is_enabled); +inv_error_t inv_init_in_use_auto_calibration(void); +void inv_init_accel_maxmin(void); +void inv_record_good_accel_maxmin(void); +int inv_get_accel_bias_stage(void); + +#ifdef __cplusplus +} +#endif + +#endif // MLDMP_ACCEL_AUTO_CALIBRATION_H__ + diff --git a/bsp/boards/mimsy2-cc2538/mpl/compass_vec_cal.h b/bsp/boards/mimsy2-cc2538/mpl/compass_vec_cal.h new file mode 100644 index 0000000000..2b156bc839 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/compass_vec_cal.h @@ -0,0 +1,35 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ + +#ifndef COMPASS_ONLY_CAL_H__ +#define COMPASS_ONLY_CAL_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_vector_compass_cal(void); +inv_error_t inv_disable_vector_compass_cal(void); +inv_error_t inv_start_vector_compass_cal(void); +inv_error_t inv_stop_vector_compass_cal(void); +void inv_vector_compass_cal_sensitivity(float sens); +inv_error_t inv_init_vector_compass_cal(void); + +#ifdef __cplusplus +} +#endif + +#endif // COMPASS_ONLY_CAL_H__ + diff --git a/bsp/boards/mimsy2-cc2538/mpl/fast_no_motion.h b/bsp/boards/mimsy2-cc2538/mpl/fast_no_motion.h new file mode 100644 index 0000000000..bf5d14af88 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/fast_no_motion.h @@ -0,0 +1,46 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef MLDMP_FAST_NO_MOTION_H__ +#define MLDMP_FAST_NO_MOTION_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + inv_error_t inv_enable_fast_nomot(void); + inv_error_t inv_disable_fast_nomot(void); + inv_error_t inv_start_fast_nomot(void); + inv_error_t inv_stop_fast_nomot(void); + inv_error_t inv_init_fast_nomot(void); + void inv_set_default_number_of_samples(int count); + inv_error_t inv_fast_nomot_is_enabled(unsigned char *is_enabled); + inv_error_t inv_update_fast_nomot(long *gyro); + + void inv_get_fast_nomot_accel_param(long *cntr, long long *param); + void inv_get_fast_nomot_compass_param(long *cntr, long long *param); + void inv_set_fast_nomot_accel_threshold(long long thresh); + void inv_set_fast_nomot_compass_threshold(long long thresh); + void int_set_fast_nomot_gyro_threshold(long long thresh); + + void inv_fnm_debug_print(void); + +#ifdef __cplusplus +} +#endif + + +#endif // MLDMP_FAST_NO_MOTION_H__ + diff --git a/bsp/boards/mimsy2-cc2538/mpl/fusion_9axis.h b/bsp/boards/mimsy2-cc2538/mpl/fusion_9axis.h new file mode 100644 index 0000000000..7d2efe9bb1 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/fusion_9axis.h @@ -0,0 +1,38 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef MLDMP_FUSION9AXIS_H__ +#define MLDMP_FUSION9AXIS_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + void inv_init_9x_fusion(void); + inv_error_t inv_9x_fusion_state_change(unsigned char newState); + inv_error_t inv_enable_9x_sensor_fusion(void); + inv_error_t inv_disable_9x_sensor_fusion(void); + inv_error_t inv_start_9x_sensor_fusion(void); + inv_error_t inv_stop_9x_sensor_fusion(void); + inv_error_t inv_9x_fusion_set_mag_fb(float fb); + inv_error_t inv_9x_fusion_enable_jitter_reduction(int en); + inv_error_t inv_9x_fusion_use_timestamps(int en); + +#ifdef __cplusplus +} +#endif + + +#endif // MLDMP_FUSION9AXIS_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl/gyro_tc.h b/bsp/boards/mimsy2-cc2538/mpl/gyro_tc.h new file mode 100644 index 0000000000..3347a14878 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/gyro_tc.h @@ -0,0 +1,43 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef _GYRO_TC_H +#define _GYRO_TC_H_ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_gyro_tc(void); +inv_error_t inv_disable_gyro_tc(void); +inv_error_t inv_start_gyro_tc(void); +inv_error_t inv_stop_gyro_tc(void); + +inv_error_t inv_get_gyro_ts(long *data); +inv_error_t inv_set_gyro_ts(long *data); + +inv_error_t inv_init_gyro_ts(void); + +inv_error_t inv_set_gtc_max_temp(long data); +inv_error_t inv_set_gtc_min_temp(long data); + +inv_error_t inv_print_gtc_data(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _GYRO_TC_H */ + diff --git a/bsp/boards/mimsy2-cc2538/mpl/heading_from_gyro.h b/bsp/boards/mimsy2-cc2538/mpl/heading_from_gyro.h new file mode 100644 index 0000000000..b73993f57e --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/heading_from_gyro.h @@ -0,0 +1,33 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef _HEADING_FROM_GYRO_H_ +#define _HEADING_FROM_GYRO_H_ +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + inv_error_t inv_enable_heading_from_gyro(void); + inv_error_t inv_disable_heading_from_gyro(void); + void inv_init_heading_from_gyro(void); + inv_error_t inv_start_heading_from_gyro(void); + inv_error_t inv_stop_heading_from_gyro(void); + +#ifdef __cplusplus +} +#endif + + +#endif /* _HEADING_FROM_GYRO_H_ */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl/inv_math.h b/bsp/boards/mimsy2-cc2538/mpl/inv_math.h new file mode 100644 index 0000000000..079c11c9e7 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/inv_math.h @@ -0,0 +1,8 @@ +/* math.h has many functions and defines that are not consistent across +* platforms. This address that */ + +#ifdef _WINDOWS +#define _USE_MATH_DEFINES +#endif + +#include \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl/invensense_adv.h b/bsp/boards/mimsy2-cc2538/mpl/invensense_adv.h new file mode 100644 index 0000000000..f101cb5c98 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/invensense_adv.h @@ -0,0 +1,27 @@ +/* + $License: + Copyright (C) 2012 InvenSense Corporation, All Rights Reserved. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ + +/* + Main header file for Invensense's Advanced library. +*/ + +#include "accel_auto_cal.h" +#include "compass_vec_cal.h" +#include "fast_no_motion.h" +#include "fusion_9axis.h" +#include "gyro_tc.h" +#include "heading_from_gyro.h" +#include "mag_disturb.h" +#include "motion_no_motion.h" +#include "no_gyro_fusion.h" +#include "quaternion_supervisor.h" +#include "mag_disturb.h" \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl/mag_disturb.h b/bsp/boards/mimsy2-cc2538/mpl/mag_disturb.h new file mode 100644 index 0000000000..ae64064f1f --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/mag_disturb.h @@ -0,0 +1,37 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +#ifndef MLDMP_MAGDISTURB_H__ +#define MLDMP_MAGDISTURB_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + int inv_check_magnetic_disturbance(unsigned long delta_time, const long *quat, + const long *compass, const long *gravity); + + void inv_track_dip_angle(int mode, float currdip); + + inv_error_t inv_enable_magnetic_disturbance(void); + inv_error_t inv_disable_magnetic_disturbance(void); + int inv_get_magnetic_disturbance_state(void); + inv_error_t inv_set_magnetic_disturbance(int time_ms); + inv_error_t inv_disable_dip_tracking(void); + inv_error_t inv_enable_dip_tracking(void); + inv_error_t inv_init_magnetic_disturbance(void); + + float Mag3ofNormalizedLong(const long *x); + +#ifdef __cplusplus +} +#endif + + +#endif // MLDMP_MAGDISTURB_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl/motion_no_motion.h b/bsp/boards/mimsy2-cc2538/mpl/motion_no_motion.h new file mode 100644 index 0000000000..d94e003c60 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/motion_no_motion.h @@ -0,0 +1,28 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INV_MOTION_NO_MOTION_H__ +#define INV_MOTION_NO_MOTION_H__ + +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_motion_no_motion(void); +inv_error_t inv_disable_motion_no_motion(void); +inv_error_t inv_init_motion_no_motion(void); +inv_error_t inv_start_motion_no_motion(void); +inv_error_t inv_stop_motion_no_motion(void); + +inv_error_t inv_set_no_motion_time(long time_ms); + +#ifdef __cplusplus +} +#endif + +#endif // INV_MOTION_NO_MOTION_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl/no_gyro_fusion.h b/bsp/boards/mimsy2-cc2538/mpl/no_gyro_fusion.h new file mode 100644 index 0000000000..db93a257bb --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/no_gyro_fusion.h @@ -0,0 +1,34 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef MLDMP_NOGYROFUSION_H__ +#define MLDMP_NOGYROFUSION_H__ +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + inv_error_t inv_enable_no_gyro_fusion(void); + inv_error_t inv_disable_no_gyro_fusion(void); + inv_error_t inv_start_no_gyro_fusion(void); + inv_error_t inv_start_no_gyro_fusion(void); + inv_error_t inv_init_no_gyro_fusion(void); + +#ifdef __cplusplus +} +#endif + + +#endif // MLDMP_NOGYROFUSION_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpl/quaternion_supervisor.h b/bsp/boards/mimsy2-cc2538/mpl/quaternion_supervisor.h new file mode 100644 index 0000000000..9822ab0606 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpl/quaternion_supervisor.h @@ -0,0 +1,27 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INV_QUATERNION_SUPERVISOR_H__ +#define INV_QUATERNION_SUPERVISOR_H__ + +#include "mltypes.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_quaternion(void); +inv_error_t inv_disable_quaternion(void); +inv_error_t inv_init_quaternion(void); +inv_error_t inv_start_quaternion(void); +void inv_set_quaternion(long *quat); + +#ifdef __cplusplus +} +#endif + +#endif // INV_QUATERNION_SUPERVISOR_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/mpu.h b/bsp/boards/mimsy2-cc2538/mpu.h new file mode 100644 index 0000000000..bed5042021 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/mpu.h @@ -0,0 +1,386 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ + +#ifndef __MPU_H_ +#define __MPU_H_ + +#ifdef __KERNEL__ +#include +#include +#elif defined LINUX +#include +#include +#else +#include "mltypes.h" +#define __u32 uint32_t +#define __s32 int32_t +#define __s64 long long +#define __u8 uint8_t +#define __u16 uint16_t +#define __s8 int8_t +#endif + +struct mpu_read_write { + /* Memory address or register address depending on ioctl */ + __u16 address; + __u16 length; + __u8 *data; +}; + +enum mpuirq_data_type { + MPUIRQ_DATA_TYPE_MPU_DATA_READY_IRQ, + MPUIRQ_DATA_TYPE_MPU_FIFO_READY_IRQ, + MPUIRQ_DATA_TYPE_SLAVE_IRQ, + MPUIRQ_DATA_TYPE_PM_EVENT, + MPUIRQ_DATA_TYPE_NUM_TYPES, +}; + +/* User space PM event notification */ +#define MPU_PM_EVENT_SUSPEND_PREPARE (3) +#define MPU_PM_EVENT_POST_SUSPEND (4) + +/** + * struct mpuirq_data - structure to report what and when + * @interruptcount : The number of times this IRQ has occured since open + * @irqtime : monotonic time of the IRQ in ns + * @data_type : The type of this IRQ enum mpuirq_data_type + * @data : Data associated with this IRQ + */ +struct mpuirq_data { + __u32 interruptcount; +#ifdef EMPL_NO_64BIT + __s32 irqtime_ns; +#else + __s64 irqtime_ns; +#endif + __u32 data_type; + __s32 data; +}; + +enum ext_slave_config_key { + /* TODO: Remove these first six. */ + MPU_SLAVE_CONFIG_ODR_SUSPEND, + MPU_SLAVE_CONFIG_ODR_RESUME, + MPU_SLAVE_CONFIG_FSR_SUSPEND, + MPU_SLAVE_CONFIG_FSR_RESUME, + MPU_SLAVE_CONFIG_IRQ_SUSPEND, + MPU_SLAVE_CONFIG_IRQ_RESUME, + MPU_SLAVE_CONFIG_ODR, + MPU_SLAVE_CONFIG_FSR, + MPU_SLAVE_CONFIG_MOT_THS, + MPU_SLAVE_CONFIG_NMOT_THS, + MPU_SLAVE_CONFIG_MOT_DUR, + MPU_SLAVE_CONFIG_NMOT_DUR, + MPU_SLAVE_CONFIG_IRQ, + MPU_SLAVE_WRITE_REGISTERS, + MPU_SLAVE_READ_REGISTERS, + MPU_SLAVE_CONFIG_INTERNAL_REFERENCE, + /* AMI 306 specific config keys */ + MPU_SLAVE_PARAM, + MPU_SLAVE_WINDOW, + MPU_SLAVE_READWINPARAMS, + MPU_SLAVE_SEARCHOFFSET, + /* MPU3050 and MPU6050 Keys */ + MPU_SLAVE_INT_CONFIG, + MPU_SLAVE_EXT_SYNC, + MPU_SLAVE_FULL_SCALE, + MPU_SLAVE_LPF, + MPU_SLAVE_CLK_SRC, + MPU_SLAVE_DIVIDER, + MPU_SLAVE_DMP_ENABLE, + MPU_SLAVE_FIFO_ENABLE, + MPU_SLAVE_DMP_CFG1, + MPU_SLAVE_DMP_CFG2, + MPU_SLAVE_TC, + MPU_SLAVE_GYRO, + MPU_SLAVE_ADDR, + MPU_SLAVE_PRODUCT_REVISION, + MPU_SLAVE_SILICON_REVISION, + MPU_SLAVE_PRODUCT_ID, + MPU_SLAVE_GYRO_SENS_TRIM, + MPU_SLAVE_ACCEL_SENS_TRIM, + MPU_SLAVE_RAM, + /* -------------------------- */ + MPU_SLAVE_CONFIG_NUM_CONFIG_KEYS +}; + +/* For the MPU_SLAVE_CONFIG_IRQ_SUSPEND and MPU_SLAVE_CONFIG_IRQ_RESUME */ +enum ext_slave_config_irq_type { + MPU_SLAVE_IRQ_TYPE_NONE, + MPU_SLAVE_IRQ_TYPE_MOTION, + MPU_SLAVE_IRQ_TYPE_DATA_READY, +}; + +/* Structure for the following IOCTS's + * MPU_CONFIG_GYRO + * MPU_CONFIG_ACCEL + * MPU_CONFIG_COMPASS + * MPU_CONFIG_PRESSURE + * MPU_GET_CONFIG_GYRO + * MPU_GET_CONFIG_ACCEL + * MPU_GET_CONFIG_COMPASS + * MPU_GET_CONFIG_PRESSURE + * + * @key one of enum ext_slave_config_key + * @len length of data pointed to by data + * @apply zero if communication with the chip is not necessary, false otherwise + * This flag can be used to select cached data or to refresh cashed data + * cache data to be pushed later or push immediately. If true and the + * slave is on the secondary bus the MPU will first enger bypass mode + * before calling the slaves .config or .get_config funcion + * @data pointer to the data to confgure or get + */ +struct ext_slave_config { + __u8 key; + __u16 len; + __u8 apply; + void *data; +}; + +enum ext_slave_type { + EXT_SLAVE_TYPE_GYROSCOPE, + EXT_SLAVE_TYPE_ACCEL, + EXT_SLAVE_TYPE_COMPASS, + EXT_SLAVE_TYPE_PRESSURE, + /*EXT_SLAVE_TYPE_TEMPERATURE */ + + EXT_SLAVE_NUM_TYPES +}; + +enum ext_slave_id { + ID_INVALID = 0, + GYRO_ID_MPU3050, + GYRO_ID_MPU6050A2, + GYRO_ID_MPU6050B1, + GYRO_ID_MPU6050B1_NO_ACCEL, + GYRO_ID_ITG3500, + + ACCEL_ID_LIS331, + ACCEL_ID_LSM303DLX, + ACCEL_ID_LIS3DH, + ACCEL_ID_KXSD9, + ACCEL_ID_KXTF9, + ACCEL_ID_BMA150, + ACCEL_ID_BMA222, + ACCEL_ID_BMA250, + ACCEL_ID_ADXL34X, + ACCEL_ID_MMA8450, + ACCEL_ID_MMA845X, + ACCEL_ID_MPU6050, + + COMPASS_ID_AK8975, + COMPASS_ID_AK8972, + COMPASS_ID_AMI30X, + COMPASS_ID_AMI306, + COMPASS_ID_YAS529, + COMPASS_ID_YAS530, + COMPASS_ID_HMC5883, + COMPASS_ID_LSM303DLH, + COMPASS_ID_LSM303DLM, + COMPASS_ID_MMC314X, + COMPASS_ID_HSCDTD002B, + COMPASS_ID_HSCDTD004A, + + PRESSURE_ID_BMA085, +}; + +#define INV_PROD_KEY(ver, rev) (ver * 100 + rev) + +enum ext_slave_endian { + EXT_SLAVE_BIG_ENDIAN, + EXT_SLAVE_LITTLE_ENDIAN, + EXT_SLAVE_FS8_BIG_ENDIAN, + EXT_SLAVE_FS16_BIG_ENDIAN, +}; + +enum ext_slave_bus { + EXT_SLAVE_BUS_INVALID = -1, + EXT_SLAVE_BUS_PRIMARY = 0, + EXT_SLAVE_BUS_SECONDARY = 1 +}; + + +/** + * struct ext_slave_platform_data - Platform data for mpu3050 and mpu6050 + * slave devices + * + * @type: the type of slave device based on the enum ext_slave_type + * definitions. + * @irq: the irq number attached to the slave if any. + * @adapt_num: the I2C adapter number. + * @bus: the bus the slave is attached to: enum ext_slave_bus + * @address: the I2C slave address of the slave device. + * @orientation: the mounting matrix of the device relative to MPU. + * @irq_data: private data for the slave irq handler + * @private_data: additional data, user customizable. Not touched by the MPU + * driver. + * + * The orientation matricies are 3x3 rotation matricies + * that are applied to the data to rotate from the mounting orientation to the + * platform orientation. The values must be one of 0, 1, or -1 and each row and + * column should have exactly 1 non-zero value. + */ +struct ext_slave_platform_data { + __u8 type; + __u32 irq; + __u32 adapt_num; + __s32 bus; + __u8 address; + __s8 orientation[9]; + void *irq_data; + void *private_data; +}; + +struct fix_pnt_range { + __s32 mantissa; + __s32 fraction; +}; + +static inline long range_fixedpoint_to_long_mg(struct fix_pnt_range rng) +{ + return (long)(rng.mantissa * 1000 + rng.fraction / 10); +} + +struct ext_slave_read_trigger { + __u8 reg; + __u8 value; +}; + +/** + * struct ext_slave_descr - Description of the slave device for programming. + * + * @suspend: function pointer to put the device in suspended state + * @resume: function pointer to put the device in running state + * @read: function that reads the device data + * @init: function used to preallocate memory used by the driver + * @exit: function used to free memory allocated for the driver + * @config: function used to configure the device + * @get_config:function used to get the device's configuration + * + * @name: text name of the device + * @type: device type. enum ext_slave_type + * @id: enum ext_slave_id + * @read_reg: starting register address to retrieve data. + * @read_len: length in bytes of the sensor data. Typically 6. + * @endian: byte order of the data. enum ext_slave_endian + * @range: full scale range of the slave ouput: struct fix_pnt_range + * @trigger: If reading data first requires writing a register this is the + * data to write. + * + * Defines the functions and information about the slave the mpu3050 and + * mpu6050 needs to use the slave device. + */ +struct ext_slave_descr { + int (*init) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*exit) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*suspend) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*resume) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*read) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata, + __u8 *data); + int (*config) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata, + struct ext_slave_config *config); + int (*get_config) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata, + struct ext_slave_config *config); + + char *name; + __u8 type; + __u8 id; + __u8 read_reg; + __u8 read_len; + __u8 endian; + struct fix_pnt_range range; + struct ext_slave_read_trigger *trigger; +}; + +/** + * struct mpu_platform_data - Platform data for the mpu driver + * @int_config: Bits [7:3] of the int config register. + * @level_shifter: 0: VLogic, 1: VDD + * @orientation: Orientation matrix of the gyroscope + * + * Contains platform specific information on how to configure the MPU3050 to + * work on this platform. The orientation matricies are 3x3 rotation matricies + * that are applied to the data to rotate from the mounting orientation to the + * platform orientation. The values must be one of 0, 1, or -1 and each row and + * column should have exactly 1 non-zero value. + */ +struct mpu_platform_data { + __u8 int_config; + __u8 level_shifter; + __s8 orientation[9]; +}; + +#if defined __KERNEL__ || defined LINUX +#define MPU_IOCTL (0x81) /* Magic number for MPU Iocts */ +/* IOCTL commands for /dev/mpu */ + +/*-------------------------------------------------------------------------- + * Deprecated, debugging only + */ +#define MPU_SET_MPU_PLATFORM_DATA \ + _IOWR(MPU_IOCTL, 0x01, struct mpu_platform_data) +#define MPU_SET_EXT_SLAVE_PLATFORM_DATA \ + _IOWR(MPU_IOCTL, 0x01, struct ext_slave_platform_data) +/*--------------------------------------------------------------------------*/ +#define MPU_GET_EXT_SLAVE_PLATFORM_DATA \ + _IOWR(MPU_IOCTL, 0x02, struct ext_slave_platform_data) +#define MPU_GET_MPU_PLATFORM_DATA \ + _IOWR(MPU_IOCTL, 0x02, struct mpu_platform_data) +#define MPU_GET_EXT_SLAVE_DESCR \ + _IOWR(MPU_IOCTL, 0x02, struct ext_slave_descr) + +#define MPU_READ _IOWR(MPU_IOCTL, 0x10, struct mpu_read_write) +#define MPU_WRITE _IOW(MPU_IOCTL, 0x10, struct mpu_read_write) +#define MPU_READ_MEM _IOWR(MPU_IOCTL, 0x11, struct mpu_read_write) +#define MPU_WRITE_MEM _IOW(MPU_IOCTL, 0x11, struct mpu_read_write) +#define MPU_READ_FIFO _IOWR(MPU_IOCTL, 0x12, struct mpu_read_write) +#define MPU_WRITE_FIFO _IOW(MPU_IOCTL, 0x12, struct mpu_read_write) + +#define MPU_READ_COMPASS _IOR(MPU_IOCTL, 0x12, __u8) +#define MPU_READ_ACCEL _IOR(MPU_IOCTL, 0x13, __u8) +#define MPU_READ_PRESSURE _IOR(MPU_IOCTL, 0x14, __u8) + +#define MPU_CONFIG_GYRO _IOW(MPU_IOCTL, 0x20, struct ext_slave_config) +#define MPU_CONFIG_ACCEL _IOW(MPU_IOCTL, 0x21, struct ext_slave_config) +#define MPU_CONFIG_COMPASS _IOW(MPU_IOCTL, 0x22, struct ext_slave_config) +#define MPU_CONFIG_PRESSURE _IOW(MPU_IOCTL, 0x23, struct ext_slave_config) + +#define MPU_GET_CONFIG_GYRO _IOWR(MPU_IOCTL, 0x20, struct ext_slave_config) +#define MPU_GET_CONFIG_ACCEL _IOWR(MPU_IOCTL, 0x21, struct ext_slave_config) +#define MPU_GET_CONFIG_COMPASS _IOWR(MPU_IOCTL, 0x22, struct ext_slave_config) +#define MPU_GET_CONFIG_PRESSURE _IOWR(MPU_IOCTL, 0x23, struct ext_slave_config) + +#define MPU_SUSPEND _IOW(MPU_IOCTL, 0x30, __u32) +#define MPU_RESUME _IOW(MPU_IOCTL, 0x31, __u32) +/* Userspace PM Event response */ +#define MPU_PM_EVENT_HANDLED _IO(MPU_IOCTL, 0x32) + +#define MPU_GET_REQUESTED_SENSORS _IOR(MPU_IOCTL, 0x40, __u32) +#define MPU_SET_REQUESTED_SENSORS _IOW(MPU_IOCTL, 0x40, __u32) +#define MPU_GET_IRQ_TO_FIFO_DIVIDER _IOR(MPU_IOCTL, 0x41, __u16) +#define MPU_SET_IRQ_TO_FIFO_DIVIDER _IOW(MPU_IOCTL, 0x41, __u16) +#define MPU_GET_IGNORE_SYSTEM_SUSPEND _IOR(MPU_IOCTL, 0x42, __u8) +#define MPU_SET_IGNORE_SYSTEM_SUSPEND _IOW(MPU_IOCTL, 0x42, __u8) +#define MPU_GET_MLDL_STATUS _IOR(MPU_IOCTL, 0x43, __u8) +#define MPU_GET_I2C_SLAVES_ENABLED _IOR(MPU_IOCTL, 0x44, __u8) + +#endif + +#endif /* __MPU_H_ */ diff --git a/bsp/boards/mimsy2-cc2538/no_gyro_fusion.h b/bsp/boards/mimsy2-cc2538/no_gyro_fusion.h new file mode 100644 index 0000000000..db93a257bb --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/no_gyro_fusion.h @@ -0,0 +1,34 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + + +/****************************************************************************** + * + * $Id$ + * + *****************************************************************************/ + +#ifndef MLDMP_NOGYROFUSION_H__ +#define MLDMP_NOGYROFUSION_H__ +#include "mltypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + inv_error_t inv_enable_no_gyro_fusion(void); + inv_error_t inv_disable_no_gyro_fusion(void); + inv_error_t inv_start_no_gyro_fusion(void); + inv_error_t inv_start_no_gyro_fusion(void); + inv_error_t inv_init_no_gyro_fusion(void); + +#ifdef __cplusplus +} +#endif + + +#endif // MLDMP_NOGYROFUSION_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/quaternion_supervisor.h b/bsp/boards/mimsy2-cc2538/quaternion_supervisor.h new file mode 100644 index 0000000000..9822ab0606 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/quaternion_supervisor.h @@ -0,0 +1,27 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INV_QUATERNION_SUPERVISOR_H__ +#define INV_QUATERNION_SUPERVISOR_H__ + +#include "mltypes.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_enable_quaternion(void); +inv_error_t inv_disable_quaternion(void); +inv_error_t inv_init_quaternion(void); +inv_error_t inv_start_quaternion(void); +void inv_set_quaternion(long *quat); + +#ifdef __cplusplus +} +#endif + +#endif // INV_QUATERNION_SUPERVISOR_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/radio.c b/bsp/boards/mimsy2-cc2538/radio.c new file mode 100644 index 0000000000..31ef466df1 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/radio.c @@ -0,0 +1,531 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "radio" bsp module. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "board.h" +#include "cc2538rf.h" +#include "debugpins.h" +#include "leds.h" +#include "radio.h" +#include "sctimer.h" + +//=========================== defines ========================================= + +/* Bit Masks for the last byte in the RX FIFO */ +#define CRC_BIT_MASK 0x80 +#define LQI_BIT_MASK 0x7F + +/* RSSI Offset */ +#define RSSI_OFFSET 73 +#define CHECKSUM_LEN 2 + +//=========================== variables ======================================= + +typedef struct { + radio_capture_cbt startFrame_cb; + radio_capture_cbt endFrame_cb; + radio_state_t state; +} radio_vars_t; + +radio_vars_t radio_vars; + +//=========================== prototypes ====================================== + +void enable_radio_interrupts(void); +void disable_radio_interrupts(void); + +void radio_on(void); +void radio_off(void); + +void radio_error_isr(void); +void radio_isr_internal(void); + +//=========================== public ========================================== + +//===== admin + +void radio_init() { + + // clear variables + memset(&radio_vars,0,sizeof(radio_vars_t)); + + // change state + radio_vars.state = RADIOSTATE_STOPPED; + //flush fifos + CC2538_RF_CSP_ISFLUSHRX(); + CC2538_RF_CSP_ISFLUSHTX(); + + radio_off(); + + //disable radio interrupts + disable_radio_interrupts(); + + /* + This CORR_THR value should be changed to 0x14 before attempting RX. Testing has shown that + too many false frames are received if the reset value is used. Make it more likely to detect + sync by removing the requirement that both symbols in the SFD must have a correlation value + above the correlation threshold, and make sync word detection less likely by raising the + correlation threshold. + */ + HWREG(RFCORE_XREG_MDMCTRL1) = 0x14; + /* tuning adjustments for optimal radio performance; details available in datasheet */ + + HWREG(RFCORE_XREG_RXCTRL) = 0x3F; + /* Adjust current in synthesizer; details available in datasheet. */ + HWREG(RFCORE_XREG_FSCTRL) = 0x55; + + /* Makes sync word detection less likely by requiring two zero symbols before the sync word. + * details available in datasheet. + */ + HWREG(RFCORE_XREG_MDMCTRL0) = 0x85; + + /* Adjust current in VCO; details available in datasheet. */ + HWREG(RFCORE_XREG_FSCAL1) = 0x01; + /* Adjust target value for AGC control loop; details available in datasheet. */ + HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; + + /* Tune ADC performance, details available in datasheet. */ + HWREG(RFCORE_XREG_ADCTEST0) = 0x10; + HWREG(RFCORE_XREG_ADCTEST1) = 0x0E; + HWREG(RFCORE_XREG_ADCTEST2) = 0x03; + + //update CCA register to -81db as indicated by manual.. won't be used.. + HWREG(RFCORE_XREG_CCACTRL0) = 0xF8; + /* + * Changes from default values + * See User Guide, section "Register Settings Update" + */ + HWREG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */ + HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */ + HWREG(ANA_REGS_O_IVCTRL) = 0x0B; /** Bias currents */ + + /* disable the CSPT register compare function */ + HWREG(RFCORE_XREG_CSPT) = 0xFFUL; + /* + * Defaults: + * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation; + * RX and TX modes with FIFOs + */ + HWREG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_AUTOCRC; + + //poipoi disable frame filtering by now.. sniffer mode. + HWREG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; + + /* Disable source address matching and autopend */ + HWREG(RFCORE_XREG_SRCMATCH) = 0; + + /* MAX FIFOP threshold */ + HWREG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN; + + HWREG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER; + HWREG(RFCORE_XREG_FREQCTRL) = CC2538_RF_CHANNEL_MIN; + + /* Enable RF interrupts see page 751 */ + // enable_radio_interrupts(); + + //register interrupt + IntRegister(INT_RFCORERTX, radio_isr_internal); + IntRegister(INT_RFCOREERR, radio_error_isr); + + IntEnable(INT_RFCORERTX); + + /* Enable all RF Error interrupts */ + HWREG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM_M; //all errors + IntEnable(INT_RFCOREERR); + //radio_on(); + + // change state + radio_vars.state = RADIOSTATE_RFOFF; +} + +void radio_setStartFrameCb(radio_capture_cbt cb) { + radio_vars.startFrame_cb = cb; +} + +void radio_setEndFrameCb(radio_capture_cbt cb) { + radio_vars.endFrame_cb = cb; +} + +//===== reset + +void radio_reset() { + /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + //flush fifos + CC2538_RF_CSP_ISFLUSHRX(); + CC2538_RF_CSP_ISFLUSHTX(); + + /* Don't turn off if we are off as this will trigger a Strobe Error */ + if(HWREG(RFCORE_XREG_RXENABLE) != 0) { + CC2538_RF_CSP_ISRFOFF(); + } + radio_init(); +} + +//===== RF admin + +void radio_setFrequency(uint8_t frequency) { + + // change state + radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; + + radio_off(); + // configure the radio to the right frequecy + if((frequency < CC2538_RF_CHANNEL_MIN) || (frequency > CC2538_RF_CHANNEL_MAX)) { + while(1); + } + + /* Changes to FREQCTRL take effect after the next recalibration */ + HWREG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN + + (frequency - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING); + + //radio_on(); + + // change state + radio_vars.state = RADIOSTATE_FREQUENCY_SET; +} + +void radio_rfOn() { + //radio_on(); +} + +void radio_rfOff() { + + // change state + radio_vars.state = RADIOSTATE_TURNING_OFF; + radio_off(); + // wiggle debug pin + debugpins_radio_clr(); + leds_radio_off(); + //enable radio interrupts + disable_radio_interrupts(); + + // change state + radio_vars.state = RADIOSTATE_RFOFF; +} + +//===== TX + +void radio_loadPacket(uint8_t* packet, uint16_t len) { + uint8_t i=0; + + // change state + radio_vars.state = RADIOSTATE_LOADING_PACKET; + + // load packet in TXFIFO + /* + When we transmit in very quick bursts, make sure previous transmission + is not still in progress before re-writing to the TX FIFO + */ + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + CC2538_RF_CSP_ISFLUSHTX(); + + /* Send the phy length byte first */ + HWREG(RFCORE_SFR_RFDATA) = len; //crc len is included + + for(i = 0; i < len; i++) { + HWREG(RFCORE_SFR_RFDATA) = packet[i]; + } + + // change state + radio_vars.state = RADIOSTATE_PACKET_LOADED; +} + +void radio_txEnable() { + + // change state + radio_vars.state = RADIOSTATE_ENABLING_TX; + + // wiggle debug pin + debugpins_radio_set(); + leds_radio_on(); + + //do nothing -- radio is activated by the strobe on rx or tx + //radio_rfOn(); + + // change state + radio_vars.state = RADIOSTATE_TX_ENABLED; +} + +void radio_txNow() { + PORT_TIMER_WIDTH count; + + // change state + radio_vars.state = RADIOSTATE_TRANSMITTING; + + //enable radio interrupts + enable_radio_interrupts(); + + //make sure we are not transmitting already + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + // send packet by STON strobe see pag 669 + + CC2538_RF_CSP_ISTXON(); + //wait 192uS + count=0; + while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE))){ + count++; //debug + } +} + +//===== RX + +void radio_rxEnable() { + + // change state + radio_vars.state = RADIOSTATE_ENABLING_RX; + + //enable radio interrupts + + // do nothing as we do not want to receive anything yet. + // wiggle debug pin + debugpins_radio_set(); + leds_radio_on(); + + // change state + radio_vars.state = RADIOSTATE_LISTENING; +} + +void radio_rxNow() { + //empty buffer before receiving + //CC2538_RF_CSP_ISFLUSHRX(); + + //enable radio interrupts + CC2538_RF_CSP_ISFLUSHRX(); + enable_radio_interrupts(); + + CC2538_RF_CSP_ISRXON(); + // busy wait until radio really listening + while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_RX_ACTIVE))); +} + +void radio_getReceivedFrame(uint8_t* pBufRead, + uint8_t* pLenRead, + uint8_t maxBufLen, + int8_t* pRssi, + uint8_t* pLqi, + bool* pCrc) { + uint8_t crc_corr,i; + + uint8_t len=0; + + /* Check the length */ + len = HWREG(RFCORE_SFR_RFDATA); //first byte is len + + + /* Check for validity */ + if(len > CC2538_RF_MAX_PACKET_LEN) { + /* wrong len */ + CC2538_RF_CSP_ISFLUSHRX(); + return; + } + + + if(len <= CC2538_RF_MIN_PACKET_LEN) { + //too short + CC2538_RF_CSP_ISFLUSHRX(); + return; + } + + //check if this fits to the buffer + if(len > maxBufLen) { + CC2538_RF_CSP_ISFLUSHRX(); + return; + } + + // when reading the packet from the RX buffer, you get the following: + // - *[1B] length byte + // - [0-125B] packet (excluding CRC) + // - [1B] RSSI + // - *[2B] CRC + + //skip first byte is len + for(i = 0; i < len - 2; i++) { + pBufRead[i] = HWREG(RFCORE_SFR_RFDATA); + } + + *pRssi = ((int8_t)(HWREG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET); + crc_corr = HWREG(RFCORE_SFR_RFDATA); + *pCrc = crc_corr & CRC_BIT_MASK; + *pLenRead = len; + + //flush it + CC2538_RF_CSP_ISFLUSHRX(); +} + +//=========================== private ========================================= + +void enable_radio_interrupts(void){ + /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ + HWREG(RFCORE_XREG_RFIRQM0) |= ((0x06|0x02|0x01) << RFCORE_XREG_RFIRQM0_RFIRQM_S) & RFCORE_XREG_RFIRQM0_RFIRQM_M; + + /* Enable RF interrupts 1, TXDONE only */ + HWREG(RFCORE_XREG_RFIRQM1) |= ((0x02) << RFCORE_XREG_RFIRQM1_RFIRQM_S) & RFCORE_XREG_RFIRQM1_RFIRQM_M; +} + +void disable_radio_interrupts(void){ + /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ + HWREG(RFCORE_XREG_RFIRQM0) = 0; + /* Enable RF interrupts 1, TXDONE only */ + HWREG(RFCORE_XREG_RFIRQM1) = 0; +} + +void radio_on(void){ + // CC2538_RF_CSP_ISFLUSHRX(); + CC2538_RF_CSP_ISRXON(); +} + +void radio_off(void){ + /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + //CC2538_RF_CSP_ISFLUSHRX(); + + /* Don't turn off if we are off as this will trigger a Strobe Error */ + if(HWREG(RFCORE_XREG_RXENABLE) != 0) { + CC2538_RF_CSP_ISRFOFF(); + //clear fifo isr flag + HWREG(RFCORE_SFR_RFIRQF0) = ~(RFCORE_SFR_RFIRQF0_FIFOP|RFCORE_SFR_RFIRQF0_RXPKTDONE); + } +} + +//=========================== callbacks ======================================= + +//=========================== interrupt handlers ============================== + +/** +\brief Stub function for the CC2538. + +In MSP430 platforms the CPU status after servicing an interrupt can be managed +toggling some bits in a special register, e.g. CPUOFF, LPM1, etc, within the +interrupt context itself. By default, after servicing an interrupt the CPU will +be off so it makes sense to return a value and enable it if something has +happened that needs the scheduler to run (a packet has been received that needs +to be processed). Otherwise, the CPU is kept in sleep mode without even +reaching the main loop. + +In the CC2538, however, the default behaviour is the contrary. After servicing +an interrupt the CPU will be on by default and it is the responsability of the +main thread to put it back to sleep (which is already done). This means that +the scheduler will always be kicked in after servicing an interrupt. This +behaviour can be changed by modifying the SLEEPEXIT field in the SYSCTRL +regiser (see page 131 of the CC2538 manual). +*/ +kick_scheduler_t radio_isr() { + return DO_NOT_KICK_SCHEDULER; +} + +void radio_isr_internal(void) { + volatile PORT_TIMER_WIDTH capturedTime; + uint8_t irq_status0,irq_status1; + + debugpins_isr_set(); + + // capture the time + capturedTime = sctimer_readCounter(); + + // reading IRQ_STATUS + irq_status0 = HWREG(RFCORE_SFR_RFIRQF0); + irq_status1 = HWREG(RFCORE_SFR_RFIRQF1); + + IntPendClear(INT_RFCORERTX); + + //clear interrupt + HWREG(RFCORE_SFR_RFIRQF0) = 0; + HWREG(RFCORE_SFR_RFIRQF1) = 0; + + //STATUS0 Register + // start of frame event + if ((irq_status0 & RFCORE_SFR_RFIRQF0_SFD) == RFCORE_SFR_RFIRQF0_SFD) { + // change state + radio_vars.state = RADIOSTATE_RECEIVING; + if (radio_vars.startFrame_cb!=NULL) { + // call the callback + radio_vars.startFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + + //or RXDONE is full -- we have a packet. + if (((irq_status0 & RFCORE_SFR_RFIRQF0_RXPKTDONE) == RFCORE_SFR_RFIRQF0_RXPKTDONE)) { + // change state + radio_vars.state = RADIOSTATE_TXRX_DONE; + if (radio_vars.endFrame_cb!=NULL) { + // call the callback + radio_vars.endFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + + // or FIFOP is full -- we have a packet. + if (((irq_status0 & RFCORE_SFR_RFIRQF0_FIFOP) == RFCORE_SFR_RFIRQF0_FIFOP)) { + // change state + radio_vars.state = RADIOSTATE_TXRX_DONE; + if (radio_vars.endFrame_cb!=NULL) { + // call the callback + radio_vars.endFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + + //STATUS1 Register + // end of frame event --either end of tx . + if (((irq_status1 & RFCORE_SFR_RFIRQF1_TXDONE) == RFCORE_SFR_RFIRQF1_TXDONE)) { + // change state + radio_vars.state = RADIOSTATE_TXRX_DONE; + if (radio_vars.endFrame_cb!=NULL) { + // call the callback + radio_vars.endFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + debugpins_isr_clr(); + + return; +} + +void radio_error_isr(void){ + uint8_t rferrm; + + rferrm = (uint8_t)HWREG(RFCORE_XREG_RFERRM); + + if ((HWREG(RFCORE_XREG_RFERRM) & (((0x02)< + +#include "results_holder.h" +#include "ml_math_func.h" +#include "mlmath.h" +#include "start_manager.h" +#include "data_builder.h" +#include "message_layer.h" +#include "log.h" + +// These 2 status bits are used to control when the 9 axis quaternion is updated +#define INV_COMPASS_CORRECTION_SET 1 +#define INV_6_AXIS_QUAT_SET 2 + +struct results_t { + long nav_quat[4]; + long gam_quat[4]; + inv_time_t nav_timestamp; + inv_time_t gam_timestamp; + long local_field[3]; /**< local earth's magnetic field */ + long mag_scale[3]; /**< scale factor to apply to magnetic field reading */ + long compass_correction[4]; /**< quaternion going from gyro,accel quaternion to 9 axis */ + int acc_state; /**< Describes accel state */ + int got_accel_bias; /**< Flag describing if accel bias is known */ + long compass_bias_error[3]; /**< Error Squared */ + unsigned char motion_state; + unsigned int motion_state_counter; /**< Incremented for each no motion event in a row */ + long compass_count; /**< compass state internal counter */ + int got_compass_bias; /**< Flag describing if compass bias is known */ + int large_mag_field; /**< Flag describing if there is a large magnetic field */ + int compass_state; /**< Internal compass state */ + long status; + struct inv_sensor_cal_t *sensor; + float quat_confidence_interval; +}; +static struct results_t rh; + +/** @internal +* Store a quaternion more suitable for gaming. This quaternion is often determined +* using only gyro and accel. +* @param[in] quat Length 4, Quaternion scaled by 2^30 +*/ +void inv_store_gaming_quaternion(const long *quat, inv_time_t timestamp) +{ + rh.status |= INV_6_AXIS_QUAT_SET; + memcpy(&rh.gam_quat, quat, sizeof(rh.gam_quat)); + rh.gam_timestamp = timestamp; +} + +/** @internal +* Sets the quaternion adjustment from 6 axis (accel, gyro) to 9 axis quaternion. +* @param[in] data Quaternion Adjustment +* @param[in] timestamp Timestamp of when this is valid +*/ +void inv_set_compass_correction(const long *data, inv_time_t timestamp) +{ + rh.status |= INV_COMPASS_CORRECTION_SET; + memcpy(rh.compass_correction, data, sizeof(rh.compass_correction)); + rh.nav_timestamp = timestamp; +} + +/** @internal +* Gets the quaternion adjustment from 6 axis (accel, gyro) to 9 axis quaternion. +* @param[out] data Quaternion Adjustment +* @param[out] timestamp Timestamp of when this is valid +*/ +void inv_get_compass_correction(long *data, inv_time_t *timestamp) +{ + memcpy(data, rh.compass_correction, sizeof(rh.compass_correction)); + *timestamp = rh.nav_timestamp; +} + +/** Returns non-zero if there is a large magnetic field. See inv_set_large_mag_field() for setting this variable. + * @return Returns non-zero if there is a large magnetic field. + */ +int inv_get_large_mag_field() +{ + return rh.large_mag_field; +} + +/** Set to non-zero if there as a large magnetic field. See inv_get_large_mag_field() for getting this variable. + * @param[in] state value to set for magnetic field strength. Should be non-zero if it is large. + */ +void inv_set_large_mag_field(int state) +{ + rh.large_mag_field = state; +} + +/** Gets the accel state set by inv_set_acc_state() + * @return accel state. + */ +int inv_get_acc_state() +{ + return rh.acc_state; +} + +/** Sets the accel state. See inv_get_acc_state() to get the value. + * @param[in] state value to set accel state to. + */ +void inv_set_acc_state(int state) +{ + rh.acc_state = state; + return; +} + +/** Returns the motion state +* @param[out] cntr Number of previous times a no motion event has occured in a row. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +int inv_get_motion_state(unsigned int *cntr) +{ + *cntr = rh.motion_state_counter; + return rh.motion_state; +} + +/** Sets the motion state + * @param[in] state motion state where INV_NO_MOTION is not moving + * and INV_MOTION is moving. + */ +void inv_set_motion_state(unsigned char state) +{ + long set; + if (state == rh.motion_state) { + if (state == INV_NO_MOTION) { + rh.motion_state_counter++; + } else { + rh.motion_state_counter = 0; + } + return; + } + rh.motion_state_counter = 0; + rh.motion_state = state; + /* Equivalent to set = state, but #define's may change. */ + if (state == INV_MOTION) + set = INV_MSG_MOTION_EVENT; + else + set = INV_MSG_NO_MOTION_EVENT; + inv_set_message(set, (INV_MSG_MOTION_EVENT | INV_MSG_NO_MOTION_EVENT), 0); +} + +/** Sets the local earth's magnetic field +* @param[in] data Local earth's magnetic field in uT scaled by 2^16. +* Length = 3. Y typically points north, Z typically points down in +* northern hemisphere and up in southern hemisphere. +*/ +void inv_set_local_field(const long *data) +{ + memcpy(rh.local_field, data, sizeof(rh.local_field)); +} + +/** Gets the local earth's magnetic field +* @param[out] data Local earth's magnetic field in uT scaled by 2^16. +* Length = 3. Y typically points north, Z typically points down in +* northern hemisphere and up in southern hemisphere. +*/ +void inv_get_local_field(long *data) +{ + memcpy(data, rh.local_field, sizeof(rh.local_field)); +} + +/** Sets the compass sensitivity + * @param[in] data Length 3, sensitivity for each compass axis + * scaled such that 1.0 = 2^30. + */ +void inv_set_mag_scale(const long *data) +{ + memcpy(rh.mag_scale, data, sizeof(rh.mag_scale)); +} + +/** Gets the compass sensitivity + * @param[out] data Length 3, sensitivity for each compass axis + * scaled such that 1.0 = 2^30. + */ +void inv_get_mag_scale(long *data) +{ + memcpy(data, rh.mag_scale, sizeof(rh.mag_scale)); +} + +/** Gets gravity vector + * @param[out] data gravity vector in body frame scaled such that 1.0 = 2^30. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_get_gravity(long *data) +{ + data[0] = + inv_q29_mult(rh.nav_quat[1], rh.nav_quat[3]) - inv_q29_mult(rh.nav_quat[2], rh.nav_quat[0]); + data[1] = + inv_q29_mult(rh.nav_quat[2], rh.nav_quat[3]) + inv_q29_mult(rh.nav_quat[1], rh.nav_quat[0]); + data[2] = + (inv_q29_mult(rh.nav_quat[3], rh.nav_quat[3]) + inv_q29_mult(rh.nav_quat[0], rh.nav_quat[0])) - + 1073741824L; + + return INV_SUCCESS; +} + +/** Returns a quaternion based only on gyro and accel. + * @param[out] data 6-axis gyro and accel quaternion scaled such that 1.0 = 2^30. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_get_6axis_quaternion(long *data) +{ + memcpy(data, rh.gam_quat, sizeof(rh.gam_quat)); + return INV_SUCCESS; +} + +/** Returns a quaternion. + * @param[out] data 9-axis quaternion scaled such that 1.0 = 2^30. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_get_quaternion(long *data) +{ + if (rh.status & (INV_COMPASS_CORRECTION_SET | INV_6_AXIS_QUAT_SET)) { + inv_q_mult(rh.compass_correction, rh.gam_quat, rh.nav_quat); + rh.status &= ~(INV_COMPASS_CORRECTION_SET | INV_6_AXIS_QUAT_SET); + } + memcpy(data, rh.nav_quat, sizeof(rh.nav_quat)); + return INV_SUCCESS; +} + +/** Returns a quaternion. + * @param[out] data 9-axis quaternion. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_get_quaternion_float(float *data) +{ + long ldata[4]; + inv_error_t result = inv_get_quaternion(ldata); + data[0] = inv_q30_to_float(ldata[0]); + data[1] = inv_q30_to_float(ldata[1]); + data[2] = inv_q30_to_float(ldata[2]); + data[3] = inv_q30_to_float(ldata[3]); + return result; +} + +/** Returns a quaternion with accuracy and timestamp. + * @param[out] data 9-axis quaternion scaled such that 1.0 = 2^30. + * @param[out] accuracy Accuracy of quaternion, 0-3, where 3 is most accurate. + * @param[out] timestamp Timestamp of this quaternion in nanoseconds + */ +void inv_get_quaternion_set(long *data, int *accuracy, inv_time_t *timestamp) +{ + inv_get_quaternion(data); + *timestamp = inv_get_last_timestamp(); + if (inv_get_compass_on()) { + *accuracy = inv_get_mag_accuracy(); + } else if (inv_get_gyro_on()) { + *accuracy = inv_get_gyro_accuracy(); + }else if (inv_get_accel_on()) { + *accuracy = inv_get_accel_accuracy(); + } else { + *accuracy = 0; + } +} + +/** Callback that gets called everytime there is new data. It is + * registered by inv_start_results_holder(). + * @param[in] sensor_cal New sensor data to process. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_generate_results(struct inv_sensor_cal_t *sensor_cal) +{ + rh.sensor = sensor_cal; + return INV_SUCCESS; +} + +/** Function to turn on this module. This is automatically called by + * inv_enable_results_holder(). Typically not called by users. + * @return Returns INV_SUCCESS if successful or an error code if not. + */ +inv_error_t inv_start_results_holder(void) +{ + inv_register_data_cb(inv_generate_results, INV_PRIORITY_RESULTS_HOLDER, + INV_GYRO_NEW | INV_ACCEL_NEW | INV_MAG_NEW); + return INV_SUCCESS; +} + +/** Initializes results holder. This is called automatically by the +* enable function inv_enable_results_holder(). It may be called any time the feature is enabled, but +* is typically not needed to be called by outside callers. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_init_results_holder(void) +{ + memset(&rh, 0, sizeof(rh)); + rh.mag_scale[0] = 1L<<30; + rh.mag_scale[1] = 1L<<30; + rh.mag_scale[2] = 1L<<30; + rh.compass_correction[0] = 1L<<30; + rh.gam_quat[0] = 1L<<30; + rh.nav_quat[0] = 1L<<30; + rh.quat_confidence_interval = (float)M_PI; + return INV_SUCCESS; +} + +/** Turns on storage of results. +*/ +inv_error_t inv_enable_results_holder() +{ + inv_error_t result; + result = inv_init_results_holder(); + if ( result ) { + return result; + } + + result = inv_register_mpl_start_notification(inv_start_results_holder); + return result; +} + +/** Sets state of if we know the accel bias. + * @return return 1 if we know the accel bias, 0 if not. + * it is set with inv_set_accel_bias_found() + */ +int inv_got_accel_bias() +{ + return rh.got_accel_bias; +} + +/** Sets whether we know the accel bias + * @param[in] state Set to 1 if we know the accel bias. + * Can be retrieved with inv_got_accel_bias() + */ +void inv_set_accel_bias_found(int state) +{ + rh.got_accel_bias = state; +} + +/** Sets state of if we know the compass bias. + * @return return 1 if we know the compass bias, 0 if not. + * it is set with inv_set_compass_bias_found() + */ +int inv_got_compass_bias() +{ + return rh.got_compass_bias; +} + +/** Sets whether we know the compass bias + * @param[in] state Set to 1 if we know the compass bias. + * Can be retrieved with inv_got_compass_bias() + */ +void inv_set_compass_bias_found(int state) +{ + rh.got_compass_bias = state; +} + +/** Sets the compass state. + * @param[in] state Compass state. It can be retrieved with inv_get_compass_state(). + */ +void inv_set_compass_state(int state) +{ + rh.compass_state = state; +} + +/** Get's the compass state + * @return the compass state that was set with inv_set_compass_state() + */ +int inv_get_compass_state() +{ + return rh.compass_state; +} + +/** Set compass bias error. See inv_get_compass_bias_error() + * @param[in] bias_error Set's how accurate we know the compass bias. It is the + * error squared. + */ +void inv_set_compass_bias_error(const long *bias_error) +{ + memcpy(rh.compass_bias_error, bias_error, sizeof(rh.compass_bias_error)); +} + +/** Get's compass bias error. See inv_set_compass_bias_error() for setting. + * @param[out] bias_error Accuracy as to how well the compass bias is known. It is the error squared. + */ +void inv_get_compass_bias_error(long *bias_error) +{ + memcpy(bias_error, rh.compass_bias_error, sizeof(rh.compass_bias_error)); +} + +/** + * @brief Returns 3-element vector of accelerometer data in body frame + * with gravity removed + * @param[out] data 3-element vector of accelerometer data in body frame + * with gravity removed + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_linear_accel(long *data) +{ + long gravity[3]; + + if (data != NULL) + { + inv_get_accel_set(data, NULL, NULL); + inv_get_gravity(gravity); + data[0] -= gravity[0] >> 14; + data[1] -= gravity[1] >> 14; + data[2] -= gravity[2] >> 14; + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** + * @brief Returns 3-element vector of accelerometer data in body frame + * @param[out] data 3-element vector of accelerometer data in body frame + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_accel(long *data) +{ + if (data != NULL) { + inv_get_accel_set(data, NULL, NULL); + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** + * @brief Returns 3-element vector of accelerometer float data + * @param[out] data 3-element vector of accelerometer float data + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_accel_float(float *data) +{ + long tdata[3]; + unsigned char i; + + if (data != NULL && !inv_get_accel(tdata)) { + for (i = 0; i < 3; ++i) { + data[i] = ((float)tdata[i] / (1L << 16)); + } + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** + * @brief Returns 3-element vector of gyro float data + * @param[out] data 3-element vector of gyro float data + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_gyro_float(float *data) +{ + long tdata[3]; + unsigned char i; + + if (data != NULL) { + inv_get_gyro_set(tdata, NULL, NULL); + for (i = 0; i < 3; ++i) { + data[i] = ((float)tdata[i] / (1L << 16)); + } + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** Set 9 axis 95% heading confidence interval for quaternion +* @param[in] ci Confidence interval in radians. +*/ +void inv_set_heading_confidence_interval(float ci) +{ + rh.quat_confidence_interval = ci; +} + +/** Get 9 axis 95% heading confidence interval for quaternion +* @return Confidence interval in radians. +*/ +float inv_get_heading_confidence_interval(void) +{ + return rh.quat_confidence_interval; +} + +/** + * @brief Returns 3-element vector of linear accel float data + * @param[out] data 3-element vector of linear aceel float data + * @return INV_SUCCESS if successful + * INV_ERROR_INVALID_PARAMETER if invalid input pointer + */ +inv_error_t inv_get_linear_accel_float(float *data) +{ + long tdata[3]; + unsigned char i; + + if (data != NULL && !inv_get_linear_accel(tdata)) { + for (i = 0; i < 3; ++i) { + data[i] = ((float)tdata[i] / (1L << 16)); + } + return INV_SUCCESS; + } + else { + return INV_ERROR_INVALID_PARAMETER; + } +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/results_holder.h b/bsp/boards/mimsy2-cc2538/results_holder.h new file mode 100644 index 0000000000..1261f91a35 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/results_holder.h @@ -0,0 +1,81 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" + +#ifndef INV_RESULTS_HOLDER_H__ +#define INV_RESULTS_HOLDER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define INV_MOTION 0x0001 +#define INV_NO_MOTION 0x0002 + + /**************************************************************************/ + /* The value of inv_get_gyro_sum_of_sqr is scaled such the (1 dps)^2 = */ + /* 2^GYRO_MAG_SQR_SHIFT. This number must be >=0 and even. */ + /* The value of inv_accel_sum_of_sqr is scaled such that (1g)^2 = */ + /* 2^ACC_MAG_SQR_SHIFT */ + /**************************************************************************/ +#define ACC_MAG_SQR_SHIFT 16 + +void inv_store_gaming_quaternion(const long *quat, inv_time_t timestamp); + +// States +#define SF_NORMAL 0 +#define SF_UNCALIBRATED 1 +#define SF_STARTUP_SETTLE 2 +#define SF_FAST_SETTLE 3 +#define SF_DISTURBANCE 4 +#define SF_SLOW_SETTLE 5 + +int inv_get_acc_state(void); +void inv_set_acc_state(int state); +int inv_get_motion_state(unsigned int *cntr); +void inv_set_motion_state(unsigned char state); +inv_error_t inv_get_gravity(long *data); +inv_error_t inv_get_6axis_quaternion(long *data); +inv_error_t inv_get_quaternion(long *data); +inv_error_t inv_get_quaternion_float(float *data); +void inv_get_quaternion_set(long *data, int *accuracy, inv_time_t *timestamp); + +inv_error_t inv_enable_results_holder(void); +inv_error_t inv_init_results_holder(void); + +/* Magnetic Field Parameters*/ +void inv_set_local_field(const long *data); +void inv_get_local_field(long *data); +void inv_set_mag_scale(const long *data); +void inv_get_mag_scale(long *data); +void inv_set_compass_correction(const long *data, inv_time_t timestamp); +void inv_get_compass_correction(long *data, inv_time_t *timestamp); +int inv_got_compass_bias(void); +void inv_set_compass_bias_found(int state); +int inv_get_large_mag_field(void); +void inv_set_large_mag_field(int state); +void inv_set_compass_state(int state); +int inv_get_compass_state(void); +void inv_set_compass_bias_error(const long *bias_error); +void inv_get_compass_bias_error(long *bias_error); +inv_error_t inv_get_linear_accel(long *data); +inv_error_t inv_get_accel(long *data); +inv_error_t inv_get_accel_float(float *data); +inv_error_t inv_get_gyro_float(float *data); +inv_error_t inv_get_linear_accel_float(float *data); +void inv_set_heading_confidence_interval(float ci); +float inv_get_heading_confidence_interval(void); + +int inv_got_accel_bias(void); +void inv_set_accel_bias_found(int state); + + +#ifdef __cplusplus +} +#endif + +#endif // INV_RESULTS_HOLDER_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/sctimer.c b/bsp/boards/mimsy2-cc2538/sctimer.c new file mode 100644 index 0000000000..eb3fa65786 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/sctimer.c @@ -0,0 +1,95 @@ +/** +\brief A timer module with only a single compare value. + +\author Tengfei Chang April 2017 +*/ + +#include "board_info.h" +#include "sctimer.h" +#include "sleepmode.h" +#include "debugpins.h" +#include + +// ========================== define ========================================== + +#define TIMERLOOP_THRESHOLD 0xffffff // 511 seconds @ 32768Hz clock +#define MINIMUM_COMPAREVALE_ADVANCE 10 + +// ========================== variable ======================================== + +typedef struct { + sctimer_cbt sctimer_cb; +} sctimer_vars_t; + +sctimer_vars_t sctimer_vars; + + +// ========================== private ========================================= + +void sctimer_isr_internal(void); + +// ========================== protocol ========================================= + +/** +\brief Initialization sctimer. +*/ +void sctimer_init(void){ + memset(&sctimer_vars, 0, sizeof(sctimer_vars_t)); + IntRegister(INT_SMTIM, sctimer_isr_internal); + IntDisable(INT_SMTIM); +} + +void sctimer_set_callback(sctimer_cbt cb){ + sctimer_vars.sctimer_cb = cb; +} + +/** +\brief set compare interrupt +*/ +void sctimer_setCompare(uint32_t val){ + uint32_t val_debug; + val_debug = SleepModeTimerCountGet(); + IntEnable(INT_SMTIM); + if (SleepModeTimerCountGet() - val < TIMERLOOP_THRESHOLD){ + // the timer is already late, schedule the ISR right now manually + IntPendSet(INT_SMTIM); + } else { + if (val-SleepModeTimerCountGet(), March 2015. +*/ + +#include "adc_sensor.h" +#include "board.h" +#include "sensors.h" + +#include "adxl346.h" +#include "max44009.h" +#include "sht21.h" + +//=========================== defines ========================================= + +//=========================== typedef ========================================= + +//=========================== variables ======================================= + +sensors_vars_t sensors_vars; + +//=========================== prototype ======================================= + +//=========================== public ========================================== + +/** + \brief Initialize sensors on the board +*/ +void sensors_init(void) { + + memset(&sensors_vars,0,sizeof(sensors_vars_t)); + + if (sht21_is_present()==1) { + sht21_init(); + sensors_vars.sensorsTypes[SENSOR_TEMPERATURE] = 1; + sensors_vars.sensorsTypes[SENSOR_HUMIDITY] = 1; + } + + if (max44009_is_present()==1) { + max44009_init(); + sensors_vars.sensorsTypes[SENSOR_LIGHT] = 1; + } + + if (adxl346_is_present()==1) { + adxl346_init(); + sensors_vars.sensorsTypes[SENSOR_XACCELERATION] = 1; + sensors_vars.sensorsTypes[SENSOR_YACCELERATION] = 1; + sensors_vars.sensorsTypes[SENSOR_ZACCELERATION] = 1; + } + + adc_sensor_init(); + sensors_vars.sensorsTypes[SENSOR_ADCTEMPERATURE] = 1; + +} + +/** + \brief Returns a bool value indicating if a given sensor is present + \param[in] sensorType sensor type polled. + \param[out] returnVal presence of the sensor. +*/ +bool sensors_is_present(uint8_t sensorType) { + return sensors_vars.sensorsTypes[sensorType]; +} + +/** + \brief Returns the callback for reading data from a given sensor + \param[in] sensorType sensor type used to associate the callback. + \param[out] callback for reading data. +*/ +callbackRead_cbt sensors_getCallbackRead(uint8_t sensorType) { + + switch (sensorType) { + case SENSOR_TEMPERATURE: + return &sht21_read_temperature; + case SENSOR_HUMIDITY: + return &sht21_read_humidity; + case SENSOR_LIGHT: + return &max44009_read_light; + case SENSOR_XACCELERATION: + return (callbackRead_cbt)&adxl346_read_x; + case SENSOR_YACCELERATION: + return (callbackRead_cbt)&adxl346_read_y; + case SENSOR_ZACCELERATION: + return (callbackRead_cbt)&adxl346_read_z; + case SENSOR_ADCTEMPERATURE: + return &adc_sens_read_temperature; + default: + return NULL; + } + +} + +/** + \brief Returns the callback for converting data from a given sensor + \param[in] sensorType sensor type used to associate the callback. + \param[out] callback for converting data. +*/ +callbackConvert_cbt sensors_getCallbackConvert(uint8_t sensorType) { + + switch (sensorType) { + case SENSOR_TEMPERATURE: + return &sht21_convert_temperature; + case SENSOR_HUMIDITY: + return &sht21_convert_humidity; + case SENSOR_LIGHT: + return &max44009_convert_light; + case SENSOR_XACCELERATION: + return NULL; + case SENSOR_YACCELERATION: + return NULL; + case SENSOR_ZACCELERATION: + return NULL; + case SENSOR_ADCTEMPERATURE: + return &adc_sens_convert_temperature; + default: + return NULL; + } + +} + +//=========================== private ========================================= diff --git a/bsp/boards/mimsy2-cc2538/servo.c b/bsp/boards/mimsy2-cc2538/servo.c new file mode 100644 index 0000000000..c5f0daf9e4 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/servo.c @@ -0,0 +1,133 @@ +/* + * servo.c + * + * Created on: Dec 4, 2017 + * Author: kilberg + */ + +/****************************************************************************** +* INCLUDES +*/ +#include +//#include "bsp.h" +//#include "bsp_led.h" +#include "gptimer.h" +#include "sys_ctrl.h" +#include "headers/hw_gptimer.h" +#include "headers/hw_ints.h" +#include "gpio.h" +#include "interrupt.h" +//#include "led.h" +#include "headers/hw_memmap.h" +#include "headers/hw_gpio.h" +#include "ioc.h" + + +//Global VAriables *************************************************************** +float servo_scale; + +//refresh width and pulse widths are in ms +void servo_init(uint32_t timer,int refresh_rate,float center){ + + uint32_t pwmTimerClkEnable; + uint32_t pwmTimerBase; + uint32_t freqCnt=SysCtrlClockGet()*refresh_rate/1000; //number of ticks in one period is period * clock rate + uint8_t pre_cnt=(freqCnt>>16)&0xFF; //prescaler count should have the upper bits 16 to 23 of the count + uint16_t timer_cnt=freqCnt & 0xFFFF; //lower 16 bits of count value + float neutral_pulse_width = center; //pulse width for neutral pos + + //calc pulse widths for servo neutral + + uint32_t neutral_match_count = neutral_pulse_width / 1000 * SysCtrlClockGet(); //match set + uint16_t match_lower = neutral_match_count & 0xFFFF; + uint8_t match_upper = (neutral_match_count >> 16) & 0xFF; + + switch(timer){ + + case 0: + pwmTimerClkEnable=SYS_CTRL_PERIPH_GPT0; + pwmTimerBase=GPTIMER0_BASE; + // timerIntA=INT_TIMER0A; + //timerIntB=INT_TIMER0B; + break; + + case 1: + pwmTimerClkEnable=SYS_CTRL_PERIPH_GPT1; + pwmTimerBase=GPTIMER1_BASE; + //timerIntA=INT_TIMER1A; + //timerIntB=INT_TIMER1B; + break; + + case 2: + pwmTimerClkEnable=SYS_CTRL_PERIPH_GPT2; + pwmTimerBase=GPTIMER2_BASE; + // timerIntA=INT_TIMER2A; + // timerIntB=INT_TIMER2B; + break; + + case 3: + pwmTimerClkEnable=SYS_CTRL_PERIPH_GPT3; + pwmTimerBase=GPTIMER3_BASE; + // timerIntA=INT_TIMER3A; + // timerIntB=INT_TIMER3B; + break; + + + } + + + SysCtrlPeripheralEnable(pwmTimerClkEnable); //enables timer module + + TimerConfigure(pwmTimerBase, GPTIMER_CFG_SPLIT_PAIR |GPTIMER_CFG_A_PWM | GPTIMER_CFG_B_PWM); //configures timers as pwm timers + TimerPrescaleSet(pwmTimerBase,GPTIMER_A,pre_cnt); //load upper 8 bits of timer count + TimerLoadSet(pwmTimerBase,GPTIMER_A,timer_cnt); //load lower 16 bits of timer count + + TimerControlLevel(pwmTimerBase,GPTIMER_A,true); //active high pwm + + TimerPrescaleSet(pwmTimerBase,GPTIMER_B,pre_cnt); //load upper 8 bits of timer count + TimerLoadSet(pwmTimerBase,GPTIMER_B,timer_cnt); //load lower 16 bits of timer count + + TimerControlLevel(pwmTimerBase,GPTIMER_B,true); //active high pwm + + + IOCPinConfigPeriphOutput(GPIO_D_BASE,GPIO_PIN_1,IOC_MUX_OUT_SEL_GPT3_ICP1); //maps pwm1 output to pin1 + IOCPinConfigPeriphOutput(GPIO_D_BASE,GPIO_PIN_2,IOC_MUX_OUT_SEL_GPT3_ICP2); + + //set match registers to determine pulse width + TimerMatchSet(pwmTimerBase,GPTIMER_A,match_lower); + TimerPrescaleMatchSet(pwmTimerBase,GPTIMER_A,match_upper); + + TimerEnable(pwmTimerBase,GPTIMER_A); + + TimerMatchSet(pwmTimerBase,GPTIMER_B,match_lower); + TimerPrescaleMatchSet(pwmTimerBase,GPTIMER_B,match_upper); + + TimerEnable(pwmTimerBase,GPTIMER_B); + + GPIOPinTypeTimer(GPIO_D_BASE,GPIO_PIN_1); //enables hw muxing of pin outputs + + IOCPadConfigSet(GPIO_D_BASE,GPIO_PIN_1,IOC_OVERRIDE_OE|IOC_OVERRIDE_PUE); // enables pins as outputs, necessary for this code to work correctly + + GPIOPinTypeTimer(GPIO_D_BASE,GPIO_PIN_2); //enables hw muxing of pin outputs + IOCPadConfigSet(GPIO_D_BASE,GPIO_PIN_2,IOC_OVERRIDE_OE|IOC_OVERRIDE_PUE); // enables pins as outputs, necessary for this code to work correctly + + +} + +//time based servo controller. input is 1-2 ms +void servo_rotate_time(float pulse_width,int servo){ + //calc pulse widths for servo neutral + + uint32_t neutral_match_count = pulse_width / 1000 * SysCtrlClockGet(); //match set + uint16_t match_lower = neutral_match_count & 0xFFFF; + uint8_t match_upper = (neutral_match_count >> 16) & 0xFF; + if (servo==0){ + TimerMatchSet(GPTIMER3_BASE,GPTIMER_A,match_lower); + TimerPrescaleMatchSet(GPTIMER3_BASE,GPTIMER_A,match_upper); + } + else if(servo==1){ + TimerMatchSet(GPTIMER3_BASE,GPTIMER_B,match_lower); + TimerPrescaleMatchSet(GPTIMER3_BASE,GPTIMER_B,match_upper); + } +} + diff --git a/bsp/boards/mimsy2-cc2538/source/adc.c b/bsp/boards/mimsy2-cc2538/source/adc.c new file mode 100644 index 0000000000..69144d7faf --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/adc.c @@ -0,0 +1,279 @@ +/****************************************************************************** +* Filename: adc.c +* Revised: $Date: 2013-03-24 11:41:19 +0100 (Sun, 24 Mar 2013) $ +* Revision: $Revision: 9521 $ +* +* Description: Driver for the SOC ADC Module. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup adc_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include "debug.h" +#include "interrupt.h" +#include "adc.h" + +//***************************************************************************** +// +//! Registers an interrupt handler for ADC interrupt +//! +//! \param pfnHandler is a pointer to the function called when the +//! SOC ADC interrupt occurs. +//! +//! This function does the actual registering of the interrupt handler, which +//! enables the global interrupt in the interrupt controller. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +SOCADCIntRegister(void (*pfnHandler)(void)) +{ + // + // Register the interrupt handler. + // + IntRegister(INT_ADC0, pfnHandler); + + // + // Enable the ADC interrupt. + // + IntEnable(INT_ADC0); +} + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the ADC interrupt +//! +//! This function does the actual unregistering of the interrupt handler. This +//! function clears the handler to be called when an ADC interrupt occurs +//! and masks off the interrupt in the interrupt controller so that the +//! interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +SOCADCIntUnregister(void) +{ + // + // Disable the interrupt. + // + IntDisable(INT_ADC0); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_ADC0); +} + +//***************************************************************************** +// +//! Configure ADC conversion for a single channel +//! +//! \param ui32Resolution is the resolution of the conversion. +//! \param ui32Reference is the reference voltage to be used for the conversion. +//! +//! This function configures the ADC for a single channel conversion. +//! The \e ui32Resolution parameter must be one of: +//! \b SOCADC_7_BIT, \b SOCADC_9_BIT, \b SOCADC_10_BIT or \b SOCADC_12_BIT. +//! The reference voltage is set using the \e ui32Reference parameter, which +//! must be configured as one of the following: +//! \b SOCADC_REF_INTERNAL for internal reference, +//! \b SOCADC_REF_EXT_AIN7 for external reference on pin AIN7 (pad PA7), +//! \b SOCADC_REF_AVDD5 for external AVDD5 pin, +//! \b SOCADC_REF_EXT_AIN67 for external reference on differential input pins +//! AIN6-AIN7 (Pads PA6-PA7). +//! +//! \note A single conversion triggers an interrupt if this has been registered +//! using SOCADCIntRegister(). +//! +//! \sa SOCADCSingleStart() and SOCADCIntRegister(). +//! +//! \return None +// +//***************************************************************************** +void +SOCADCSingleConfigure(uint32_t ui32Resolution, uint32_t ui32Reference) +{ + uint32_t ui32Reg; + + // + // Check the arguments. + // + ASSERT((ui32Resolution == SOCADC_7_BIT) || + (ui32Resolution == SOCADC_9_BIT) || + (ui32Resolution == SOCADC_10_BIT) || + (ui32Resolution == SOCADC_12_BIT)); + ASSERT((ui32Reference == SOCADC_REF_INTERNAL) || + (ui32Reference == SOCADC_REF_EXT_AIN7) || + (ui32Reference == SOCADC_REF_AVDD5) || + (ui32Reference == SOCADC_REF_EXT_AIN67)); + + // + // Stop random generator + // + HWREG(SOC_ADC_ADCCON1) = 0x3c; + + ui32Reg = HWREG(SOC_ADC_ADCCON3) & ~(SOC_ADC_ADCCON3_EREF_M | + SOC_ADC_ADCCON3_EDIV_M); + HWREG(SOC_ADC_ADCCON3) = ui32Reg | ui32Resolution | ui32Reference; +} + +//***************************************************************************** +// +//! Start a configured single conversion +//! +//! \param ui32Channel is the input channel to use for the conversion. +//! +//! This function initiates a configured single channel conversion. +//! The input channel is set using the \e ui32Channel parameter. +//! This parameter must be configured as one of the following values: +//! \b SOCADC_AIN0 for single ended input Pad PA0 +//! \b SOCADC_AIN1 for single ended input Pad PA1 +//! \b SOCADC_AIN2 for single ended input Pad PA2 +//! \b SOCADC_AIN3 for single ended input Pad PA3 +//! \b SOCADC_AIN4 for single ended input Pad PA4 +//! \b SOCADC_AIN5 for single ended input Pad PA5 +//! \b SOCADC_AIN6 for single ended input Pad PA6 +//! \b SOCADC_AIN7 for single ended input Pad PA7 +//! \b SOCADC_AIN01 for differential Pads PA0-PA1 +//! \b SOCADC_AIN23 for differential Pads PA2-PA3 +//! \b SOCADC_AIN45 for differential Pads PA4-PA5 +//! \b SOCADC_AIN67 for differential Pads PA6-PA7 +//! \b SOCADC_GND for Ground as input +//! \b SOCADC_TEMP_SENS for on-chip temperature sensor +//! \b SOCADC_VDD for Vdd/3 +//! +//! \note A single conversion triggers an interrupt if this has been registered +//! using SOCADCIntRegister(). +//! +//! \sa SOCADCSingleConfigure() and SOCADCIntRegister(). +//! +//! \return None +// +//***************************************************************************** +void +SOCADCSingleStart(uint32_t ui32Channel) +{ + uint32_t ui32Reg; + + // + // Check the arguments. + // + ASSERT((ui32Channel == SOCADC_AIN0) || + (ui32Channel == SOCADC_AIN1) || + (ui32Channel == SOCADC_AIN2) || + (ui32Channel == SOCADC_AIN3) || + (ui32Channel == SOCADC_AIN4) || + (ui32Channel == SOCADC_AIN5) || + (ui32Channel == SOCADC_AIN6) || + (ui32Channel == SOCADC_AIN7) || + (ui32Channel == SOCADC_AIN01) || + (ui32Channel == SOCADC_AIN23) || + (ui32Channel == SOCADC_AIN45) || + (ui32Channel == SOCADC_AIN67) || + (ui32Channel == SOCADC_GND) || + (ui32Channel == SOCADC_TEMP_SENS) || + (ui32Channel == SOCADC_VDD)); + + // + // Program selected channel, this indirectly starts the conversion + // + ui32Reg = HWREG(SOC_ADC_ADCCON3) & ~(SOC_ADC_ADCCON3_ECH_M); + HWREG(SOC_ADC_ADCCON3) = ui32Reg | ui32Channel; +} + +//***************************************************************************** +// +//! Get data value from conversion +//! +//! This function gets the latest conversion data result of the programmed +//! conversion. The function returns 16 bits of data, but depending on the +//! programmed precision, only part of the data is significant. +//! The following defined bit masks can be used to extract the significant data +//! depending on the decimation rate: +//! \b SOCADC_7_BIT_MASK, \b SOCADC_9_BIT_MASK, +//! \b SOCADC_10_BIT_MASK and \b SOCADC_12_BIT_MASK +//! +//! \sa SOCADCEndOfCOnversionGet(). +//! +//! \return Data conversion value +// +//***************************************************************************** +uint16_t +SOCADCDataGet(void) +{ + uint32_t ui32Reg; + + ui32Reg = HWREG(SOC_ADC_ADCL) & SOC_ADC_ADCL_ADC_M; + ui32Reg |= ((HWREG(SOC_ADC_ADCH) & SOC_ADC_ADCH_ADC_M) << 8); + + return ((uint16_t) ui32Reg); +} + +//***************************************************************************** +// +//! Check if conversion is done +//! +//! This function can be used to query the status of the conversion. +//! +//! \return true if conversion is done, otherwise false. +// +//***************************************************************************** +bool +SOCADCEndOfCOnversionGet(void) +{ + return((HWREG(SOC_ADC_ADCCON1) & SOC_ADC_ADCCON1_EOC) ? true : false); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + diff --git a/bsp/boards/mimsy2-cc2538/source/adc.h b/bsp/boards/mimsy2-cc2538/source/adc.h new file mode 100644 index 0000000000..5e5c682c1a --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/adc.h @@ -0,0 +1,150 @@ +/****************************************************************************** +* Filename: adc.h +* Revised: $Date: 2013-01-21 15:25:21 +0100 (Mon, 21 Jan 2013) $ +* Revision: $Revision: 9178 $ +* +* Description: Prototypes for the SOC ADC API +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __ADC_H__ +#define __ADC_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// Values that can be passed to SOCADCSingleConfigure as the ui32Resolution +// parameter (Resolution or decimation rate). +// +//***************************************************************************** +#define SOCADC_7_BIT 0x00000000 // 64 decimation rate ( 7 bits ENOB) +#define SOCADC_9_BIT 0x00000010 // 128 decimation rate ( 9 bits ENOB) +#define SOCADC_10_BIT 0x00000020 // 256 decimation rate (10 bits ENOB) +#define SOCADC_12_BIT 0x00000030 // 512 decimation rate (12 bits ENOB) + +//***************************************************************************** +// +// The following defines can be used to extract the significant data +// depending on the chosen decimation rate +// +//***************************************************************************** +#define SOCADC_7_BIT_MASK 0xfe00 // Mask for getting data( 7 bits ENOB) +#define SOCADC_9_BIT_MASK 0xff80 // Mask for getting data( 9 bits ENOB) +#define SOCADC_10_BIT_MASK 0xffc0 // Mask for getting data(10 bits ENOB) +#define SOCADC_12_BIT_MASK 0xfff0 // Mask for getting data(12 bits ENOB) + +#define SOCADC_7_BIT_RSHIFT 9 // Mask for getting data( 7 bits ENOB) +#define SOCADC_9_BIT_RSHIFT 7 // Mask for getting data( 9 bits ENOB) +#define SOCADC_10_BIT_RSHIFT 6 // Mask for getting data(10 bits ENOB) +#define SOCADC_12_BIT_RSHIFT 4 // Mask for getting data(12 bits ENOB) + +//***************************************************************************** +// +// Values that can be passed to SOCADCSingleConfigure as the +// ui32Reference parameter (reference voltage). +// +//***************************************************************************** +#define SOCADC_REF_INTERNAL 0x00000000 // Internal reference +#define SOCADC_REF_EXT_AIN7 0x00000040 // External reference on AIN7 pin +#define SOCADC_REF_AVDD5 0x00000080 // AVDD5 pin +#define SOCADC_REF_EXT_AIN67 0x000000c0 // External reference on AIN6-AIN7 + // differential input pins +//***************************************************************************** +// +// Values that can be passed to SOCADCSingleStart as the ui32Channel +// parameter (input channel). +// +//***************************************************************************** +#define SOCADC_AIN0 0x00000000 // Single ended Pad PA0 +#define SOCADC_AIN1 0x00000001 // Single ended Pad PA1 +#define SOCADC_AIN2 0x00000002 // Single ended Pad PA2 +#define SOCADC_AIN3 0x00000003 // Single ended Pad PA3 +#define SOCADC_AIN4 0x00000004 // Single ended Pad PA4 +#define SOCADC_AIN5 0x00000005 // Single ended Pad PA5 +#define SOCADC_AIN6 0x00000006 // Single ended Pad PA6 +#define SOCADC_AIN7 0x00000007 // Single ended Pad PA7 +#define SOCADC_AIN01 0x00000008 // Differential Pads PA0-PA1 +#define SOCADC_AIN23 0x00000008 // Differential Pads PA2-PA3 +#define SOCADC_AIN45 0x00000008 // Differential Pads PA4-PA5 +#define SOCADC_AIN67 0x00000008 // Differential Pads PA6-PA7 +#define SOCADC_GND 0x0000000c // Ground +#define SOCADC_TEMP_SENS 0x0000000e // On-chip temperature sensor +#define SOCADC_VDD 0x0000000f // Vdd/3 + +//***************************************************************************** +// +// Values that can be passed to SOCADCStart as the ui32StartSelect +// parameter (Start Selection Criteria). +// +//***************************************************************************** +#define SOCADC_FULLSPEED 0x00000010 // Full speed, do not wait for triggers +#define SOCADC_TIMER_COMP 0x00000020 // GP Timer 0, Timber A compare event +#define SOCADC_ONE_SHOT 0x00000030 // Do a single sample + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void SOCADCIntRegister(void (*pfnHandler)(void)); +extern void SOCADCIntUnregister(void); + +extern void SOCADCSingleConfigure(uint32_t ui32Resolution, + uint32_t ui32Reference); +extern void SOCADCSingleStart(uint32_t ui32Channel); + +extern uint16_t SOCADCDataGet(void); +extern bool SOCADCEndOfCOnversionGet(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __ADC_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/aes.c b/bsp/boards/mimsy2-cc2538/source/aes.c new file mode 100644 index 0000000000..5272d0bfba --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/aes.c @@ -0,0 +1,352 @@ +/****************************************************************************** +* Filename: aes.c +* Revised: $Date: 2013-03-22 16:13:31 +0100 (Fri, 22 Mar 2013) $ +* Revision: $Revision: 9513 $ +* +* Description: Support for Hardware AES encryption. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup aes_api +//! @{ +// +//***************************************************************************** + +#include "aes.h" + +//***************************************************************************** +// +// Length of AES ECB block in bytes +// +//***************************************************************************** +#define AES_ECB_LENGTH 16 + +//***************************************************************************** +// +// Current AES operation initialized to None +// +//***************************************************************************** +volatile uint8_t g_ui8CurrentAESOp = AES_NONE; + + +//***************************************************************************** +// +//! AESLoadKey writes the key into the Key Ram. Key Ram location must be +//! specified. +//! +//! \param pui8Key is pointer to AES Key. +//! \param ui8KeyLocation is location in Key RAM. +//! +//! The \e ui8KeyLocation parameter is an enumerated type which specifies +//! the Key Ram locationin which the key is stored. +//! This parameter can have any of the following values: +//! +//! - \b KEY_AREA_0 +//! - \b KEY_AREA_1 +//! - \b KEY_AREA_2, +//! - \b KEY_AREA_3, +//! - \b KEY_AREA_4, +//! - \b KEY_AREA_5, +//! - \b KEY_AREA_6, +//! - \b KEY_AREA_7 +//! +//! The pointer \e pui8Key has the address where the Key is stored. +//! +//! \return AES_SUCCESS if successful. +// +//***************************************************************************** +uint8_t AESLoadKey(uint8_t *pui8Key , uint8_t ui8KeyLocation) +{ + static uint32_t ui32temp[4]; + uint8_t * pui8temp = (uint8_t *)ui32temp; + uint8_t i; + + g_ui8CurrentAESOp = AES_KEYL0AD; + // The key address needs to be 4 byte aligned + for(i = 0; i < KEY_BLENGTH; i++) + { + pui8temp[i] = pui8Key[i]; + } + IntDisable(INT_AES); + + // workaround for AES registers not retained after PM2 + HWREG(AES_CTRL_INT_CFG) |= AES_CTRL_INT_CFG_LEVEL; + HWREG(AES_CTRL_INT_EN) |= (AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV); + + // configure master control module + HWREG(AES_CTRL_ALG_SEL) &= (~AES_CTRL_ALG_SEL_KEYSTORE); + HWREG(AES_CTRL_ALG_SEL) |= AES_CTRL_ALG_SEL_KEYSTORE; + + // clear any outstanding events + HWREG(AES_CTRL_INT_CLR) |= (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + + //configure key store module (area, size) + HWREG(AES_KEY_STORE_SIZE) &= KEY_STORE_SIZE_BITS; + + // 128-bit key size + HWREG(AES_KEY_STORE_SIZE) |= KEY_STORE_SIZE_128; + + // enable keys to write (e.g. Key 0) + HWREG(AES_KEY_STORE_WRITE_AREA) = (0x00000001 << ui8KeyLocation); + + + // configure DMAC + // enable DMA channel 0 + HWREG(AES_DMAC_CH0_CTRL) |= 0x000000001; + + // base address of the key in ext. memory + HWREG(AES_DMAC_CH0_EXTADDR) = (uint32_t)pui8temp; + + // total key length in bytes (e.g. 16 for 1 x 128-bit key) + HWREG(AES_DMAC_CH0_DMALENGTH) = 0x10; + + // wait for operation completed + do + { + ASM_NOP; + } + while((!(HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV))); + + // check for absence of errors in DMA and key store + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) + { + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_DMA_BUS_ERR; + return (AES_DMA_BUS_ERROR); + } + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR)) + { + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_WR_ERR; + return (AES_KEYSTORE_WRITE_ERROR); + } + + // acknowledge the interrupt + HWREG(AES_CTRL_INT_CLR) |= (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + + // disable master control/DMA clock + HWREG(AES_CTRL_ALG_SEL) = 0x00000000; + + // check status, if error return error code + if((HWREG(AES_KEY_STORE_WRITTEN_AREA) & 0x7) != 0x1) + { + g_ui8CurrentAESOp = AES_NONE; + return (AES_KEYSTORE_WRITE_ERROR); + } + + for(i = 0; i < KEY_BLENGTH; i++) + { + pui8temp[i] = 0; + } + + g_ui8CurrentAESOp = AES_NONE; + return (AES_SUCCESS); +} + +//***************************************************************************** +// +//! AESECBStart starts an AES-ECB operation. +//! +//! \param pui8MsgIn is pointer to input data. +//! \param pui8MsgOut is pointer to output data. +//! \param ui8KeyLocation is the location in Key RAM. +//! \param ui8Encrypt is set 'true' to ui8Encrypt or set 'false' to decrypt. +//! \param ui8IntEnable is set 'true' to enable AES interrupts or 'false' to +//! disable AES interrupt. +//! +//! The \e ui8KeyLocation parameter is an enumerated type which specifies +//! the Key Ram location in which the key is stored. +//! This parameter can have any of the following values: +//! +//! - \b KEY_AREA_0 +//! - \b KEY_AREA_1 +//! - \b KEY_AREA_2, +//! - \b KEY_AREA_3, +//! - \b KEY_AREA_4, +//! - \b KEY_AREA_5, +//! - \b KEY_AREA_6, +//! - \b KEY_AREA_7 +//! +//! \return AES_SUCCESS if successful. +// +//***************************************************************************** +uint8_t AESECBStart(uint8_t *pui8MsgIn, + uint8_t *pui8MsgOut, + uint8_t ui8KeyLocation, + uint8_t ui8Encrypt, + uint8_t ui8IntEnable) +{ + // workaround for AES registers not retained after PM2 + g_ui8CurrentAESOp = AES_ECB; + HWREG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + HWREG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV; + if(ui8IntEnable) + { + IntPendClear(INT_AES); + IntEnable(INT_AES); + } + + // configure the master control module + // enable the DMA path to the AES engine + HWREG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES; + // clear any outstanding events + HWREG(AES_CTRL_INT_CLR) |= (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + + HWREG(AES_KEY_STORE_READ_AREA) = (uint32_t)ui8KeyLocation; + + //wait until key is loaded to the AES module + do + { + ASM_NOP; + } + while((HWREG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY)); + + // check for Key Store read error + if((HWREG(AES_CTRL_INT_STAT)& AES_CTRL_INT_STAT_KEY_ST_RD_ERR)) + { + // Clear Key Store Read error + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + return (AES_KEYSTORE_READ_ERROR); + } + + // configure AES engine + // program AES-ECB-128 encryption and no IV + if(ui8Encrypt) + { + HWREG(AES_AES_CTRL) = 0x0000000C; + } + else + { + HWREG(AES_AES_CTRL) = 0x00000008; + } + + // write length of the message (lo) + HWREG(AES_AES_C_LENGTH_0) = (uint32_t) AES_ECB_LENGTH; + // write length of the message (hi) + HWREG(AES_AES_C_LENGTH_1) = 0; + + // configure DMAC + // enable DMA channel 0 + HWREG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH0_CTRL_EN; + + // base address of the input data in ext. memory + HWREG(AES_DMAC_CH0_EXTADDR) = (uint32_t)pui8MsgIn; + + // input data length in bytes, equal to the message + HWREG(AES_DMAC_CH0_DMALENGTH) = AES_ECB_LENGTH; + + // length (may be non-block size aligned) + HWREG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH1_CTRL_EN; // enable DMA channel 1 + + // base address of the output data buffer + HWREG(AES_DMAC_CH1_EXTADDR) = (uint32_t)pui8MsgOut; + + // output data length in bytes, equal to the result + HWREG(AES_DMAC_CH1_DMALENGTH) = AES_ECB_LENGTH; + + return (AES_SUCCESS); +} + +//***************************************************************************** +// +//! AESECBCheckResult is called to check the result of AES-ECB AESECBStart +//! operation. +//! +//! \return if result is available or error occurs returns true. If result +//! is not yet available or no error occurs returns false +// +//***************************************************************************** +uint8_t AESECBCheckResult(void) +{ + return (((HWREGB(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)) || + ((HWREGB(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) || + ((HWREGB(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR)) || + ((HWREGB(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR))); +} + +//***************************************************************************** +// +//! AESECBGetResult gets the result of the AES ECB operation. This function +//! must only be called after AESECBStart function is called. +//! +//! \return AES_SUCCESS if successful. +// +//***************************************************************************** +uint8_t AESECBGetResult(void) +{ + //check for errors + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) + { + // clear the DMA error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_DMA_BUS_ERR; + return (AES_DMA_BUS_ERROR); + } + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR)) + { + // clear the Key Store Write error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_WR_ERR; + return (AES_KEYSTORE_WRITE_ERROR); + } + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR)) + { + // clear the Key Store Read error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + return (AES_KEYSTORE_READ_ERROR); + } + + // if no errors then AES ECB operation was successful, disable AES + // interrupt + IntDisable(INT_AES); + + //clear DMA done and result available bits + HWREG(AES_CTRL_INT_CLR) |= (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + + // result has already been copied to the output buffer by DMA + HWREG(AES_CTRL_ALG_SEL) = 0x00000000; // disable master control/DMA clock + HWREG(AES_AES_CTRL) = 0x00000000; // clear mode + g_ui8CurrentAESOp = AES_NONE; + return (AES_SUCCESS); +} + +//***************************************************************************** +// +//! Close the Doxygen group. +//! @} +// +//***************************************************************************** + diff --git a/bsp/boards/mimsy2-cc2538/source/aes.h b/bsp/boards/mimsy2-cc2538/source/aes.h new file mode 100644 index 0000000000..85de5c36d7 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/aes.h @@ -0,0 +1,172 @@ +/****************************************************************************** +* Filename: aes.h +* Revised: $Date: 2013-03-22 16:13:31 +0100 (Fri, 22 Mar 2013) $ +* Revision: $Revision: 9513 $ +* +* Description: AES header file. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __AES_H__ +#define __AES_H__ + +#include +#include +#include +#include "interrupt.h" + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// General constants +// +//***************************************************************************** + +// AES and SHA256 module return codes +#define AES_SUCCESS 0 +#define SHA256_SUCCESS 0 +#define AES_KEYSTORE_READ_ERROR 1 +#define AES_KEYSTORE_WRITE_ERROR 2 +#define AES_DMA_BUS_ERROR 3 +#define CCM_AUTHENTICATION_FAILED 4 +#define SHA2_ERROR 5 +#define SHA256_INVALID_PARAM 6 +#define SHA256_TEST_ERROR 7 +#define AES_ECB_TEST_ERROR 8 +#define AES_NULL_ERROR 9 +#define SHA256_NULL_ERROR 9 +#define AES_CCM_TEST_ERROR 10 + +// Key store module defines +#define STATE_BLENGTH 16 // Number of bytes in State +#define KEY_BLENGTH 16 // Number of bytes in Key +#define KEY_EXP_LENGTH 176 // Nb * (Nr+1) * 4 +#define KEY_STORE_SIZE_BITS 0x03UL +#define KEY_STORE_SIZE_NA 0x00UL +#define KEY_STORE_SIZE_128 0x01UL +#define KEY_STORE_SIZE_192 0x02UL +#define KEY_STORE_SIZE_256 0x03UL + +// AES module defines +#define AES_BUSY 0x08 +#define ENCRYPT 0x00 +#define DECRYPT 0x01 + +// Defines for setting the mode of the AES operation +#define ECB 0x1FFFFFE0 +#define CCM 0x00040000 + +// Macro for setting the mode of the AES operation +#define AES_SETMODE_ECB do { HWREG(AES_AES_CTRL) &= ~ECB; } while (0) +#define AES_SETMODE(mode) do { HWREG(AES_AES_CTRL) &= ~mode; HW_REG(AES_AES_CTRL) |= mode} while (0) + +// Macro for MIN +#define MIN(n,m) (((n) < (m)) ? (n) : (m)) + +//ASM NOP in ccs and IAR +#ifdef ccs +#define ASM_NOP asm(" NOP") +#elif defined rvmdk +#define ASM_NOP __nop() +#else +#define ASM_NOP asm("NOP") +#endif + +//***************************************************************************** +// +//For 128 bit key all 8 Key Area locations from 0 to 8 are valid +//However for 192 bit and 256 bit keys, only even Key Areas 0, 2, 4, 6 +//are valid. This is passes as a parameter to AesECBStart() +// +//***************************************************************************** +enum +{ + KEY_AREA_0, + KEY_AREA_1, + KEY_AREA_2, + KEY_AREA_3, + KEY_AREA_4, + KEY_AREA_5, + KEY_AREA_6, + KEY_AREA_7 +}; + +// Current AES operation +enum +{ + AES_NONE, + AES_KEYL0AD, + AES_ECB, + AES_CCM, + AES_SHA256, + AES_RNG +}; + +// Variable that holds the current AES operation +extern volatile uint8_t g_ui8CurrentAESOp; + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +// AES and Keystore functions +extern uint8_t AESLoadKey(uint8_t *pui8Key, uint8_t ui8KeyLocation); +extern uint8_t AESECBStart(uint8_t *pui8MsgIn, + uint8_t *pui8MsgOut, + uint8_t ui8KeyLocation, + uint8_t ui8Encrypt, + uint8_t ui8IntEnable); +extern uint8_t AESECBCheckResult(void); +extern uint8_t AESECBGetResult(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __AES_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/bl_commands.h b/bsp/boards/mimsy2-cc2538/source/bl_commands.h new file mode 100644 index 0000000000..3d8bdef61a --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/bl_commands.h @@ -0,0 +1,421 @@ +/****************************************************************************** +* Filename: bl_commands.h +* Revised: $Date: 2012-10-03 22:23:04 +0200 (on, 03 okt 2012) $ +* Revision: $Revision: 8460 $ +* +* Description: Commands and return messages supported by the +* ROM-based boot loader. +* +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __BL_COMMANDS_H__ +#define __BL_COMMANDS_H__ + +//***************************************************************************** +// +// This command is used to receive an acknowledge from the the boot loader +// proving that communication has been established. This command is a single +// byte. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[1]; +// +// ui8Command[0] = COMMAND_PING; +// +//***************************************************************************** +#define COMMAND_PING 0x20 + +//***************************************************************************** +// +// This command is sent to the boot loader to indicate where +// to store data and how many bytes will be sent by the +// COMMAND_SEND_DATA commands that follow. The command +// consists of two 32-bit values that are both transferred MSB first. +// The first 32-bit value is the address to start programming data +// into, while the second is the 32-bit size of the data that will be +// sent. The Program Size parameter must be a multiple of 4. This +// command should be followed by a COMMAND_GET_STATUS to +// ensure that the program address and program size were valid +// for the boot loader. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[9]; +// +// ui8Command[0] = COMMAND_DOWNLOAD; +// ui8Command[1] = Program Address [31:24]; +// ui8Command[2] = Program Address [23:16]; +// ui8Command[3] = Program Address [15:8]; +// ui8Command[4] = Program Address [7:0]; +// ui8Command[5] = Program Size [31:24]; +// ui8Command[6] = Program Size [23:16]; +// ui8Command[7] = Program Size [15:8]; +// ui8Command[8] = Program Size [7:0]; +// +//***************************************************************************** +#define COMMAND_DOWNLOAD 0x21 + +//***************************************************************************** +// +// This command is sent to the boot loader to transfer execution control to the +// specified address. The command is followed by a 32-bit value, transferred +// MSB first, that is the address to which execution control is transferred. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[5]; +// +// ui8Command[0] = COMMAND_RUN; +// ui8Command[1] = Run Address [31:24]; +// ui8Command[2] = Run Address [23:16]; +// ui8Command[3] = Run Address [15:8]; +// ui8Command[4] = Run Address [7:0]; +// +//***************************************************************************** +#define COMMAND_RUN 0x22 + +//***************************************************************************** +// +// This command returns the status of the last command that was issued. +// Typically this command should be received after every command is sent to +// ensure that the previous command was successful or, if unsuccessful, to +// properly respond to a failure. The command requires one byte in the data of +// the packet and the boot loader should respond by sending a packet with one +// byte of data that contains the current status code. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[1]; +// +// ui8Command[0] = COMMAND_GET_STATUS; +// +// The following are the definitions for the possible status values that can be +// returned from the boot loader when COMMAND_GET_STATUS is sent to +// the CC2538 device. +// +// COMMAND_RET_SUCCESS +// COMMAND_RET_UNKNOWN_CMD +// COMMAND_RET_INVALID_CMD +// COMMAND_RET_INVALID_ADD +// COMMAND_RET_FLASH_FAIL +// +//***************************************************************************** +#define COMMAND_GET_STATUS 0x23 + +//***************************************************************************** +// +// This command should only follow a COMMAND_DOWNLOAD command +// or another COMMAND_SEND_DATA command, if more data +// is needed. Consecutive send data commands automatically increment +// the address and continue programming from the previous +// location. The transfer size is limited by the maximum size of +// a packet, which allows up to 252 data bytes to be transferred at a +// time. The command terminates programming once the number +// of bytes indicated by the COMMAND_DOWNLOAD command has +// been received. Each time this function is called, it should be +// followed by a COMMAND_GET_STATUS command to ensure that +// the data was successfully programmed into the flash. If the boot +// loader sends a NAK to this command, the boot loader will not increment +// the current address which allows for retransmission of +// the previous data. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[9]; +// +// ui8Command[0] = COMMAND_SEND_DATA +// ui8Command[1] = Data[0]; +// ui8Command[2] = Data[1]; +// ui8Command[3] = Data[2]; +// ui8Command[4] = Data[3]; +// ui8Command[5] = Data[4]; +// ui8Command[6] = Data[5]; +// ui8Command[7] = Data[6]; +// ui8Command[8] = Data[7]; +// +//***************************************************************************** +#define COMMAND_SEND_DATA 0x24 + +//***************************************************************************** +// +// This command is used to tell the boot loader to reset. This is used after +// downloading a new image to the cc2538 device to cause the new application +// or the new boot loader to start from a reset. The normal boot sequence +// occurs and the image runs as if from a hardware reset. It can also be used +// to reset the boot loader if a critical error occurs and the host device +// wants to restart communication with the boot loader. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[1]; +// +// ui8Command[0] = COMMAND_RESET; +// +// The boot loader responds with an ACK signal to the host device before +// actually executing the software reset on the cc2538 device running the +// boot loader. This informs the updater application that the command was +// received successfully and the part will be reset. +// +//***************************************************************************** +#define COMMAND_RESET 0x25 + +//***************************************************************************** +// +// This command will erase the required flash pages. A single flash +// page has the size of 2KB which is the minimum size that can be +// erased. The command consists of two 32-bit values that are both +// transferred MSB first. The first 32-bit value is the address in a +// flash page from where the erase starts, and the second 32-bits +// value is the number of bytes comprised by the erase. The Boot +// Loader responds with an ACK signal to the host device after the +// actual erase operation is performed. The page erase operation +// will always start erasing at the start address of the page that +// incorporates the input Data Address. The erase will end at the +// end of the page which is determined from the input parameters. +// On CC2538™ the flash starts at address 0x00200000. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[9]; +// +// ui8Command[0] = COMMAND_ERASE; +// ui8Command[1] = Data Address [31:24]; +// ui8Command[2] = Data Address [23:16]; +// ui8Command[3] = Data Address [15:8]; +// ui8Command[4] = Data Address [7:0]; +// ui8Command[5] = Data Size [31:24]; +// ui8Command[6] = Data Size [23:16]; +// ui8Command[7] = Data Size [15:8]; +// ui8Command[8] = Data Size [7:0]; +// +//***************************************************************************** +#define COMMAND_ERASE 0x26 + +//***************************************************************************** +// +// This command is used to check a flash area using CRC32. The command consists +// of two 32-bit values that are both transferred MSB first. The first 32-bit +// value is the address in flash from where the CRC32 calculation starts and +// the second 32-bits value is the number of bytes comprised by the CRC32 +// calculation. The command will send the ACK in response to the command after +// the actual CRC32 calculation. +// The result is finally returned as 4 byte in a packet. The Boot Loader will +// then wait for an ACK from the host as a confirmation that the packet was +// received. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[9]; +// +// ui8Command[0]= COMMAND_CRC32; +// ui8Command[1]= Data Address [31:24]; +// ui8Command[2]= Data Address [23:16]; +// ui8Command[3]= Data Address [15: 8]; +// ui8Command[4]= Data Address [ 7: 0]; +// ui8Command[5]= Data Size [31:24]; +// ui8Command[6]= Data Size [23:16]; +// ui8Command[7]= Data Size [15: 8]; +// ui8Command[8]= Data Size [7: 0];w\end{verbatim} +// +//***************************************************************************** +#define COMMAND_CRC32 0x27 + +//***************************************************************************** +// +// This command will make the Boot Loader to return the value of the Chip ID. +// The Boot Loader should first respond by sending the ACK in response to the +// command and then send a packet with four bytes of data that contains the +// Chip ID value. The two LSB bytes hold the chip part number while the +// remaining bytes are reserved for future use and will have the value of 0x00. +// The Boot Loader will then wait for an ACK from the host as a confirmation +// that the packet was received. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[1]; +// ui8Command[0]= COMMAND_GET_CHIP_ID; +// +//***************************************************************************** +#define COMMAND_GET_CHIP_ID 0x28 + +//***************************************************************************** +// +// This command is used in to switch system clock source from internal +// 16 MHz RC oscillator to external 32 MHz crystal oscillator. +// This can be used to increase transfer +// speed on the boot loader serial interfaces. The device will respond with an +// ACK on the command packet before the actual switch to the external 32 MHz +// crystal oscillator is done. +// If the command is transferred on the UART interface the host must execute a +// UART baud rate auto-detection [3.2.3.1.1] in order to establish the baud +// rate to be used while the device is running from the external 32 MHz crystal +// oscillator. The device must be reset in order to switch back to running from +// the internal 16 MHz RC oscillator. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[1]; +// +// ui8Command[0]= COMMAND_SET_XOSC; +// +//***************************************************************************** +#define COMMAND_SET_XOSC 0x29 + +//***************************************************************************** +// +// his command used for reading either an 8-bit or 32-bit word at a specified +// address within the device memory map. +// The command consists of a 32-bit value that is transferred MSB first +// followed by an 8-bit value specifying the read access width. The 32-bit +// value is the address within the device memory map to be read and the 8-bit +// value specifies the access width of the read operation. Allowed values for +// the access width are 1 and 4 (1 = 1 byte / 4 = 4 bytes). +// The command will send an ACK in response to the command after the specified +// data is read from memory. The read data is finally returned as 4 bytes +// (MSB first) in a packet. The Boot Loader will then wait for an ACK from +// the host as a confirmation that the packet was received. +// For an access width value of 1 the read data will be located in the LSB of +// the four bytes returned while the MSB bytes will have the value of 0x00. +// If an invalid access width is specified within the command the Boot Loader +// will ACK the command and respond with 4 bytes with value 0x00 in a packet. +// An eventual following COMMAND_GET_STATUS command will in this case report +// COMMAND_RET_INVALID_CMD. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[6]; +// +// ui8Command[0]= COMMAND_MEMORY_READ; +// ui8Command[1]= Data Address [31:24]; +// ui8Command[2]= Data Address [23:16]; +// ui8Command[3]= Data Address [15: 8]; +// ui8Command[4]= Data Address [ 7: 0]; +// ui8Command[5]= Read access width [7:0]; +// +//***************************************************************************** +#define COMMAND_MEMORY_READ 0x2A + +//***************************************************************************** +// +// This command is used for writing either an 8-bit or 32-bit word to a +// specified address within the device memory map. +// The command consists of two 32-bit values that are transferred MSB first +// followed by an 8-bit value specifying the write access width. The first +// 32-bit value is the address within the device memory map to be written. +// The second 32-bit value is the data to be written. The 8-bit value specifies +// the access width of the write operation. Allowed values for the access width +// are 1 and 4 (1 = 1 byte / 4 = 4 bytes). +// The command will send an ACK in response to the command after the specified +// data is written to memory. +// For an access width value of 1 the data to be written must be located in the +// LSB of the four data bytes in the command. +// If an invalid access width is specified within the command the Boot Loader +// will ACK the command but it will not perform any memory write operation. +// An eventual following COMMAND_GET_STATUS command will in this case +// report COMMAND_RET_INVALID_CMD. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[10]; +// +// ui8Command[0]= COMMAND_MEMORY_WRITE; +// ui8Command[1]= Data Address [31:24]; +// ui8Command[2]= Data Address [23:16]; +// ui8Command[3]= Data Address [15: 8]; +// ui8Command[4]= Data Address [ 7: 0]; +// ui8Command[5]= Data [31:24] +// ui8Command[6]= Data [23:16] +// ui8Command[7]= Data [15: 8] +// ui8Command[8]= Data [7: 0] +// ui8Command[9]= Read access width [7:0]; +// +//***************************************************************************** +#define COMMAND_MEMORY_WRITE 0x2B + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that the previous command completed successful. +// +//***************************************************************************** +#define COMMAND_RET_SUCCESS 0x40 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that the command sent was an unknown command. +// +//***************************************************************************** +#define COMMAND_RET_UNKNOWN_CMD 0x41 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that the previous command was formatted incorrectly. +// +//***************************************************************************** +#define COMMAND_RET_INVALID_CMD 0x42 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that the previous download command contained an invalid address value. +// +//***************************************************************************** +#define COMMAND_RET_INVALID_ADR 0x43 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that an attempt to program or erase the flash has failed. +// +//***************************************************************************** +#define COMMAND_RET_FLASH_FAIL 0x44 + +//***************************************************************************** +// +// This is the value that is sent to acknowledge a packet. +// +//***************************************************************************** +#define COMMAND_ACK 0xcc + +//***************************************************************************** +// +// This is the value that is sent to not-acknowledge a packet. +// +//***************************************************************************** +#define COMMAND_NAK 0x33 + +#endif // __BL_COMMANDS_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/ccm.c b/bsp/boards/mimsy2-cc2538/source/ccm.c new file mode 100644 index 0000000000..21815e36d1 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/ccm.c @@ -0,0 +1,640 @@ +/****************************************************************************** +* Filename: ccm.c +* Revised: $Date: 2013-03-22 16:13:31 +0100 (Fri, 22 Mar 2013) $ +* Revision: $Revision: 9513 $ +* +* Description: Support for Hardware CCM encryption and authentication. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup ccm_api +//! @{ +// +//***************************************************************************** + +#include "aes.h" +#include "ccm.h" + + +//***************************************************************************** +// +//! CCMAuthEncryptStart starts the CCM operation +//! +//! \param bEncrypt if set to 'true' then run encryption and set to 'false' for +//! authentication only. +//! \param ui8Mval is the length of authentication field in octets [0,2,4,6,8,10, +//! 12, 14 or 16]. +//! \param pui8N is the pointer to 13-byte or 12-byte Nonce. +//! \param pui8M is the pointer to octet string 'm'/input message. +//! \param ui16LenM is the length of pui8M[] in octets. +//! \param pui8A is the pointer to octet string 'a'. +//! \param ui16LenA is the Length of pui8A[] in octets. +//! \param ui8KeyLocation is the location where the Key is stored in Key RAM. +//! \param pui8Cstate is the pointer to output buffer. +//! \param ui8CCMLVal is the ccm L Value to be used. +//! \param ui8IntEnable if set to 'true' to enable interrupts or 'false' to +//! disable interrupts. Should be 'false' if \e bEncrypt is set to 'false'. +//! +//! +//! The function will place in \e pui8Cstate the first ui8Mval bytes +//! containing the Authentication Tag. +//! +//! The \e ui8KeyLocation parameter is an enumerated type which specifies +//! the Key Ram location in which the key is stored. +//! This parameter can have any of the following values: +//! +//! - \b KEY_AREA_0 +//! - \b KEY_AREA_1 +//! - \b KEY_AREA_2, +//! - \b KEY_AREA_3, +//! - \b KEY_AREA_4, +//! - \b KEY_AREA_5, +//! - \b KEY_AREA_6, +//! - \b KEY_AREA_7 +//! +//! \return AES_SUCCESS if successful. +// +//***************************************************************************** +uint8_t CCMAuthEncryptStart(bool bEncrypt, + uint8_t ui8Mval, + uint8_t *pui8N, + uint8_t *pui8M, + uint16_t ui16LenM, + uint8_t *pui8A, + uint16_t ui16LenA, + uint8_t ui8KeyLocation, + uint8_t *pui8Cstate, + uint8_t ui8CCMLVal, + uint8_t ui8IntEnable) +{ + uint8_t ui8A0[16]; + uint32_t ui32CtrlVal; + uint8_t ui8I; + g_ui8CurrentAESOp = AES_CCM; + + IntDisable(INT_AES); + + // workaround for AES registers not retained after PM2 + HWREG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + HWREG(AES_CTRL_INT_EN) = (AES_CTRL_INT_EN_RESULT_AV | + AES_CTRL_INT_EN_DMA_IN_DONE); + + HWREG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES; + HWREG(AES_CTRL_INT_CLR) |= (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + + HWREG(AES_KEY_STORE_READ_AREA) = (uint32_t)ui8KeyLocation; + + //wait until key is loaded to the AES module + do + { + ASM_NOP; + } + while((HWREG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY)); + + //check for Key Store read error + if((HWREG(AES_CTRL_INT_STAT)& AES_CTRL_INT_STAT_KEY_ST_RD_ERR)) + { + // clear the Keystore Read error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + return (AES_KEYSTORE_READ_ERROR); + } + + // Prepare the initialization vector + ui8A0[0] = ui8CCMLVal - 1; // Lval + + for(ui8I = 0; ui8I < 13; ui8I++) + { + ui8A0[ui8I + 1] = pui8N[ui8I]; + } + if(3 == ui8CCMLVal) + { + ui8A0[13] = 0; + } + ui8A0[14] = 0; // initialize counter to 0 + ui8A0[15] = 0; // initialize counter to 0 + + // write initialization vector + HWREG(AES_AES_IV_0) = ((uint32_t *)&ui8A0)[0]; + HWREG(AES_AES_IV_1) = ((uint32_t *)&ui8A0)[1]; + HWREG(AES_AES_IV_2) = ((uint32_t *)&ui8A0)[2]; + HWREG(AES_AES_IV_3) = ((uint32_t *)&ui8A0)[3]; + + // configure AES engine + ui32CtrlVal = ((ui8CCMLVal - 1) << + AES_AES_CTRL_CCM_L_S); // CCM_L + + if(ui8Mval >= 2) + { + ui32CtrlVal |= (((ui8Mval - 2) >> 1) << + AES_AES_CTRL_CCM_M_S); // CCM_M + } + else + { + ui32CtrlVal |= (0 << + AES_AES_CTRL_CCM_M_S); // CCM_M + } + ui32CtrlVal |= (AES_AES_CTRL_CCM); // CCM + ui32CtrlVal |= (1 << AES_AES_CTRL_key_size_S); // key = 128 + ui32CtrlVal |= (1 << AES_AES_CTRL_input_ready); // encryption + ui32CtrlVal |= AES_AES_CTRL_CTR; // CTR + ui32CtrlVal |= AES_AES_CTRL_save_context; // save context + ui32CtrlVal |= (0x3 << AES_AES_CTRL_ctr_width_S);// CTR width 128 + // program AES-CCM-128 encryption + HWREG(AES_AES_CTRL) = ui32CtrlVal; + + // write the length of the crypto block (lo) + HWREG(AES_AES_C_LENGTH_0) = (uint16_t)(ui16LenM) ; + // write the length of the crypto block (hi) + HWREG(AES_AES_C_LENGTH_1) = 0; + + // write the length of the AAD data block may be non-block size aligned + HWREG(AES_AES_AUTH_LENGTH) = ui16LenA; + + if(ui16LenA != 0) + { + // configure DMAC to fetch the AAD data + // enable DMA channel 0 + HWREG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH0_CTRL_EN; + // base address of the AAD input data in ext. memory + HWREG(AES_DMAC_CH0_EXTADDR) = (uint32_t)pui8A; + // AAD data length in bytes, equal to the AAD length len + //({aad data}) (may be non-block size aligned) + + HWREG(AES_DMAC_CH0_DMALENGTH) = ui16LenA; + + // wait for completion of the AAD data transfer, DMA_IN_DONE + do + { + ASM_NOP; + } + while(!(HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE)); + + // check for the absence of error + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) + { + //clear the DMA error + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_DMA_BUS_ERR; + return (AES_DMA_BUS_ERROR); + } + } + + // clear interrupt status + HWREG(AES_CTRL_INT_CLR) = (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + if(ui8IntEnable) + { + IntPendClear(INT_AES); + IntEnable(INT_AES); + } + + // enable result available bit in interrupt enable + HWREG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV; + + if(bEncrypt) + { + // configure DMAC + // enable DMA channel 0 + HWREG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH0_CTRL_EN; + // base address of the payload data in ext. memory + HWREG(AES_DMAC_CH0_EXTADDR) = (uint32_t)pui8M; + // payload data length in bytes, equal to the message length + //len({crypto_data}) + HWREG(AES_DMAC_CH0_DMALENGTH) = (ui16LenM); + + // enable DMA channel 1 + HWREG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH1_CTRL_EN; + // base address of the output data buffer + HWREG(AES_DMAC_CH1_EXTADDR) = (uint32_t)pui8M; + // output data length in bytes, equal to the result data length + // len({crypto data}) + HWREG(AES_DMAC_CH1_DMALENGTH) = ui16LenM; + } + return (AES_SUCCESS); + +} + +//***************************************************************************** +// +//! CCMAuthEncryptCheckResult checks the status of CCM encrypt operation. +//! +//! \return if result is available or error occurs, function returns true. +//! If result is not yet available or no error occurs, returns false +//! +// +//***************************************************************************** +uint8_t CCMAuthEncryptCheckResult(void) +{ + return (((HWREGB(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)) || + ((HWREGB(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) || + ((HWREGB(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR)) || + ((HWREGB(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR))); +} + +//***************************************************************************** +// +//! CCMAuthEncryptGetResult gets the result of CCM operation. This +//! function should be called after CCCMAuthEncryptStart is called. +//! +//! \param ui8Mval is length of authentication field in octets [0,2,4,6,8,10,12, +//! 14 or 16]. +//! \param ui16LenM is length of message pui8M[] in octets. +//! \param pui8Cstate is pointer to AES state buffer. +//! +//! \return AES_SUCCESS if successful. +// +//***************************************************************************** +uint8_t CCMAuthEncryptGetResult(uint8_t ui8Mval, + uint16_t ui16LenM, + uint8_t *pui8Cstate) + +{ + uint8_t volatile ui8MIC[16]; + uint8_t ui8I; + + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) + { + // clear the DMA error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_DMA_BUS_ERR; + return (AES_DMA_BUS_ERROR); + } + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR)) + { + // clear the Key Store Write error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_WR_ERR; + return (AES_KEYSTORE_WRITE_ERROR); + } + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR)) + { + // clear the Key Store Read error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + return (AES_KEYSTORE_READ_ERROR); + } + + IntDisable(INT_AES); + + // disable the master control/DMA clock + HWREG(AES_CTRL_ALG_SEL) = 0x00000000; + + // read tag + // wait for the context ready bit [30] + do + { + ASM_NOP; + } + while((HWREG(AES_AES_CTRL) & AES_AES_CTRL_saved_context_ready) != + AES_AES_CTRL_saved_context_ready); + + // Read the tag registers + ((uint32_t *)&ui8MIC)[0] = HWREG(AES_AES_TAG_OUT_0); + ((uint32_t *)&ui8MIC)[1] = HWREG(AES_AES_TAG_OUT_1); + ((uint32_t *)&ui8MIC)[2] = HWREG(AES_AES_TAG_OUT_2); + ((uint32_t *)&ui8MIC)[3] = HWREG(AES_AES_TAG_OUT_3); + + // clear the interrupt status + HWREG(AES_CTRL_INT_CLR) |= (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + + // copy tag to pui8Cstate + for(ui8I = 0; ui8I < ui8Mval; ui8I++) + { + pui8Cstate[ui8I] = ui8MIC[ui8I]; + } + g_ui8CurrentAESOp = AES_NONE; + return (AES_SUCCESS); +} + +//***************************************************************************** +// +//! CCMInvAuthDecryptStart starts the CCM Decryption and Inverse +//! Authentication operation. +//! +//! \param bDecrypt if set to 'true' then run decryption, set to 'false' if +//! authentication only +//! \param ui8Mval is the length of authentication field in octets [0,2,4,6,8, +//! 10,12,14 or 16]. +//! \param pui8N is the pointer to 13-byte or 12-byte Nonce. +//! \param pui8C is the pointer to octet string 'c' = 'm' || auth tag T. +//! \param ui16LenC is the length of pui8C[] in octets. +//! \param pui8A is the pointer to octet string 'a'. +//! \param ui16LenA is the Length of pui8A[] in octets. +//! \param ui8KeyLocation is the location where the Key is stored in Key RAM. +//! \param pui8Cstate is the pointer to output buffer. (cannot be part +//! of pui8C[]). +//! \param ui8CCMLVal is the ccm L Value to be used. +//! \param ui8IntEnable if set to 'true' to enable interrupts or 'false' to +//! disable interuupts. Set to 'false' if \e bDecrypt is set to 'false'. +//! +//! +//! The function will place in \e pui8Cstate the first ui8Mval bytes of +//! containing the Authentication Tag. +//! +//! The \e ui8KeyLocation parameter is an enumerated type which specifies +//! the Key Ram locationin which the key is stored. +//! This parameter can have any of the following values: +//! +//! - \b KEY_AREA_0 +//! - \b KEY_AREA_1 +//! - \b KEY_AREA_2, +//! - \b KEY_AREA_3, +//! - \b KEY_AREA_4, +//! - \b KEY_AREA_5, +//! - \b KEY_AREA_6, +//! - \b KEY_AREA_7 +//! +//! \return AES_SUCCESS if successful. +// +//***************************************************************************** +uint8_t CCMInvAuthDecryptStart(bool bDecrypt, + uint8_t ui8Mval, + uint8_t *pui8N, + uint8_t *pui8C, + uint16_t ui16LenC, + uint8_t *pui8A, + uint16_t ui16LenA, + uint8_t ui8KeyLocation, + uint8_t *pui8Cstate, + uint8_t ui8CCMLVal, + uint8_t ui8IntEnable) +{ + uint16_t ui16LenM = ui16LenC - ui8Mval; + uint8_t ui8A0[16]; + uint32_t ui32CtrlVal; + uint8_t ui8I; + g_ui8CurrentAESOp = AES_CCM; + + // workaround for AES registers not retained after PM2 + HWREG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + HWREG(AES_CTRL_INT_EN) = (AES_CTRL_INT_EN_RESULT_AV | + AES_CTRL_INT_EN_DMA_IN_DONE); + + HWREG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES; + HWREG(AES_CTRL_INT_CLR) = (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + + HWREG(AES_KEY_STORE_READ_AREA) = (uint32_t)ui8KeyLocation; + + //wait until key is loaded to the AES module + do + { + ASM_NOP; + } + while((HWREG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY)); + + //check for Key Store read error + if((HWREG(AES_CTRL_INT_STAT)& AES_CTRL_INT_STAT_KEY_ST_RD_ERR)) + { + // clear the Keystore Read error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + return (AES_KEYSTORE_READ_ERROR); + } + + // Prepare the initialization vector + ui8A0[0] = ui8CCMLVal - 1; // Lval + for(ui8I = 0; ui8I < 13; ui8I++) + { + ui8A0[ui8I + 1] = pui8N[ui8I]; + } + if(3 == ui8CCMLVal) + { + ui8A0[13] = 0; + } + ui8A0[14] = 0; // initialize counter to 0 + ui8A0[15] = 0; // initialize counter to 0 + + // write initialization vector + HWREG(AES_AES_IV_0) = ((uint32_t *)&ui8A0)[0]; + HWREG(AES_AES_IV_1) = ((uint32_t *)&ui8A0)[1]; + HWREG(AES_AES_IV_2) = ((uint32_t *)&ui8A0)[2]; + HWREG(AES_AES_IV_3) = ((uint32_t *)&ui8A0)[3]; + + // configure AES engine + ui32CtrlVal = ((ui8CCMLVal - 1) << + AES_AES_CTRL_CCM_L_S); // CCM_L + if(ui8Mval >= 2) + { + ui32CtrlVal |= (((ui8Mval - 2) >> 1) << + AES_AES_CTRL_CCM_M_S); // CCM_M + } + else + { + ui32CtrlVal |= (0 << + AES_AES_CTRL_CCM_M_S); // CCM_M + } + ui32CtrlVal |= (AES_AES_CTRL_CCM); // CCM + ui32CtrlVal |= (1 << AES_AES_CTRL_key_size_S); // key = 128 + ui32CtrlVal |= (0 << AES_AES_CTRL_input_ready); // decryption + ui32CtrlVal |= AES_AES_CTRL_CTR; // CTR + ui32CtrlVal |= AES_AES_CTRL_save_context; // save context + ui32CtrlVal |= (0x3 << AES_AES_CTRL_ctr_width_S); // CTR width 128 + // program AES-CCM-128 encryption + HWREG(AES_AES_CTRL) = ui32CtrlVal; + + // write the length of the crypto block (lo) + HWREG(AES_AES_C_LENGTH_0) = (uint16_t)(ui16LenM) ; + // write the length of the crypto block (hi) + HWREG(AES_AES_C_LENGTH_1) = 0; + + // write the length of the AAD data block may be non-block size aligned + HWREG(AES_AES_AUTH_LENGTH) = ui16LenA; + + if(ui16LenA != 0) + { + // configure DMAC to fetch the AAD data + // enable DMA channel 0 + HWREG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH0_CTRL_EN; + // base address of the AAD input data in ext. memory + HWREG(AES_DMAC_CH0_EXTADDR) = (uint32_t)pui8A; + // AAD data length in bytes, equal to the AAD length len + //({aad data}) (may be non-block size aligned) + + HWREG(AES_DMAC_CH0_DMALENGTH) = ui16LenA; + + // wait for completion of the AAD data transfer, DMA_IN_DONE + do + { + ASM_NOP; + } + while(!(HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE)); + + // check for the absence of error + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) + { + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_DMA_BUS_ERR; + return (AES_DMA_BUS_ERROR); + } + } + + // clear interrupt status + HWREG(AES_CTRL_INT_CLR) = (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + + if(ui8IntEnable) + { + IntPendClear(INT_AES); + IntEnable(INT_AES); + } + + // enable result available bit in interrupt enable + HWREG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV; + + if(bDecrypt) + { + // configure DMAC + // enable DMA channel 0 + HWREG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH0_CTRL_EN; + // base address of the payload data in ext. memory + HWREG(AES_DMAC_CH0_EXTADDR) = (uint32_t)pui8C; + // payload data length in bytes, equal to the message length len({crypto_data}) + HWREG(AES_DMAC_CH0_DMALENGTH) = (ui16LenM); + + // enable DMA channel 1 + HWREG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH1_CTRL_EN; + // base address of the output data buffer + HWREG(AES_DMAC_CH1_EXTADDR) = (uint32_t)pui8C; + // output data length in bytes, equal to the result data length len({crypto data}) + HWREG(AES_DMAC_CH1_DMALENGTH) = ui16LenM; + } + + return (AES_SUCCESS); +} + +//***************************************************************************** +// +//! CCMInvAuthDecryptCheckResult function checks CCM decrypt and Inverse +//! Authentication result. +//! +//! \return if result is available or error occurs returns true. If result +//! is not yet available or no error occurs returns false +// +//***************************************************************************** +uint8_t CCMInvAuthDecryptCheckResult(void) +{ + // check if result is available (or) some error has occured + return (CCMAuthEncryptCheckResult()); +} + +//***************************************************************************** +// +//! CCMInvAuthDecryptGetResult gets the result of CCM operation. This +//! function should be called only after CCMInvAuthDecryptStart is called. +//! +//! \param ui8Mval is length of authentication field in octets [0,2,4,6,8,10, +//! 12,14 or 16]. +//! \param pui8C is pointer to octet string 'c' = 'm' || auth tag T. +//! \param ui16LenC is length of message pui8C[] in octets. +//! \param pui8Cstate is pointer to AES state buffer, cannot be part of +//! pui8C[]). +//! +//! \return AES_SUCCESS if successful. +// +//***************************************************************************** +uint8_t CCMInvAuthDecryptGetResult(uint8_t ui8Mval, + uint8_t *pui8C, + uint16_t ui16LenC, + uint8_t *pui8Cstate) +{ + uint8_t volatile ui8MIC[16]; + uint16_t ui16LenM = ui16LenC - ui8Mval; + uint8_t ui8I, ui8J; + + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) + { + //clear the DMA error + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_DMA_BUS_ERR; + return (AES_DMA_BUS_ERROR); + } + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR)) + { + // clear the Key Store Write error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_WR_ERR; + return (AES_KEYSTORE_WRITE_ERROR); + } + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR)) + { + // clear the Key Store Read error bit + HWREG(AES_CTRL_INT_CLR) |= AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + return (AES_KEYSTORE_READ_ERROR); + } + + IntDisable(INT_AES); + + // disable the master control/DMA clock + HWREG(AES_CTRL_ALG_SEL) = 0x00000000; + + // read tag + // wait for the context ready bit [30] + do + { + ASM_NOP; + } + while((HWREG(AES_AES_CTRL) & AES_AES_CTRL_saved_context_ready) != + AES_AES_CTRL_saved_context_ready); + + // Read the tag registers + ((uint32_t *)&ui8MIC)[0] = HWREG(AES_AES_TAG_OUT_0); + ((uint32_t *)&ui8MIC)[1] = HWREG(AES_AES_TAG_OUT_1); + ((uint32_t *)&ui8MIC)[2] = HWREG(AES_AES_TAG_OUT_2); + ((uint32_t *)&ui8MIC)[3] = HWREG(AES_AES_TAG_OUT_3); + + // clear the interrupt status + HWREG(AES_CTRL_INT_CLR) |= (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + + // copy tag to pui8Cstate + for(ui8I = 0; ui8I < ui8Mval; ui8I++) + { + pui8Cstate[ui8I] = ui8MIC[ui8I]; + } + + for(ui8J = 0; ui8J < ui8Mval; ui8J++) + { + if(pui8Cstate[ui8J] != pui8C[ui16LenM + ui8J]) + { + return (CCM_AUTHENTICATION_FAILED); + } + } + + g_ui8CurrentAESOp = AES_NONE; + return (AES_SUCCESS); +} + +//***************************************************************************** +// +//! Close the Doxygen group. +//! @} +// +//***************************************************************************** + diff --git a/bsp/boards/mimsy2-cc2538/source/ccm.h b/bsp/boards/mimsy2-cc2538/source/ccm.h new file mode 100644 index 0000000000..ea7ddd7a7d --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/ccm.h @@ -0,0 +1,97 @@ +/****************************************************************************** +* Filename: ccm.h +* Revised: $Date: 2013-03-22 16:13:31 +0100 (Fri, 22 Mar 2013) $ +* Revision: $Revision: 9513 $ +* +* Description: Support for Hardware CCM encryption and authentication. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __CCM_H__ +#define __CCM_H__ + +#include + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +extern uint8_t CCMAuthEncryptStart (bool bEncrypt, + uint8_t ui8Mval, + uint8_t *pui8N, + uint8_t *pui8M, + uint16_t ui16LenM, + uint8_t *pui8A, + uint16_t ui16LenA, + uint8_t ui8KeyLocation, + uint8_t *pui8Cstate, + uint8_t ui8CCMLVal, + uint8_t ui8IntEnable); +extern uint8_t CCMAuthEncryptCheckResult(void); +extern uint8_t CCMAuthEncryptGetResult(uint8_t ui8Mval, + uint16_t ui16LenM, + uint8_t *pui8Cstate); +extern uint8_t CCMInvAuthDecryptStart (bool bDecrypt, + uint8_t ui8Mval, + uint8_t *pui8N, + uint8_t *pui8C, + uint16_t ui16LenC, + uint8_t *pui8A, + uint16_t ui16LenA, + uint8_t ui8KeyLocation, + uint8_t *pui8Cstate, + uint8_t ui8CCMLVal, + uint8_t ui8IntEnable); +extern uint8_t CCMInvAuthDecryptCheckResult(void); +extern uint8_t CCMInvAuthDecryptGetResult(uint8_t ui8Mval, + uint8_t *pui8C, + uint16_t ui16LenC, + uint8_t *pui8Cstate); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __CCM_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/cpu.c b/bsp/boards/mimsy2-cc2538/source/cpu.c new file mode 100644 index 0000000000..eb105eae4b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/cpu.c @@ -0,0 +1,554 @@ +/****************************************************************************** +* Filename: cpu.c +* Revised: $Date: 2013-01-21 15:25:21 +0100 (Mon, 21 Jan 2013) $ +* Revision: $Revision: 9178 $ +* +* Description: Instruction wrappers for special CPU instructions needed by +* the drivers. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + + +#include "cpu.h" + +//***************************************************************************** +// +// Wrapper function for the CPSID instruction. Returns the state of PRIMASK +// on entry. +// +//***************************************************************************** +#if defined(__GNUC__) +uint32_t __attribute__((naked)) +CPUcpsid(void) +{ + uint32_t ui32Ret; + + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsid i\n" + " bx lr\n" + : "=r" (ui32Ret)); + + // + // The return is handled in the inline assembly, but the compiler will + // still complain if there is not an explicit return here (despite the fact + // that this does not result in any code being produced because of the + // naked attribute). + // + return(ui32Ret); +} +#endif +#if (__ICCARM__) +uint32_t +CPUcpsid(void) +{ + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsid i\n"); + + // + // "Warning[Pe940]: missing return statement at end of non-void function" + // is suppressed here to avoid putting a "bx lr" in the inline assembly + // above and a superfluous return statement here. + // +#pragma diag_suppress=Pe940 +} +#pragma diag_default=Pe940 +#endif +#if defined(__KEIL__) || defined(__ARMCC_VERSION) +__asm uint32_t +CPUcpsid(void) +{ + // + // Read PRIMASK and disable interrupts. + // + mrs r0, PRIMASK; + cpsid i; + bx lr +} +#endif +#if defined(__TI_COMPILER_VERSION__) +uint32_t +CPUcpsid(void) +{ + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsid i\n" + " bx lr\n"); + + // + // The following keeps the compiler happy, because it wants to see a + // return value from this function. It will generate code to return + // a zero. However, the real return is the "bx lr" above, so the + // return(0) is never executed and the function returns with the value + // you expect in R0. + // + return(0); +} +#endif + +//***************************************************************************** +// +// Wrapper function returning the state of PRIMASK (indicating whether +// interrupts are enabled or disabled). +// +//***************************************************************************** +#if defined(__GNUC__) +uint32_t __attribute__((naked)) +CPUprimask(void) +{ + uint32_t ui32Ret; + + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " bx lr\n" + : "=r" (ui32Ret)); + + // + // The return is handled in the inline assembly, but the compiler will + // still complain if there is not an explicit return here (despite the fact + // that this does not result in any code being produced because of the + // naked attribute). + // + return(ui32Ret); +} +#endif +#if (__ICCARM__) +uint32_t +CPUprimask(void) +{ + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n"); + + // + // "Warning[Pe940]: missing return statement at end of non-void function" + // is suppressed here to avoid putting a "bx lr" in the inline assembly + // above and a superfluous return statement here. + // +#pragma diag_suppress=Pe940 +} +#pragma diag_default=Pe940 +#endif +#if defined(__KEIL__) || defined(__ARMCC_VERSION) +__asm uint32_t +CPUprimask(void) +{ + // + // Read PRIMASK and disable interrupts. + // + mrs r0, PRIMASK; + bx lr +} +#endif +#if defined(__TI_COMPILER_VERSION__) +uint32_t +CPUprimask(void) +{ + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " bx lr\n"); + + // + // The following keeps the compiler happy, because it wants to see a + // return value from this function. It will generate code to return + // a zero. However, the real return is the "bx lr" above, so the + // return(0) is never executed and the function returns with the value + // you expect in R0. + // + return(0); +} +#endif + +//***************************************************************************** +// +// Wrapper function for the CPSIE instruction. Returns the state of PRIMASK +// on entry. +// +//***************************************************************************** +#if defined(__GNUC__) +uint32_t __attribute__((naked)) +CPUcpsie(void) +{ + uint32_t ui32Ret; + + // + // Read PRIMASK and enable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsie i\n" + " bx lr\n" + : "=r" (ui32Ret)); + + // + // The return is handled in the inline assembly, but the compiler will + // still complain if there is not an explicit return here (despite the fact + // that this does not result in any code being produced because of the + // naked attribute). + // + return(ui32Ret); +} +#endif +#if (__ICCARM__) +uint32_t +CPUcpsie(void) +{ + // + // Read PRIMASK and enable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsie i\n"); + + // + // "Warning[Pe940]: missing return statement at end of non-void function" + // is suppressed here to avoid putting a "bx lr" in the inline assembly + // above and a superfluous return statement here. + // +#pragma diag_suppress=Pe940 +} +#pragma diag_default=Pe940 +#endif +#if defined(__KEIL__) || defined(__ARMCC_VERSION) +__asm uint32_t +CPUcpsie(void) +{ + // + // Read PRIMASK and enable interrupts. + // + mrs r0, PRIMASK; + cpsie i; + bx lr +} +#endif +#if defined(__TI_COMPILER_VERSION__) +uint32_t +CPUcpsie(void) +{ + // + // Read PRIMASK and enable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsie i\n" + " bx lr\n"); + + // + // The following keeps the compiler happy, because it wants to see a + // return value from this function. It will generate code to return + // a zero. However, the real return is the "bx lr" above, so the + // return(0) is never executed and the function returns with the value + // you expect in R0. + // + return(0); +} +#endif + +//***************************************************************************** +// +// Wrapper function for the WFI instruction. +// +//***************************************************************************** +#if defined(__GNUC__) +void __attribute__((naked)) +CPUwfi(void) +{ + // + // Wait for the next interrupt. + // + __asm(" wfi\n" + " bx lr\n"); +} +#endif +#if (__ICCARM__) +void +CPUwfi(void) +{ + // + // Wait for the next interrupt. + // + __asm(" wfi\n"); +} +#endif +#if defined(__KEIL__) || defined(__ARMCC_VERSION) +__asm void +CPUwfi(void) +{ + // + // Wait for the next interrupt. + // + wfi; + bx lr +} +#endif +#if defined(__TI_COMPILER_VERSION__) +void +CPUwfi(void) +{ + // + // Wait for the next interrupt. + // + __asm(" wfi\n"); +} +#endif + +//***************************************************************************** +// +// Wrapper function for the WFE instruction. +// +//***************************************************************************** +#if defined(__GNUC__) +void __attribute__((naked)) +CPUwfe(void) +{ + // + // Wait for the next event + // + __asm(" wfe\n" + " bx lr\n"); +} +#endif +#if (__ICCARM__) +void +CPUwfe(void) +{ + // + // Wait for the next event + // + __asm(" wfe\n"); +} +#endif +#if defined(__KEIL__) || defined(__ARMCC_VERSION) +__asm void +CPUwfe(void) +{ + // + // Wait for the next event + // + wfe; + bx lr +} +#endif +#if defined(__TI_COMPILER_VERSION__) +void +CPUwfe(void) +{ + // + // Wait for the next event + // + __asm(" wfe\n"); +} +#endif + +//***************************************************************************** +// +// Wrapper function for the SEV instruction (Send event). +// +//***************************************************************************** +#if defined(__GNUC__) +void __attribute__((naked)) +CPUsev(void) +{ + // + // Send event + // + __asm(" sev\n" + " bx lr\n"); +} +#endif +#if (__ICCARM__) +void +CPUsev(void) +{ + // + // Send event + // + __asm(" sev\n"); +} +#endif +#if defined(__KEIL__) || defined(__ARMCC_VERSION) +__asm void +CPUsev(void) +{ + // + // Send event + // + sev; + bx lr +} +#endif +#if defined(__TI_COMPILER_VERSION__) +void +CPUsev(void) +{ + // + // Send event + // + __asm(" sev\n"); +} +#endif + +//***************************************************************************** +// +// Wrapper function for writing the BASEPRI register. +// +//***************************************************************************** +#if defined(__GNUC__) +void __attribute__((naked)) +CPUbasepriSet(uint32_t ui32NewBasepri) +{ + + // + // Set the BASEPRI register + // + __asm(" msr BASEPRI, r0\n" + " bx lr\n"); +} +#endif +#if (__ICCARM__) +void +CPUbasepriSet(uint32_t ui32NewBasepri) +{ + // + // Set the BASEPRI register + // + __asm(" msr BASEPRI, r0\n"); +} +#endif +#if defined(__KEIL__) || defined(__ARMCC_VERSION) +__asm void +CPUbasepriSet(uint32_t ui32NewBasepri) +{ + // + // Set the BASEPRI register + // + msr BASEPRI, r0; + bx lr +} +#endif +#if defined(__TI_COMPILER_VERSION__) +void +CPUbasepriSet(uint32_t ui32NewBasepri) +{ + // + // Set the BASEPRI register + // + __asm(" msr BASEPRI, r0\n"); +} +#endif + +//***************************************************************************** +// +// Wrapper function for reading the BASEPRI register. +// +//***************************************************************************** +#if defined(__GNUC__) +uint32_t __attribute__((naked)) +CPUbasepriGet(void) +{ + uint32_t ui32Ret; + + // + // Read BASEPRI + // + __asm(" mrs r0, BASEPRI\n" + " bx lr\n" + : "=r" (ui32Ret)); + + // + // The return is handled in the inline assembly, but the compiler will + // still complain if there is not an explicit return here (despite the fact + // that this does not result in any code being produced because of the + // naked attribute). + // + return(ui32Ret); +} +#endif +#if (__ICCARM__) +uint32_t +CPUbasepriGet(void) +{ + // + // Read BASEPRI + // + __asm(" mrs r0, BASEPRI\n"); + + // + // "Warning[Pe940]: missing return statement at end of non-void function" + // is suppressed here to avoid putting a "bx lr" in the inline assembly + // above and a superfluous return statement here. + // +#pragma diag_suppress=Pe940 +} +#pragma diag_default=Pe940 +#endif +#if defined(rvmdk) || defined(__ARMCC_VERSION) +__asm uint32_t +CPUbasepriGet(void) +{ + // + // Read BASEPRI + // + mrs r0, BASEPRI; + bx lr +} +#endif +#if defined(__TI_COMPILER_VERSION__) +uint32_t +CPUbasepriGet(void) +{ + // + // Read BASEPRI + // + __asm(" mrs r0, BASEPRI\n" + " bx lr\n"); + + // + // The following keeps the compiler happy, because it wants to see a + // return value from this function. It will generate code to return + // a zero. However, the real return is the "bx lr" above, so the + // return(0) is never executed and the function returns with the value + // you expect in R0. + // + return(0); +} +#endif diff --git a/bsp/boards/mimsy2-cc2538/source/cpu.h b/bsp/boards/mimsy2-cc2538/source/cpu.h new file mode 100644 index 0000000000..ce37ca3fbf --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/cpu.h @@ -0,0 +1,79 @@ +/****************************************************************************** +* Filename: cpu.h +* Revised: $Date: 2013-01-21 15:25:21 +0100 (Mon, 21 Jan 2013) $ +* Revision: $Revision: 9178 $ +* +* Description: Prototypes for the CPU instruction wrapper functions. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __CPU_H__ +#define __CPU_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// Prototypes. +// +//***************************************************************************** +extern uint32_t CPUcpsid(void); +extern uint32_t CPUcpsie(void); +extern uint32_t CPUprimask(void); +extern void CPUwfi(void); +extern void CPUwfe(void); +extern void CPUsev(void); +extern uint32_t CPUbasepriGet(void); +extern void CPUbasepriSet(uint32_t ui32NewBasepri); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __CPU_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/debug.c b/bsp/boards/mimsy2-cc2538/source/debug.c new file mode 100644 index 0000000000..188c3511e7 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/debug.c @@ -0,0 +1,72 @@ +/****************************************************************************** +* Filename: debug.c +* Revised: $Date: 2013-01-11 14:28:46 +0100 (fr, 11 jan 2013) $ +* Revision: $Revision: 9099 $ +* +* Description: Debug stub. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup debug_api +//! @{ +// +//***************************************************************************** + +#include "debug.h" + +//***************************************************************************** +// +//! +//! Function stub for allowing compile with ENABLE_ASSERT flag asserted. +//! +// +//***************************************************************************** +void +__error__(char *pcFilename, uint32_t ui32Line) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +//! Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/debug.h b/bsp/boards/mimsy2-cc2538/source/debug.h new file mode 100644 index 0000000000..33a48dfd17 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/debug.h @@ -0,0 +1,70 @@ +/****************************************************************************** +* Filename: debug.h +* Revised: $Date: 2013-04-12 14:54:28 +0200 (Fri, 12 Apr 2013) $ +* Revision: $Revision: 9731 $ +* +* Description: Macros for assisting debug of the driver library. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +#include + +//***************************************************************************** +// +// Prototype for the function that is called when an invalid argument is passed +// to an API. This is only used when doing a ENABLE_ASSERT build. +// +//***************************************************************************** +extern void __error__(char *pcFilename, uint32_t ui32Line); + +//***************************************************************************** +// +// The ASSERT macro, which does the actual assertion checking. Typically, this +// will be for procedure arguments. +// +//***************************************************************************** +#ifdef ENABLE_ASSERT +#define ASSERT(expr) { \ + if(!(expr)) \ + { \ + __error__(__FILE__, __LINE__); \ + } \ + } +#else +#define ASSERT(expr) +#endif + +#endif // __DEBUG_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/ecc_curveinfo.h b/bsp/boards/mimsy2-cc2538/source/ecc_curveinfo.h new file mode 100644 index 0000000000..bf00c21fa4 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/ecc_curveinfo.h @@ -0,0 +1,115 @@ +/****************************************************************************** +* Filename: ecc_curveinfo.h +* Revised: $Date: 2012-10-01 11:15:04 -0700 (Mon, 01 Oct 2012) $ +* Revision: $Revision: 31660 $ +* +* Description: Typedef for the ecc curve information. +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __ECC_CURVES_H__ +#define __ECC_CURVES_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// A structure which contains the necessary elements of the +// Elliptical curve cryptography's (ECC) prime curve. +// +//***************************************************************************** +typedef struct _curveInfo +{ + // + // Name of the curve. + // + char* name; + + // + // Size of the curve in 32-bit word. + // + uint8_t ui8Size; + + // + // The prime that defines the field of the curve. + // + uint32_t* pui32Prime; + + // + // Order of the curve. + // + uint32_t* pui32N; + + // + // Co-efficient a of the equation. + // + uint32_t* pui32A; + + // + // co-efficient b of the equation. + // + uint32_t* pui32B; + + // + // x co-ordinate value of the generator point. + // + uint32_t* pui32Gx; + + // + // y co-ordinate value of the generator point. + // + uint32_t* pui32Gy; +} +tECCCurveInfo; + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __ECC_CURVES_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/flash.c b/bsp/boards/mimsy2-cc2538/source/flash.c new file mode 100644 index 0000000000..8f202773e6 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/flash.c @@ -0,0 +1,475 @@ +/****************************************************************************** +* Filename: flash.c +* Revised: $Date: 2013-03-24 14:46:31 +0100 (Sun, 24 Mar 2013) $ +* Revision: $Revision: 9524 $ +* +* Description: Driver for programming the on-chip flash. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup flash_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include "debug.h" +#include "flash.h" +#include "rom.h" + +//***************************************************************************** +// +//! Erases a flash main page with use of ROM function +//! +//! \param ui32Address is the start address of the flash main page to be erased. +//! +//! This function erases one 2 kB main page of the on-chip flash. After +//! erasing, the page is filled with 0xFF bytes. Locked pages cannot be +//! erased. The flash main pages do not include the upper page. +//! +//! This function does not return until the page is erased or an error +//! encountered. +//! +//! \return Returns 0 on success, -1 if erasing error is encountered, +//! or -2 in case of illegal parameter use. +// +//***************************************************************************** +int32_t +FlashMainPageErase(uint32_t ui32Address) +{ + int32_t i32Stat; // 0 = pass, -1 = fail + uint32_t ui32CurrentCacheMode; + + i32Stat = 0; + + // + // Check the arguments. + // + ASSERT(!(ui32Address < FLASH_BASE)); + ASSERT(!(ui32Address >= (FLASH_BASE + (FlashSizeGet() * 1024) - + FLASH_ERASE_SIZE))); + ASSERT(!(ui32Address & (FLASH_ERASE_SIZE - 1))); + + // + // Save current cache mode since the ROM function will change it. + // + ui32CurrentCacheMode = FlashCacheModeGet(); + + // + // Erase the specified flash main page by calling ROM function. + // + i32Stat = ROM_PageErase(ui32Address, FLASH_ERASE_SIZE); + + // + // Restore cache mode. + // + FlashCacheModeSet(ui32CurrentCacheMode); + + // + // Return status pass or fail. + // + return(i32Stat); +} + +//***************************************************************************** +// +//! Erases the upper flash page with use of ROM function +//! +//! This function erases the 2 kB upper page of the on-chip flash. After +//! erasing, the page is filled with 0xFF bytes. A locked page cannot +//! be erased. +//! +//! This function does not return until the flash page is erased or +//! an error encountered. +//! +//! \return Returns 0 on success, -1 if erasing error is encountered +//! or, -2 in case of illegal parameter use. +// +//***************************************************************************** +int32_t +FlashUpperPageErase(void) +{ + uint32_t ui32UpperPageAddr; + uint32_t ui32CurrentCacheMode; + int32_t i32Stat; // 0 = pass, -1 = fail, -2 = wrong param + + i32Stat = 0; + + // + // Find start address of upper flash page + // + ui32UpperPageAddr = FLASH_BASE + (FlashSizeGet() * 1024) - FLASH_ERASE_SIZE; + + // + // Save current cache mode since the ROM function will change it. + // + ui32CurrentCacheMode = FlashCacheModeGet(); + + // + // Erase the upper flash page by calling ROM function. + // + i32Stat = ROM_PageErase(ui32UpperPageAddr, FLASH_ERASE_SIZE); + + // + // Restore cache mode. + // + FlashCacheModeSet(ui32CurrentCacheMode); + + // + // Return status pass or fail. + // + return(i32Stat); +} + +//***************************************************************************** +// +//! Programs the flash main pages by use of ROM function +//! +//! \param pui32Data is a pointer to the data to be programmed. +//! \param ui32Address is the starting address in flash to be programmed. Must +//! be a multiple of four and within the flash main pages. +//! \param ui32Count is the number of bytes to be programmed. Must be a multiple +//! of four. +//! +//! This function programs a sequence of words into the on-chip flash. +//! Programming each location consists of the result of an AND operation +//! of the new data and the existing data; in other words, bits that contain +//! 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed +//! to 1. Therefore, a word can be programmed multiple times as long as these +//! rules are followed; if a program operation attempts to change a 0 bit to +//! a 1 bit, that bit will not have its value changed. +//! +//! Because the flash is programmed one word at a time, the starting address and +//! byte count must both be multiples of four. The caller must +//! verify the programmed contents, if verification is required. +//! +//! This function does not return until the data is programmed or an +//! error encountered. Locked flash pages cannot be programmed. +//! +//! \return Returns 0 on success, -1 if a programming error is encountered +//! or, -2 in case of illegal parameter use. +// +//***************************************************************************** +int32_t +FlashMainPageProgram(uint32_t *pui32Data, uint32_t ui32Address, + uint32_t ui32Count) +{ + uint32_t ui32CurrentCacheMode; + int32_t i32Stat; // 0 = pass, -1 = fail, -2 = wrong param + + i32Stat = 0; // Start out passing + + // + // Check the arguments. + // + ASSERT(!(ui32Address < FLASH_BASE)); + ASSERT(!((ui32Address + ui32Count) > (FLASH_BASE + (FlashSizeGet() * 1024) - + FLASH_ERASE_SIZE))); + ASSERT(!(ui32Address & 3)); + ASSERT(!(ui32Count & 3)); + + // + // Save current cache mode since the ROM function will change it. + // + ui32CurrentCacheMode = FlashCacheModeGet(); + + // + // Program flash by executing function in ROM. + // + i32Stat = ROM_ProgramFlash(pui32Data, ui32Address, ui32Count); + + // + // Restore cache mode. + // + FlashCacheModeSet(ui32CurrentCacheMode); + + // + // Return status pass or fail. + // + return(i32Stat); +} + +//***************************************************************************** +// +//! Programs the upper page of the flash by use of ROM function +//! +//! \param pui32Data is a pointer to the data to be programmed. +//! \param ui32Address is the starting address within the flash upper page to be +//! programmed. Must be a multiple of four and within the flash upper page. +//! \param ui32Count is the number of bytes to be programmed. Must be a multiple +//! of four. +//! +//! This function programs a sequence of words into the on-chip flash. +//! Programming each location consists of the result of an AND operation +//! of the new data and the existing data; in other words, bits that contain +//! 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed +//! to 1. Therefore, a word can be programmed multiple times as long as these +//! rules are followed; if a program operation attempts to change a 0 bit to +//! a 1 bit, that bit will not have its value changed. +//! +//! Because the flash is programmed one word at a time, the starting address and +//! byte count must both be multiples of four. The caller must +//! verify the programmed contents, if such verification is required. +//! +//! This function does not return until the data is programmed or an +//! error encountered. A locked flash page cannot be programmed. +//! +//! \return Returns 0 on success, -1 if a programming error is encountered +//! or, -2 in case of illegal parameter use. +// +//***************************************************************************** +int32_t +FlashUpperPageProgram(uint32_t *pui32Data, uint32_t ui32Address, + uint32_t ui32Count) +{ + uint32_t ui32CurrentCacheMode; + int32_t i32Stat; // 0 = pass, -1 = fail, -2 = wrong param + + i32Stat = 0; // Start out passing + + // + // Check the arguments. + // + ASSERT(!(ui32Address < (FLASH_BASE + (FlashSizeGet() * 1024) - + FLASH_ERASE_SIZE))); + ASSERT(!((ui32Address + ui32Count) > (FLASH_BASE + + (FlashSizeGet() * 1024)))); + ASSERT(!(ui32Address & 3)); + ASSERT(!(ui32Count & 3)); + + // + // Save current cache mode since the ROM function will change it. + // + ui32CurrentCacheMode = FlashCacheModeGet(); + + // + // Program flash by executing function in ROM. + // + i32Stat = ROM_ProgramFlash(pui32Data, ui32Address, ui32Count); + + // + // Clear flash controller register bit set by ROM function. + // + HWREG(FLASH_CTRL_FCTL) &= (~FLASH_CTRL_FCTL_UPPER_PAGE_ACCESS); + + // + // Restore cache mode. + // + FlashCacheModeSet(ui32CurrentCacheMode); + + // + // Return status pass or fail. + // + return(i32Stat); +} + +//***************************************************************************** +// +//! Gets the current contents of the flash at the designated address +//! +//! \param ui32Addr is the desired address to be read within the flash. +//! +//! This function helps differentiate flash memory reads from flash +//! register reads. +//! +//! \return Returns the 32bit value as an uint32_t value. +// +//***************************************************************************** +uint32_t +FlashGet(uint32_t ui32Addr) +{ + return(HWREG(ui32Addr)); +} + +//***************************************************************************** +// +//! Gets the current state of the flash Cache Mode +//! +//! This function gets the current setting for the Cache Mode. +//! +//! \return Returns the CM bits. Return value should match one of the +//! FLASH_CACHE_MODE_<> macros defined in flash.h. +// +//***************************************************************************** +uint32_t +FlashCacheModeGet(void) +{ + // + // Return a FLASH_CACHE_MODE_<> macro value. + // + return(HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_CM_M); +} + +//***************************************************************************** +// +//! Sets the flash Cache Mode state +//! +//! \param ui32CacheMode is the desired cache mode. +//! +//! This function sets the flash Cache Mode to the desired state and accepts +//! a right justified 2 bit setting for the Cachemode bits. The function waits +//! for the flash to be idle, reads the FCTL register contents, masks in the +//! requested setting, and writes it into the FCTL register. +//! +//! The parameter \e ui32CacheMode can have one of the following values: +//! +//! - \b FLASH_CTRL_CACHE_MODE_DISABLE +//! - \b FLASH_CTRL_CACHE_MODE_ENABLE +//! - \b FLASH_CTRL_CACHE_MODE_PREFETCH_ENABLE +//! - \b FLASH_CTRL_CACHE_MODE_REALTIME +//! +//! \return None +// +//***************************************************************************** +void +FlashCacheModeSet(uint32_t ui32CacheMode) +{ + uint32_t ui32Busy; + uint32_t ui32TempValue; + + // + // Check the arguments. + // + ASSERT((ui32CacheMode == FLASH_CTRL_CACHE_MODE_DISABLE) || + (ui32CacheMode == FLASH_CTRL_CACHE_MODE_ENABLE) || + (ui32CacheMode == FLASH_CTRL_CACHE_MODE_PREFETCH_ENABLE) || + (ui32CacheMode == FLASH_CTRL_CACHE_MODE_REALTIME)); + + // + // Wait until FLASH is not busy. + // + ui32Busy = 1; + while(ui32Busy) + { + ui32TempValue = HWREG(FLASH_CTRL_FCTL); + ui32Busy = ui32TempValue & FLASH_CTRL_FCTL_BUSY; + } + + // + // Set desired cache mode. + // + ui32TempValue &= ~FLASH_CTRL_FCTL_CM_M; + HWREG(FLASH_CTRL_FCTL) = ui32TempValue | ui32CacheMode; +} + +//***************************************************************************** +// +//! Returns the flash size in number of KBytes +//! +//! This function returns the size of the flash in KBytes as determined by +//! examining the FLASH_DIECFG0 register settings. +//! +//! \return Returns the flash size in KBytes +// +//***************************************************************************** +uint32_t +FlashSizeGet(void) +{ + uint32_t ui32RegValue; + uint32_t ui32Size; + + ui32RegValue = HWREG(FLASH_CTRL_DIECFG0); + ui32RegValue = (ui32RegValue & FLASH_CTRL_DIECFG0_FLASH_SIZE_M) >> + FLASH_CTRL_DIECFG0_FLASH_SIZE_S; + + switch(ui32RegValue) + { + case 0x04: + ui32Size = 512; + break; + case 0x03: + ui32Size = 384; + break; + case 0x02: + ui32Size = 256; + break; + case 0x01: + ui32Size = 128; + break; + case 0x00: + ui32Size = 64; + break; + default: + ui32Size = 64; + break; + } + return(ui32Size); +} + +//***************************************************************************** +// +//! Returns the SRAM size in number of KBytes +//! +//! This function returns the size of the SRAM in KBytes as determined by +//! examining the FLASH_DIECFG0 register settings. +//! +//! \return Returns the SRAM size in KBytes +// +//***************************************************************************** +uint32_t +FlashSramSizeGet(void) +{ + uint32_t ui32RegValue; + uint32_t ui32Size; + + ui32RegValue = HWREG(FLASH_CTRL_DIECFG0); + ui32RegValue = (ui32RegValue & FLASH_CTRL_DIECFG0_SRAM_SIZE_M) >> + FLASH_CTRL_DIECFG0_SRAM_SIZE_S; + + switch(ui32RegValue) + { + case 0x04: + ui32Size = 32; + break; + case 0x01: + ui32Size = 8; + break; + case 0x00: + ui32Size = 16; + break; + default: + ui32Size = 32; + break; + } + return(ui32Size); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/flash.h b/bsp/boards/mimsy2-cc2538/source/flash.h new file mode 100644 index 0000000000..57aa2316f6 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/flash.h @@ -0,0 +1,104 @@ +/****************************************************************************** +* Filename: flash.h +* Revised: $Date: 2013-01-23 16:55:36 +0100 (Wed, 23 Jan 2013) $ +* Revision: $Revision: 9193 $ +* +* Description: Prototypes for the flash driver. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __FLASH_H__ +#define __FLASH_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// Values that can be passed to FlashCacheModeSet() +// and returned by FlashCacheModeGet() +// +//***************************************************************************** +#define FLASH_CTRL_CACHE_MODE_DISABLE 0x0 +#define FLASH_CTRL_CACHE_MODE_ENABLE 0x4 +#define FLASH_CTRL_CACHE_MODE_PREFETCH_ENABLE 0x8 +#define FLASH_CTRL_CACHE_MODE_REALTIME 0xc + +//***************************************************************************** +// +// Define for the erase size of the FLASH block that is erased by an erase +// operation. +// +//**************************************************************************** +#define FLASH_ERASE_SIZE 0x800 + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern int32_t FlashMainPageErase(uint32_t ui32Address); +extern int32_t FlashUpperPageErase(void); +extern int32_t FlashMainPageProgram(uint32_t *pui32Data, + uint32_t ui32Address, + uint32_t ui32Count); +extern int32_t FlashUpperPageProgram(uint32_t *pui32Data, + uint32_t ui32Address, + uint32_t ui32Count); + +extern uint32_t FlashGet(uint32_t ui32Addr); +extern uint32_t FlashCacheModeGet(void); +extern void FlashCacheModeSet(uint32_t ui32CacheMode); +extern uint32_t FlashSizeGet(void); +extern uint32_t FlashSramSizeGet(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __FLASH_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/gpio.c b/bsp/boards/mimsy2-cc2538/source/gpio.c new file mode 100644 index 0000000000..b33a221d9a --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/gpio.c @@ -0,0 +1,1377 @@ +/****************************************************************************** +* Filename: gpio.c +* Revised: $Date: 2013-04-29 09:36:44 +0200 (Mon, 29 Apr 2013) $ +* Revision: $Revision: 9922 $ +* +* Description: Driver for the GPIO controller. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup gpio_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include +#include "debug.h" +#include "gpio.h" +#include "interrupt.h" +#include "ioc.h" + +//***************************************************************************** +// +//! \internal +//! Checks a GPIO base address +//! +//! \param ui32Port is the base address of the GPIO port. +//! +//! This function determines if a GPIO port base address is valid. +//! +//! \return Returns \b true if the base address is valid and \b false +//! otherwise. +// +//***************************************************************************** +#ifdef ENABLE_ASSERT +static bool +GPIOBaseValid(uint32_t ui32Port) +{ + return((ui32Port == GPIO_A_BASE) || (ui32Port == GPIO_B_BASE) || + (ui32Port == GPIO_C_BASE) || (ui32Port == GPIO_D_BASE)); +} +#endif + +//***************************************************************************** +// +//! \internal +//! Gets the GPIO interrupt number +//! +//! \param ui32Port is the base address of the GPIO port. +//! +//! Given a GPIO base address, returns the corresponding interrupt number. +//! +//! \return Returns a GPIO interrupt number, or 0 if \e ui32Port is invalid. +// +//***************************************************************************** +uint32_t +GPIOGetIntNumber(uint32_t ui32Port) +{ + uint32_t ui32Int; + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Determine the GPIO interrupt number for the given module. + // + switch(ui32Port) + { + case GPIO_A_BASE: + { + ui32Int = INT_GPIOA; + break; + } + + case GPIO_B_BASE: + { + ui32Int = INT_GPIOB; + break; + } + + case GPIO_C_BASE: + { + ui32Int = INT_GPIOC; + break; + } + + case GPIO_D_BASE: + { + ui32Int = INT_GPIOD; + break; + } + + default: + { + return(0); + } + } + + // + // Return GPIO interrupt number. + // + return(ui32Int); +} + +//***************************************************************************** +// +//! Sets the direction and mode of the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! \param ui32PinIO is the pin direction and/or mode. +//! +//! This function sets the specified pin(s) on the selected GPIO port +//! as either an input or output under software control or sets the +//! pin to be under hardware control. +//! +//! The parameter \e ui32PinIO is an enumerated data type that can be one of +//! the following values: +//! +//! - \b GPIO_DIR_MODE_IN +//! - \b GPIO_DIR_MODE_OUT +//! - \b GPIO_DIR_MODE_HW +//! +//! where \b GPIO_DIR_MODE_IN specifies that the pin will be programmed as +//! a software controlled input, \b GPIO_DIR_MODE_OUT specifies that the pin +//! will be programmed as a software controlled output, and +//! \b GPIO_DIR_MODE_HW specifies that the pin will be placed under +//! hardware control. +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +GPIODirModeSet(uint32_t ui32Port, uint8_t ui8Pins, + uint32_t ui32PinIO) +{ + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + ASSERT((ui32PinIO == GPIO_DIR_MODE_IN) || (ui32PinIO == GPIO_DIR_MODE_OUT) || + (ui32PinIO == GPIO_DIR_MODE_HW)); + + // + // Set the pin direction and mode. + // + HWREG(ui32Port + GPIO_O_DIR) = ((ui32PinIO & GPIO_DIR_MODE_OUT) ? + (HWREG(ui32Port + GPIO_O_DIR) | ui8Pins) : + (HWREG(ui32Port + GPIO_O_DIR) & ~(ui8Pins))); + HWREG(ui32Port + GPIO_O_AFSEL) = ((ui32PinIO & GPIO_DIR_MODE_HW) ? + (HWREG(ui32Port + GPIO_O_AFSEL) | ui8Pins) : + (HWREG(ui32Port + GPIO_O_AFSEL) & ~(ui8Pins))); +} + +//***************************************************************************** +// +//! Gets the direction and mode of a pin +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pin is the pin number. +//! +//! This function gets the direction and control mode for a specified pin on +//! the selected GPIO port. The pin can be configured as either an input or +//! output under software control, or it can be under hardware control. The +//! type of control and direction are returned as an enumerated data type. +//! +//! \return Returns one of the enumerated data types described for +//! GPIODirModeSet(). +// +//***************************************************************************** +uint32_t +GPIODirModeGet(uint32_t ui32Port, uint8_t ui8Pin) +{ + uint32_t ui32Dir; + uint32_t ui32AFSEL; + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + ASSERT(ui8Pin < 8); + + // + // Convert from a pin number to a bit position. + // + ui8Pin = 1 << ui8Pin; + + // + // Return the pin direction and mode. + // + ui32Dir = HWREG(ui32Port + GPIO_O_DIR); + ui32AFSEL = HWREG(ui32Port + GPIO_O_AFSEL); + return(((ui32Dir & ui8Pin) ? GPIO_DIR_MODE_OUT : GPIO_DIR_MODE_IN) | + ((ui32AFSEL & ui8Pin) ? GPIO_DIR_MODE_HW : GPIO_DIR_MODE_IN)); +} + +//***************************************************************************** +// +//! Sets the interrupt type for the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! \param ui32IntType specifies the type of interrupt trigger mechanism. +//! +//! This function sets up the various interrupt trigger mechanisms for the +//! specified pin(s) on the selected GPIO port. +//! +//! The parameter \e ui32IntType is an enumerated data type that can be one of +//! the following values: +//! +//! - \b GPIO_FALLING_EDGE +//! - \b GPIO_RISING_EDGE +//! - \b GPIO_BOTH_EDGES +//! - \b GPIO_LOW_LEVEL +//! - \b GPIO_HIGH_LEVEL +//! +//! where the different values describe the interrupt detection mechanism +//! (edge or level) and the particular triggering event (falling, rising, +//! or both edges for edge detect, low or high for level detect). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \note To avoid any spurious interrupts, the user must +//! ensure that the GPIO inputs remain stable for the duration of +//! this function. +//! +//! \return None +// +//***************************************************************************** +void +GPIOIntTypeSet(uint32_t ui32Port, uint8_t ui8Pins, + uint32_t ui32IntType) +{ + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + ASSERT((ui32IntType == GPIO_FALLING_EDGE) || + (ui32IntType == GPIO_RISING_EDGE) || (ui32IntType == GPIO_BOTH_EDGES) || + (ui32IntType == GPIO_LOW_LEVEL) || (ui32IntType == GPIO_HIGH_LEVEL)); + + // + // Set the pin interrupt type. + // + HWREG(ui32Port + GPIO_O_IBE) = ((ui32IntType & 1) ? + (HWREG(ui32Port + GPIO_O_IBE) | ui8Pins) : + (HWREG(ui32Port + GPIO_O_IBE) & ~(ui8Pins))); + HWREG(ui32Port + GPIO_O_IS) = ((ui32IntType & 2) ? + (HWREG(ui32Port + GPIO_O_IS) | ui8Pins) : + (HWREG(ui32Port + GPIO_O_IS) & ~(ui8Pins))); + HWREG(ui32Port + GPIO_O_IEV) = ((ui32IntType & 4) ? + (HWREG(ui32Port + GPIO_O_IEV) | ui8Pins) : + (HWREG(ui32Port + GPIO_O_IEV) & ~(ui8Pins))); +} + +//***************************************************************************** +// +//! Gets the interrupt type for a pin +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pin is the pin number. +//! +//! This function gets the interrupt type for a specified pin on the selected +//! GPIO port. The pin can be configured as a falling edge, rising edge, or +//! both edge detected interrupt, or can be configured as a low level or +//! high level detected interrupt. The type of interrupt detection mechanism +//! is returned as an enumerated data type. +//! +//! \return Returns one of the enumerated data types described for +//! GPIOIntTypeSet(). +// +//***************************************************************************** +uint32_t +GPIOIntTypeGet(uint32_t ui32Port, uint8_t ui8Pin) +{ + uint32_t ui32IBE, ui32IS, ui32IEV; + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + ASSERT(ui8Pin < 8); + + // + // Convert from a pin number to a bit position. + // + ui8Pin = 1 << ui8Pin; + + // + // Return the pin interrupt type. + // + ui32IBE = HWREG(ui32Port + GPIO_O_IBE); + ui32IS = HWREG(ui32Port + GPIO_O_IS); + ui32IEV = HWREG(ui32Port + GPIO_O_IEV); + return(((ui32IBE & ui8Pin) ? 1 : 0) | ((ui32IS & ui8Pin) ? 2 : 0) | + ((ui32IEV & ui8Pin) ? 4 : 0)); +} + +//***************************************************************************** +// +//! Enables interrupts for the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! Unmasks the interrupt for the specified pin(s). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinIntEnable(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Enable the interrupts. + // + HWREG(ui32Port + GPIO_O_IE) |= ui8Pins; +} + +//***************************************************************************** +// +//! Disables interrupts for the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! Masks the interrupt for the specified pin(s) +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinIntDisable(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Disable the interrupts. + // + HWREG(ui32Port + GPIO_O_IE) &= ~(ui8Pins); +} + +//***************************************************************************** +// +//! Gets interrupt status for the specified GPIO port +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param bMasked specifies whether masked or raw interrupt status is +//! returned. +//! +//! If \e bMasked is set as \b true, then the masked interrupt status is +//! returned; otherwise, the raw interrupt status is returned. +//! +//! \return Returns a bit-packed byte, where each bit that is set identifies +//! an active masked or raw interrupt, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! Bits 31:8 should be ignored. +// +//***************************************************************************** +uint32_t +GPIOPinIntStatus(uint32_t ui32Port, bool bMasked) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Return the interrupt status. + // + if(bMasked) + { + return(HWREG(ui32Port + GPIO_O_MIS)); + } + else + { + return(HWREG(ui32Port + GPIO_O_RIS)); + } +} + +//***************************************************************************** +// +//! Clears the interrupt for the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! Clears the interrupt for the specified pin(s). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \note The write buffer in the Cortex-M3 processor can cause the interrupt +//! source to take several clock cycles before clearing. +//! Therefore, TI recommends clearing the interrupt source early in the +//! interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to clear the interrupt source early can result in +//! the interrupt handler being immediately reentered (because NVIC still sees +//! the interrupt source asserted). +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinIntClear(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Clear the interrupts. + // + HWREG(ui32Port + GPIO_O_IC) = ui8Pins; +} + +//***************************************************************************** +// +//! Registers an interrupt handler for a GPIO port +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param pfnHandler is a pointer to the GPIO port interrupt handling +//! function. +//! +//! This function ensures that the interrupt handler specified by +//! \e pfnHandler is called when an interrupt is detected from the selected +//! GPIO port. This function also enables the corresponding GPIO interrupt +//! in the interrupt controller; individual pin interrupts and interrupt +//! sources must be enabled with GPIOPinIntEnable(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPortIntRegister(uint32_t ui32Port, void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Get the interrupt number associated with the specified GPIO. + // + ui32Port = GPIOGetIntNumber(ui32Port); + + // + // Register the interrupt handler. + // + IntRegister(ui32Port, pfnHandler); + + // + // Enable the GPIO interrupt. + // + IntEnable(ui32Port); +} + +//***************************************************************************** +// +//! Removes an interrupt handler for a GPIO port +//! +//! \param ui32Port is the base address of the GPIO port. +//! +//! This function unregisters the interrupt handler for the specified +//! GPIO port. This function also disables the corresponding +//! GPIO port interrupt in the interrupt controller; individual GPIO interrupts +//! and interrupt sources must be disabled with GPIOPinIntDisable(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPortIntUnregister(uint32_t ui32Port) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Get the interrupt number associated with the specified GPIO. + // + ui32Port = GPIOGetIntNumber(ui32Port); + + // + // Disable the GPIO interrupt. + // + IntDisable(ui32Port); + + // + // Unregister the interrupt handler. + // + IntUnregister(ui32Port); +} + +//***************************************************************************** +// +//! Reads the values present of the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! The values at the specified pin(s) are read, as specified by \e ui8Pins. +//! Values are returned for both input and output pin(s), and the value +//! for pin(s) that are not specified by \e ui8Pins are set to 0. +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return Returns a bit-packed byte providing the state of the specified +//! pin, where bit 0 of the byte represents GPIO port pin 0, bit 1 represents +//! GPIO port pin 1, and so on. Any bit that is not specified by \e ui8Pins +//! is returned as a 0. Bits 31:8 should be ignored. +// +//***************************************************************************** +uint32_t +GPIOPinRead(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Return the pin value(s). + // + return(HWREG(ui32Port + (GPIO_O_DATA + (ui8Pins << 2)))); +} + +//***************************************************************************** +// +//! Writes a value to the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! \param ui8Val is the value to write to the pin(s). +//! +//! Writes the corresponding bit values to the output pin(s) specified by +//! \e ui8Pins. Writing to a pin configured as an input pin has no effect. +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinWrite(uint32_t ui32Port, uint8_t ui8Pins, uint8_t ui8Val) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Write the pins. + // + HWREG(ui32Port + (GPIO_O_DATA + (ui8Pins << 2))) = ui8Val; +} + +//***************************************************************************** +// +//! Configures pin(s) for use as GPIO inputs +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! The GPIO pins must be properly configured in order to function correctly as +//! GPIO inputs. This function provides the proper configuration for those +//! pin(s). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinTypeGPIOInput(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Make the pin(s) be inputs. + // + GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_IN); + + // + // Set the pad(s) to no override of the drive type. + // + IOCPadConfigSet(ui32Port, ui8Pins, IOC_OVERRIDE_DIS); +} + +//***************************************************************************** +// +//! Configures pin(s) for use as GPIO outputs +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! The GPIO pins must be properly configured to function correctly as +//! GPIO outputs. This function provides the proper configuration for those +//! pin(s). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinTypeGPIOOutput(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Make the pin(s) be outputs. + // + GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_OUT); + + // + // Set the pad(s) no override of the drive type. + // + IOCPadConfigSet(ui32Port, ui8Pins, IOC_OVERRIDE_DIS); +} + +//***************************************************************************** +// +//! Configures pin(s) for use by the I2C peripheral +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! The I2C pins must be properly configured for the I2C peripheral to function +//! correctly. This function provides the proper configuration for those +//! pin(s). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \note This function cannot be used to turn any pin into an I2C pin; it only +//! configures an I2C pin for proper operation. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinTypeI2C(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) to no drive type. + // + IOCPadConfigSet(ui32Port, ui8Pins, IOC_OVERRIDE_DIS); +} + +//***************************************************************************** +// +//! Configures pin(s) for use by the SSI peripheral +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! The SSI pins must be properly configured for the SSI peripheral to function +//! correctly. This function provides a typical configuration for those +//! pin(s); other configurations might work as well depending upon the board +//! setup (for example, using the on-chip pull-ups). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \note This function cannot be used to turn any pin into a SSI pin; but only +//! configures an SSI pin for proper operation. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinTypeSSI(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) to no drive type. + // + IOCPadConfigSet(ui32Port, ui8Pins, IOC_OVERRIDE_DIS); +} + +//***************************************************************************** +// +//! Configures pin(s) for use by the Timer peripheral +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! The CCP pins must be properly configured for the timer peripheral to +//! function correctly. This function provides a typical configuration for +//! those pin(s); other configurations might work as well depending upon the +//! board setup (for example, using the on-chip pull-ups). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \note This function cannot be used to turn any pin into a timer pin but only +//! configures a timer pin for proper operation. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinTypeTimer(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) to no drive type. + // + IOCPadConfigSet(ui32Port, ui8Pins, IOC_OVERRIDE_DIS); +} + +//***************************************************************************** +// +//! Configures input pin(s) for use by the UART peripheral +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! The UART input pins must be properly configured for the UART peripheral to +//! function correctly. This function provides a typical configuration for +//! those pin(s); other configurations might work as well depending upon the +//! board setup (for example, using the on-chip pull-ups). +//! +//! \note For PC0 through PC3 the function GPIOPinTypeUARTHiDrive() should +//! be used to configure these high drive pins. +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \note This function cannot be used to turn any pin into a UART pin; but only +//! configures a UART pin for proper operation. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinTypeUARTInput(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + ASSERT(!((ui32Port == GPIO_C_BASE) && ((ui8Pins & 0xf) > 0))); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) to override disable. + // + IOCPadConfigSet(ui32Port, ui8Pins, IOC_OVERRIDE_DIS); +} + +//***************************************************************************** +// +//! Configures output pin(s) for use by the UART peripheral +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! The UART output pins must be properly configured for the UART peripheral to +//! function correctly. This function provides a typical configuration for +//! those pin(s); other configurations might work as well depending upon the +//! board setup (for example, using the on-chip pull-ups). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \note This function cannot be used to turn any pin into a UART pin; but only +//! configures a UART pin for proper operation. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPinTypeUARTOutput(uint32_t ui32Port, uint8_t ui8Pins) +{ + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + ASSERT(!((ui32Port == GPIO_C_BASE) && ((ui8Pins & 0xf) > 0))); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) to output enable. + // + IOCPadConfigSet(ui32Port, ui8Pins, IOC_OVERRIDE_OE); +} + +//***************************************************************************** +// +//! Sets the power-up interrupt type for the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! \param ui32IntType specifies type of power-up interrupt trigger mechanism. +//! +//! This function sets up the various interrupt trigger mechanisms for the +//! specified pin(s) on the selected GPIO port. +//! +//! The parameter \e ui32IntType is an enumerated data type that can be one of +//! the following values: +//! +//! - \b GPIO_POW_FALLING_EDGE +//! - \b GPIO_POW_RISING_EDGE +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \note To avoid any spurious interrupts, the user must +//! ensure that the GPIO inputs remain stable for the duration of +//! this function. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPowIntTypeSet(uint32_t ui32Port, uint8_t ui8Pins, + uint32_t ui32IntType) +{ + uint32_t ui32PortOffset; + uint32_t ui32IntPins; + + // + // Initialize value + // + ui32PortOffset = 0; + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + ASSERT((ui32IntType == GPIO_POW_FALLING_EDGE) || + (ui32IntType == GPIO_POW_RISING_EDGE)); + + // + // Find bit mask for wanted pin(s) + // + if(ui32Port == GPIO_A_BASE) + { + ui32PortOffset = 0; + } + if(ui32Port == GPIO_B_BASE) + { + ui32PortOffset = 8; + } + if(ui32Port == GPIO_C_BASE) + { + ui32PortOffset = 16; + } + if(ui32Port == GPIO_D_BASE) + { + ui32PortOffset = 24; + } + ui32IntPins = ui8Pins << ui32PortOffset; + + // + // Set the pin interrupt type. + // + if(ui32IntType == GPIO_POW_FALLING_EDGE) + { + HWREG(ui32Port + GPIO_O_P_EDGE_CTRL) |= ui32IntPins; + } + else // GPIO_POW_RAISING_EDGE + { + HWREG(ui32Port + GPIO_O_P_EDGE_CTRL) &= ~(ui32IntPins); + } +} + +//***************************************************************************** +// +//! Gets the power-up interrupt type for a pin +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pin is the pin number. +//! +//! This function gets the interrupt type for a specified pin on the selected +//! GPIO port. The pin can be configured as a falling edge, rising edge, or +//! both edge detected interrupt, or it can be configured as a low level or +//! high level detected interrupt. The type of interrupt detection mechanism +//! is returned as an enumerated data type. +//! +//! \return Returns one of the enumerated data types described for +//! GPIOIntTypeSet(). +// +//***************************************************************************** +uint32_t +GPIOPowIntTypeGet(uint32_t ui32Port, uint8_t ui8Pin) +{ + uint32_t ui32PortOffset; + uint32_t ui32IntPin; + + // + // Initialize value + // + ui32PortOffset = 0; + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + ASSERT(ui8Pin < 8); + + // + // Convert from a port- pin number to a bit position. + // + if(ui32Port == GPIO_A_BASE) + { + ui32PortOffset = 0; + } + if(ui32Port == GPIO_B_BASE) + { + ui32PortOffset = 8; + } + if(ui32Port == GPIO_C_BASE) + { + ui32PortOffset = 16; + } + if(ui32Port == GPIO_D_BASE) + { + ui32PortOffset = 24; + } + ui32IntPin = 1 << (ui8Pin + ui32PortOffset); + + // + // Return the pin interrupt type. + // + if(HWREG(ui32Port + GPIO_O_P_EDGE_CTRL) & ui32IntPin) + { + return(GPIO_POW_FALLING_EDGE); + } + else + { + return(GPIO_POW_RISING_EDGE); + } +} + +//***************************************************************************** +// +//! Enables power-up interrupts for the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! Unmasks the interrupt for the specified pin(s). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPowIntEnable(uint32_t ui32Port, uint8_t ui8Pins) +{ + uint32_t ui32PortOffset; + uint32_t ui32IntPins; + + // + // Initialize value + // + ui32PortOffset = 0; + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Find bit mask for wanted pin(s) + // + if(ui32Port == GPIO_A_BASE) + { + ui32PortOffset = 0; + } + if(ui32Port == GPIO_B_BASE) + { + ui32PortOffset = 8; + } + if(ui32Port == GPIO_C_BASE) + { + ui32PortOffset = 16; + } + if(ui32Port == GPIO_D_BASE) + { + ui32PortOffset = 24; + } + ui32IntPins = ui8Pins << ui32PortOffset; + + // + // Enable the interrupts. + // + HWREG(ui32Port + GPIO_O_PI_IEN) |= ui32IntPins; +} + +//***************************************************************************** +// +//! Disables power-up interrupts for the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! Masks the interrupt for the specified pin(s). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPowIntDisable(uint32_t ui32Port, uint8_t ui8Pins) +{ + uint32_t ui32PortOffset; + uint32_t ui32IntPins; + + // + // Initialize value + // + ui32PortOffset = 0; + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Find bit mask for wanted pin(s) + // + if(ui32Port == GPIO_A_BASE) + { + ui32PortOffset = 0; + } + if(ui32Port == GPIO_B_BASE) + { + ui32PortOffset = 8; + } + if(ui32Port == GPIO_C_BASE) + { + ui32PortOffset = 16; + } + if(ui32Port == GPIO_D_BASE) + { + ui32PortOffset = 24; + } + ui32IntPins = ui8Pins << ui32PortOffset; + + // + // Disable the interrupts. + // + HWREG(ui32Port + GPIO_O_PI_IEN) &= ~(ui32IntPins); +} + +//***************************************************************************** +// +//! Gets power-up interrupt status for the specified GPIO port +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param bMasked specifies whether masked or raw interrupt status is +//! returned. +//! +//! If \e bMasked is set as \b true, then the masked interrupt status is +//! returned; otherwise, the raw interrupt status is returned. +//! +//! \return Returns a bit-packed byte, where each bit that is set identifies +//! an active masked or raw interrupt, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! Bits 31:8 should be ignored. +// +//***************************************************************************** +uint32_t +GPIOPowIntStatus(uint32_t ui32Port, bool bMasked) +{ + uint32_t ui32PortOffset; + + // + // Initialize value + // + ui32PortOffset = 0; + + // Check the arguments. + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Find bit mask for wanted pin(s) + // + if(ui32Port == GPIO_A_BASE) + { + ui32PortOffset = 0; + } + if(ui32Port == GPIO_B_BASE) + { + ui32PortOffset = 8; + } + if(ui32Port == GPIO_C_BASE) + { + ui32PortOffset = 16; + } + if(ui32Port == GPIO_D_BASE) + { + ui32PortOffset = 24; + } + + // Return the interrupt status. + if(bMasked) + { + return((HWREG(ui32Port + GPIO_O_IRQ_DETECT_ACK) >> ui32PortOffset) & + 0xFF); + } + else + { + return((HWREG(ui32Port + GPIO_O_IRQ_DETECT_UNMASK) >> ui32PortOffset) & + 0xFF); + } +} + +//***************************************************************************** +// +//! Clears the power-up interrupt for the specified pin(s) +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the pin(s). +//! +//! Clears the interrupt for the specified pin(s). +//! +//! The pin(s) are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +GPIOPowIntClear(uint32_t ui32Port, uint8_t ui8Pins) +{ + uint32_t ui32PortOffset; + uint32_t ui32IntPins; + + // + // Initialize value + // + ui32PortOffset = 0; + + // + // Check the arguments. + // + ASSERT(GPIOBaseValid(ui32Port)); + + // + // Find bit mask for wanted pin(s) + // + if(ui32Port == GPIO_A_BASE) + { + ui32PortOffset = 0; + } + if(ui32Port == GPIO_B_BASE) + { + ui32PortOffset = 8; + } + if(ui32Port == GPIO_C_BASE) + { + ui32PortOffset = 16; + } + if(ui32Port == GPIO_D_BASE) + { + ui32PortOffset = 24; + } + ui32IntPins = ui8Pins << ui32PortOffset; + + // + // Clear the interrupts. + // + HWREG(ui32Port + GPIO_O_IRQ_DETECT_ACK) |= ui32IntPins; +} + +//***************************************************************************** +// +//! Enable Wake Up Interrupt +//! +//! \param ui32Config is the source to enable wake up on interrupt. +//! +//! This function enables wake up on interrupt from the selected sources. +//! +//! The \e ui32Config argument must be one or the logical or of several of +//! the following values: +//! +//! \b GPIO_IWE_PORT_A, \b GPIO_IWE_PORT_B, \b GPIO_IWE_PORT_C, +//! \b GPIO_IWE_PORT_D, \b GPIO_IWE_USB, +//! \b GPIO_IWE_SM_TIMER. +//! +//! \return None +// +//***************************************************************************** +void +GPIOIntWakeupEnable(uint32_t ui32Config) +{ + ASSERT((ui32Config & + (GPIO_IWE_PORT_A | + GPIO_IWE_PORT_B | + GPIO_IWE_PORT_C | + GPIO_IWE_PORT_D | + GPIO_IWE_USB | + GPIO_IWE_SM_TIMER)) != 0); + + // + // Enable Wakeup from selected Interrupt sources + // + HWREG(SYS_CTRL_IWE) |= ui32Config; +} + +//***************************************************************************** +// +//! Disable Wake Up Interrupt +//! +//! \param ui32Config is the source to disable wake on interrupt from. +//! +//! This function disables Wake up on interrupt from the selected sources. +//! +//! The \e ui32Config argument must be one or the logical or of several of +//! the following values: +//! +//! \b GPIO_IWE_PORT_A, \b GPIO_IWE_PORT_B, \b GPIO_IWE_PORT_C, +//! \b GPIO_IWE_PORT_D, \b GPIO_IWE_USB, +//! \b GPIO_IWE_SM_TIMER, +//! +//! \return None +// +//***************************************************************************** +void +GPIOIntWakeupDisable(uint32_t ui32Config) +{ + ASSERT((ui32Config & + (GPIO_IWE_PORT_A | + GPIO_IWE_PORT_B | + GPIO_IWE_PORT_C | + GPIO_IWE_PORT_D | + GPIO_IWE_USB | + GPIO_IWE_SM_TIMER)) != 0); + + // + // Disable Wakeup from selected Interrupt sources + // + HWREG(SYS_CTRL_IWE) &= ~ui32Config; +} + +//***************************************************************************** +//! Close the Doxygen group. +//! @} +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/gpio.h b/bsp/boards/mimsy2-cc2538/source/gpio.h new file mode 100644 index 0000000000..8bd3153b2f --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/gpio.h @@ -0,0 +1,169 @@ +/****************************************************************************** +* Filename: gpio.h +* Revised: $Date: 2013-02-06 15:01:04 +0100 (Wed, 06 Feb 2013) $ +* Revision: $Revision: 9297 $ +* +* Description: Prototypes for the GPIO driver. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __GPIO_H__ +#define __GPIO_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// The following values define the bit field for the ui8Pins argument to several +// of the APIs. +// +//***************************************************************************** +#define GPIO_PIN_0 0x00000001 // GPIO pin 0 +#define GPIO_PIN_1 0x00000002 // GPIO pin 1 +#define GPIO_PIN_2 0x00000004 // GPIO pin 2 +#define GPIO_PIN_3 0x00000008 // GPIO pin 3 +#define GPIO_PIN_4 0x00000010 // GPIO pin 4 +#define GPIO_PIN_5 0x00000020 // GPIO pin 5 +#define GPIO_PIN_6 0x00000040 // GPIO pin 6 +#define GPIO_PIN_7 0x00000080 // GPIO pin 7 + +//***************************************************************************** +// +// Values that can be passed to GPIODirModeSet as the ui32PinIO parameter, and +// returned from GPIODirModeGet. +// +//***************************************************************************** +#define GPIO_DIR_MODE_IN 0x00000000 // Pin is a GPIO input +#define GPIO_DIR_MODE_OUT 0x00000001 // Pin is a GPIO output +#define GPIO_DIR_MODE_HW 0x00000002 // Pin is a peripheral function + +//***************************************************************************** +// +// Values that can be passed to GPIOIntTypeSet as the ui32IntType parameter, and +// returned from GPIOIntTypeGet. +// +//***************************************************************************** +#define GPIO_FALLING_EDGE 0x00000000 // Interrupt on falling edge +#define GPIO_RISING_EDGE 0x00000004 // Interrupt on rising edge +#define GPIO_BOTH_EDGES 0x00000001 // Interrupt on both edges +#define GPIO_LOW_LEVEL 0x00000002 // Interrupt on low level +#define GPIO_HIGH_LEVEL 0x00000007 // Interrupt on high level + +//***************************************************************************** +// +// Values that can be passed to the GPIOPowIntTypeSet function as the ui32IntType +// parameter and returned from the GPIOPowIntTypeGet function. +// +//***************************************************************************** +#define GPIO_POW_RISING_EDGE 0x00000000 // Interrupt on rising edge +#define GPIO_POW_FALLING_EDGE 0x00000001 // Interrupt on falling edge + +//***************************************************************************** +// +// The following are values that can be passed to the GPIOIntWakeupEnable() +// and GPIOIntWakeupDiable() API as the ui32Config parameter. +// +//***************************************************************************** +#define GPIO_IWE_PORT_A 0x00000001 // Port A Wake up Interrupt +#define GPIO_IWE_PORT_B 0x00000002 // Port B Wake up Interrupt +#define GPIO_IWE_PORT_C 0x00000004 // Port C Wake up Interrupt +#define GPIO_IWE_PORT_D 0x00000008 // Port D Wake up Interrupt +#define GPIO_IWE_USB 0x00000010 // USB Wake up Interrupt +#define GPIO_IWE_SM_TIMER 0x00000020 // SM Timer Wake up Interrupt + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void GPIODirModeSet(uint32_t ui32Port, uint8_t ui8Pins, + uint32_t ui32PinIO); +extern uint32_t GPIODirModeGet(uint32_t ui32Port, uint8_t ui8Pin); + +extern uint32_t GPIOGetIntNumber(uint32_t ui32Port); +extern void GPIOIntTypeSet(uint32_t ui32Port, uint8_t ui8Pins, + uint32_t ui32IntType); +extern uint32_t GPIOIntTypeGet(uint32_t ui32Port, uint8_t ui8Pin); +extern void GPIOPinIntEnable(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPinIntDisable(uint32_t ui32Port, uint8_t ui8Pins); +extern uint32_t GPIOPinIntStatus(uint32_t ui32Port, bool bMasked); +extern void GPIOPinIntClear(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPortIntRegister(uint32_t ui32Port, + void (*pfnHandler)(void)); +extern void GPIOPortIntUnregister(uint32_t ui32Port); + +extern uint32_t GPIOPinRead(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPinWrite(uint32_t ui32Port, uint8_t ui8Pins, + uint8_t ui8Val); + +extern void GPIOPinTypeGPIOInput(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPinTypeGPIOOutput(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPinTypeI2C(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPinTypeSSI(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPinTypeTimer(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPinTypeUARTInput(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPinTypeUARTOutput(uint32_t ui32Port, uint8_t ui8Pins); + +extern void GPIOPowIntEnable(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPowIntDisable(uint32_t ui32Port, uint8_t ui8Pins); +extern void GPIOPowIntTypeSet(uint32_t ui32Port, uint8_t ui8Pins, + uint32_t ui32IntType); +extern uint32_t GPIOPowIntTypeGet(uint32_t ui32Port, + uint8_t ui8Pin); +extern uint32_t GPIOPowIntStatus(uint32_t ui32Port, bool bMasked); +extern void GPIOPowIntClear(uint32_t ui32Port, uint8_t ui8Pins); + +extern void GPIOIntWakeupEnable(uint32_t ui32Config); +extern void GPIOIntWakeupDisable(uint32_t ui32Config); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __GPIO_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/gptimer.c b/bsp/boards/mimsy2-cc2538/source/gptimer.c new file mode 100644 index 0000000000..6445e2937a --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/gptimer.c @@ -0,0 +1,1128 @@ +/****************************************************************************** +* Filename: gptimer.c +* Revised: $Date: 2013-04-12 14:54:28 +0200 (Fri, 12 Apr 2013) $ +* Revision: $Revision: 9731 $ +* +* Description: Driver for the general purpose timer module. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup timer_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include "debug.h" +#include "interrupt.h" +#include "gptimer.h" + +//***************************************************************************** +// +//! \internal +//! Checks a timer base address +//! +//! \param ui32Base is the base address of the timer module. +//! +//! This function determines if a timer module base address is valid. +//! +//! \return Returns \b true if the base address is valid and \b false +//! otherwise. +// +//***************************************************************************** +#ifdef ENABLE_ASSERT +static bool +TimerBaseValid(uint32_t ui32Base) +{ + return((ui32Base == GPTIMER0_BASE) || (ui32Base == GPTIMER1_BASE) || + (ui32Base == GPTIMER2_BASE) || (ui32Base == GPTIMER3_BASE)); +} +#endif + +//***************************************************************************** +// +//! Enables the timer(s) +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to enable; must be one of \b GPTIMER_A, +//! \b GPTIMER_B, or \b GPTIMER_BOTH. +//! +//! This function enables operation of the timer module. The timer must be +//! configured before it is enabled. +//! +//! \return None +// +//***************************************************************************** +void +TimerEnable(uint32_t ui32Base, uint32_t ui32Timer) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Enable the timer(s) module. + // + HWREG(ui32Base + GPTIMER_O_CTL) |= ui32Timer & (GPTIMER_CTL_TAEN | GPTIMER_CTL_TBEN); +} + +//***************************************************************************** +// +//! Disables the timer(s) +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to disable; must be one of +//! \b GPTIMER_A, \b GPTIMER_B, or \b GPTIMER_BOTH. +//! +//! This function disables operation of the timer module. +//! +//! \return None +// +//***************************************************************************** +void +TimerDisable(uint32_t ui32Base, uint32_t ui32Timer) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Disable the timer module. + // + HWREG(ui32Base + GPTIMER_O_CTL) &= ~(ui32Timer & + (GPTIMER_CTL_TAEN | GPTIMER_CTL_TBEN)); +} + + +//***************************************************************************** +// +//! Configures the timer(s) +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Config is the configuration for the timer. +//! +//! This function configures the operating mode of the timer(s). The timer +//! module is disabled before being configured, and is left in the disabled +//! state. +//! The 16/32-bit timer is comprised of two 16-bit timers that can +//! operate independently or be concatenated to form a 32-bit timer. +//! +//! The configuration is specified in \e ui32Config as one of the following +//! values: +//! +//! - \b GPTIMER_CFG_ONE_SHOT - Full-width one-shot timer +//! - \b GPTIMER_CFG_ONE_SHOT_UP - Full-width one-shot timer that counts up +//! instead of down (not available on all parts) +//! - \b GPTIMER_CFG_PERIODIC - Full-width periodic timer +//! - \b GPTIMER_CFG_PERIODIC_UP - Full-width periodic timer that counts up +//! instead of down (not available on all parts) +//! - \b GPTIMER_CFG_SPLIT_PAIR - Two half-width timers +//! +//! When configured for a pair of half-width timers, each timer is separately +//! configured. The first timer is configured by setting \e ui32Config to +//! the result of a logical OR operation between one of the following values +//! and \e ui32Config: +//! +//! - \b GPTIMER_CFG_A_ONE_SHOT - Half-width one-shot timer +//! - \b GPTIMER_CFG_A_ONE_SHOT_UP - Half-width one-shot timer that counts up +//! instead of down (not available on all parts) +//! - \b GPTIMER_CFG_A_PERIODIC - Half-width periodic timer +//! - \b GPTIMER_CFG_A_PERIODIC_UP - Half-width periodic timer that counts up +//! instead of down (not available on all parts) +//! - \b GPTIMER_CFG_A_CAP_COUNT - Half-width edge count capture +//! - \b GPTIMER_CFG_A_CAP_COUNT_UP - Half-width edge count capture that counts +//! up instead of down (not available on all parts) +//! - \b GPTIMER_CFG_A_CAP_TIME - Half-width edge time capture +//! - \b GPTIMER_CFG_A_CAP_TIME_UP - Half-width edge time capture that +//! counts up instead of down (not available on all parts) +//! - \b GPTIMER_CFG_A_PWM - Half-width PWM output +//! +//! Similarly, the second timer is configured by setting \e ui32Config to +//! the result of a logical OR operation between one of the corresponding +//! \b GPTIMER_CFG_B_* values and \e ui32Config. +//! +//! \return None +// +//***************************************************************************** +void +TimerConfigure(uint32_t ui32Base, uint32_t ui32Config) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Config == GPTIMER_CFG_ONE_SHOT) || + (ui32Config == GPTIMER_CFG_ONE_SHOT_UP) || + (ui32Config == GPTIMER_CFG_PERIODIC) || + (ui32Config == GPTIMER_CFG_PERIODIC_UP) || + ((ui32Config & 0xff000000) == GPTIMER_CFG_SPLIT_PAIR)); + ASSERT(((ui32Config & 0xff000000) != GPTIMER_CFG_SPLIT_PAIR) || + ((((ui32Config & 0x000000ff) == GPTIMER_CFG_A_ONE_SHOT) || + ((ui32Config & 0x000000ff) == GPTIMER_CFG_A_ONE_SHOT_UP) || + ((ui32Config & 0x000000ff) == GPTIMER_CFG_A_PERIODIC) || + ((ui32Config & 0x000000ff) == GPTIMER_CFG_A_PERIODIC_UP) || + ((ui32Config & 0x000000ff) == GPTIMER_CFG_A_CAP_COUNT) || + ((ui32Config & 0x000000ff) == GPTIMER_CFG_A_CAP_TIME) || + ((ui32Config & 0x000000ff) == GPTIMER_CFG_A_PWM)) && + (((ui32Config & 0x0000ff00) == GPTIMER_CFG_B_ONE_SHOT) || + ((ui32Config & 0x0000ff00) == GPTIMER_CFG_B_ONE_SHOT_UP) || + ((ui32Config & 0x0000ff00) == GPTIMER_CFG_B_PERIODIC) || + ((ui32Config & 0x0000ff00) == GPTIMER_CFG_B_PERIODIC_UP) || + ((ui32Config & 0x0000ff00) == GPTIMER_CFG_B_CAP_COUNT) || + ((ui32Config & 0x0000ff00) == GPTIMER_CFG_B_CAP_COUNT_UP) || + ((ui32Config & 0x0000ff00) == GPTIMER_CFG_B_CAP_TIME) || + ((ui32Config & 0x0000ff00) == GPTIMER_CFG_B_CAP_TIME_UP) || + ((ui32Config & 0x0000ff00) == GPTIMER_CFG_B_PWM)))); + + // + // Disable the timers. + // + HWREG(ui32Base + GPTIMER_O_CTL) &= ~(GPTIMER_CTL_TAEN | GPTIMER_CTL_TBEN); + + // + // Set the global timer configuration. + // + HWREG(ui32Base + GPTIMER_O_CFG) = ui32Config >> 24; + + // + // Set the configuration of the A and B timers. Note that the B timer + // configuration is ignored by the hardware in 32-bit modes. + // + HWREG(ui32Base + GPTIMER_O_TAMR) = (ui32Config & 255) | GPTIMER_TAMR_TAPWMIE; + HWREG(ui32Base + GPTIMER_O_TBMR) = + ((ui32Config >> 8) & 255) | GPTIMER_TBMR_TBPWMIE; +} + +//***************************************************************************** +// +//! Controls the output level +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to adjust; must be one of \b GPTIMER_A, +//! \b GPTIMER_B, or \b GPTIMER_BOTH. +//! \param bInvert specifies the output level. +//! +//! This function sets the PWM output level for the specified timer. If the +//! \e bInvert parameter is \b true, then the timer's output is made active +//! low; otherwise, it is made active high. +//! +//! \return None +// +//***************************************************************************** +void +TimerControlLevel(uint32_t ui32Base, uint32_t ui32Timer, + bool bInvert) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Set the output levels as requested. + // + ui32Timer &= GPTIMER_CTL_TAPWML | GPTIMER_CTL_TBPWML; + HWREG(ui32Base + GPTIMER_O_CTL) = (bInvert ? + (HWREG(ui32Base + GPTIMER_O_CTL) | ui32Timer) : + (HWREG(ui32Base + GPTIMER_O_CTL) & ~(ui32Timer))); +} + +//***************************************************************************** +// +//! Enables or disables the trigger output +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer to adjust; must be one of \b GPTIMER_A, +//! \b GPTIMER_B, or \b GPTIMER_BOTH. +//! \param bEnable specifies the desired trigger state. +//! +//! This function controls the trigger output for the specified timer. If the +//! \e bEnable parameter is \b true, then the timer's output trigger is +//! enabled; otherwise it is disabled. +//! +//! \return None +// +//***************************************************************************** +void +TimerControlTrigger(uint32_t ui32Base, uint32_t ui32Timer, + bool bEnable) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Set the trigger output as requested. + // + ui32Timer &= GPTIMER_CTL_TAOTE | GPTIMER_CTL_TBOTE; + HWREG(ui32Base + GPTIMER_O_CTL) = (bEnable ? + (HWREG(ui32Base + GPTIMER_O_CTL) | ui32Timer) : + (HWREG(ui32Base + GPTIMER_O_CTL) & ~(ui32Timer))); +} + +//***************************************************************************** +// +//! Controls the event type +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to be adjusted; must be one of +//! \b GPTIMER_A, \b GPTIMER_B, or \b GPTIMER_BOTH. +//! \param ui32Event specifies the type of event; must be one of +//! \b GPTIMER_EVENT_POS_EDGE, \b GPTIMER_EVENT_NEG_EDGE, or +//! \b GPTIMER_EVENT_BOTH_EDGES. +//! +//! This function sets the signal edge(s) that triggers the timer when in +//! capture mode. +//! +//! \return None +// +//***************************************************************************** +void +TimerControlEvent(uint32_t ui32Base, uint32_t ui32Timer, + uint32_t ui32Event) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Set the event type. + // + ui32Timer &= GPTIMER_CTL_TAEVENT_M | GPTIMER_CTL_TBEVENT_M; + HWREG(ui32Base + GPTIMER_O_CTL) = ((HWREG(ui32Base + GPTIMER_O_CTL) & ~ui32Timer) | + (ui32Event & ui32Timer)); +} + +//***************************************************************************** +// +//! Controls the stall handling +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to be adjusted; must be one of +//! \b GPTIMER_A, \b GPTIMER_B, or \b GPTIMER_BOTH. +//! \param bStall specifies the response to a stall signal. +//! +//! This function controls the stall response for the specified timer. If the +//! \e bStall parameter is \b true, then the timer stops counting if the +//! processor enters debug mode; otherwise the timer keeps running while in +//! debug mode. +//! +//! \return None +// +//***************************************************************************** +void +TimerControlStall(uint32_t ui32Base, uint32_t ui32Timer, + bool bStall) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Set the stall mode. + // + ui32Timer &= GPTIMER_CTL_TASTALL | GPTIMER_CTL_TBSTALL; + HWREG(ui32Base + GPTIMER_O_CTL) = (bStall ? + (HWREG(ui32Base + GPTIMER_O_CTL) | ui32Timer) : + (HWREG(ui32Base + GPTIMER_O_CTL) & ~(ui32Timer))); +} + +//***************************************************************************** +// +//! Controls the wait on trigger handling +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to be adjusted; must be one of +//! \b GPTIMER_A, \b GPTIMER_B, or \b GPTIMER_BOTH. +//! \param bWait specifies if the timer should wait for a trigger input. +//! +//! This function controls whether or not a timer waits for a trigger input to +//! start counting. When enabled, the previous timer in the trigger chain must +//! count to its timeout in order for this timer to start counting. Refer to +//! the part's data sheet for a description of the trigger chain. +//! +//! \note This functionality is not available on all parts. +//! +//! \return None +// +//***************************************************************************** +void +TimerControlWaitOnTrigger(uint32_t ui32Base, uint32_t ui32Timer, + bool bWait) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Set the wait on trigger mode for timer A. + // + if((ui32Timer & GPTIMER_A) != 0) + { + if(bWait) + { + HWREG(ui32Base + GPTIMER_O_TAMR) |= GPTIMER_TAMR_TAWOT; + } + else + { + HWREG(ui32Base + GPTIMER_O_TAMR) &= ~(GPTIMER_TAMR_TAWOT); + } + } + + // + // Set the wait on trigger mode for timer B. + // + if((ui32Timer & GPTIMER_B) != 0) + { + if(bWait) + { + HWREG(ui32Base + GPTIMER_O_TBMR) |= GPTIMER_TBMR_TBWOT; + } + else + { + HWREG(ui32Base + GPTIMER_O_TBMR) &= ~(GPTIMER_TBMR_TBWOT); + } + } +} + +//***************************************************************************** +// +//! Set the timer prescale value +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to adjust; must be one of \b GPTIMER_A, +//! \b GPTIMER_B, or \b GPTIMER_BOTH. +//! \param ui32Value is the timer prescale value; must be between 0 and 255, +//! inclusive. +//! +//! This function sets the value of the input clock prescaler. The prescaler +//! is only operational when in 16-bit mode and is used to extend the range of +//! the 16-bit timer modes. +//! +//! \note The availability of the prescaler varies with the timer mode in use. +//! Please consult the datasheet for the part you are using +//! to determine whether this support is available. +//! +//! \return None +// +//***************************************************************************** +void +TimerPrescaleSet(uint32_t ui32Base, uint32_t ui32Timer, + uint32_t ui32Value) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + ASSERT(ui32Value < 256); + + // + // Set the timer A prescaler if requested. + // + if(ui32Timer & GPTIMER_A) + { + HWREG(ui32Base + GPTIMER_O_TAPR) = ui32Value; + } + + // + // Set the timer B prescaler if requested. + // + if(ui32Timer & GPTIMER_B) + { + HWREG(ui32Base + GPTIMER_O_TBPR) = ui32Value; + } +} + +//***************************************************************************** +// +//! Get the timer prescale value +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer; must be one of \b GPTIMER_A or +//! \b GPTIMER_B. +//! +//! This function gets the value of the input clock prescaler. The prescaler +//! is only operational when in 16-bit mode and is used to extend the range of +//! the 16-bit timer modes. +//! +//! \note The availability of the prescaler varies with the timer mode in use. +//! Please consult the datasheet for the part you are using +//! to determine whether this support is available. +//! +//! \return The value of the timer prescaler +// +//***************************************************************************** +uint32_t +TimerPrescaleGet(uint32_t ui32Base, uint32_t ui32Timer) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Return the appropriate prescale value. + // + return((ui32Timer == GPTIMER_A) ? HWREG(ui32Base + GPTIMER_O_TAPR) : + HWREG(ui32Base + GPTIMER_O_TBPR)); +} + +//***************************************************************************** +// +//! Set the timer prescale match value +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to adjust; must be one of +//! \b GPTIMER_A, \b GPTIMER_B, or \b GPTIMER_BOTH. +//! \param ui32Value is the timer prescale match value; must be between 0 and +//! 255, inclusive. +//! +//! This function sets the value of the input clock prescaler match value. +//! When in a 16-bit mode that uses the counter match and the prescaler, the +//! prescale match effectively extends the range of the counter to 24-bits. +//! +//! \note The availability of the prescaler match varies with the timer mode +//! in use. Please consult the datasheet for the part you are using to +//! determine whether this support is available. +//! +//! \return None +// +//***************************************************************************** +void +TimerPrescaleMatchSet(uint32_t ui32Base, uint32_t ui32Timer, + uint32_t ui32Value) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + ASSERT(ui32Value < 256); + + // + // Set the timer A prescale match if requested. + // + if(ui32Timer & GPTIMER_A) + { + HWREG(ui32Base + GPTIMER_O_TAPMR) = ui32Value; + } + + // + // Set the timer B prescale match if requested. + // + if(ui32Timer & GPTIMER_B) + { + HWREG(ui32Base + GPTIMER_O_TBPMR) = ui32Value; + } +} + +//***************************************************************************** +// +//! Get the timer prescale match value +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer; must be one of \b GPTIMER_A or +//! \b GPTIMER_B. +//! +//! This function gets the value of the input clock prescaler match value. +//! When in a 16-bit mode that uses the counter match and prescaler, the +//! prescale match effectively extends the range of the counter to 24-bits. +//! +//! \note The availability of the prescaler match varies with the timer mode +//! in use. Please consult the datasheet for the part you are using to +//! determine whether this support is available. +//! +//! \return The value of the timer prescale match. +// +//***************************************************************************** +uint32_t +TimerPrescaleMatchGet(uint32_t ui32Base, uint32_t ui32Timer) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Return the appropriate prescale match value. + // + return((ui32Timer == GPTIMER_A) ? HWREG(ui32Base + GPTIMER_O_TAPMR) : + HWREG(ui32Base + GPTIMER_O_TBPMR)); +} + +//***************************************************************************** +// +//! Sets the timer load value +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to adjust; must be one of: +//! \b GPTIMER_A, \b GPTIMER_B, or \b GPTIMER_BOTH. Only \b GPTIMER_A should +//! be used when the timer is configured for 32-bit operation. +//! \param ui32Value is the load value. +//! +//! This function sets the timer load value; if the timer is running then the +//! value will be immediately loaded into the timer. +//! +//! \return None +// +//***************************************************************************** +void +TimerLoadSet(uint32_t ui32Base, uint32_t ui32Timer, + uint32_t ui32Value) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Set the timer A load value if requested. + // + if(ui32Timer & GPTIMER_A) + { + HWREG(ui32Base + GPTIMER_O_TAILR) = ui32Value; + } + + // + // Set the timer B load value if requested. + // + if(ui32Timer & GPTIMER_B) + { + HWREG(ui32Base + GPTIMER_O_TBILR) = ui32Value; + } +} + +//***************************************************************************** +// +//! Gets the timer load value +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer; must be one of \b GPTIMER_A or +//! \b GPTIMER_B. Only \b GPTIMER_A should be used when the timer is +//! configured for 32-bit operation. +//! +//! This function gets the currently programmed interval load value for the +//! specified timer. +//! +//! \return Returns the load value for the timer. +// +//***************************************************************************** +uint32_t +TimerLoadGet(uint32_t ui32Base, uint32_t ui32Timer) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B)); + + // + // Return the appropriate load value. + // + return((ui32Timer == GPTIMER_A) ? HWREG(ui32Base + GPTIMER_O_TAILR) : + HWREG(ui32Base + GPTIMER_O_TBILR)); +} + + + +//***************************************************************************** +// +//! Gets the current timer value +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer; must be one of \b GPTIMER_A or +//! \b GPTIMER_B. Only \b GPTIMER_A should be used when the timer is +//! configured for 32-bit operation. +//! +//! This function reads the current value of the specified timer. +//! +//! \return Returns the current value of the timer. +// +//***************************************************************************** +uint32_t +TimerValueGet(uint32_t ui32Base, uint32_t ui32Timer) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B)); + + // + // Return the appropriate timer value. + // + return((ui32Timer == GPTIMER_A) ? HWREG(ui32Base + GPTIMER_O_TAR) : + HWREG(ui32Base + GPTIMER_O_TBR)); +} + +//***************************************************************************** +// +//! Sets the timer match value +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s) to adjust; must be one of +//! \b GPTIMER_A, \b GPTIMER_B, or \b GPTIMER_BOTH. Only \b GPTIMER_A should +//! be used when the timer is configured for 32-bit operation. +//! \param ui32Value is the match value. +//! +//! This function sets the match value for a timer. This is used in capture +//! count mode to determine when to interrupt the processor and in PWM mode to +//! determine the duty cycle of the output signal. +//! +//! \return None +// +//***************************************************************************** +void +TimerMatchSet(uint32_t ui32Base, uint32_t ui32Timer, + uint32_t ui32Value) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Set the timer A match value if requested. + // + if(ui32Timer & GPTIMER_A) + { + HWREG(ui32Base + GPTIMER_O_TAMATCHR) = ui32Value; + } + + // + // Set the timer B match value if requested. + // + if(ui32Timer & GPTIMER_B) + { + HWREG(ui32Base + GPTIMER_O_TBMATCHR) = ui32Value; + } +} + +//***************************************************************************** +// +//! Gets the timer match value +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer; must be one of \b GPTIMER_A or +//! \b GPTIMER_B. Only \b GPTIMER_A should be used when the timer is +//! configured for 32-bit operation. +//! +//! This function gets the match value for the specified timer. +//! +//! \return Returns the match value for the timer. +// +//***************************************************************************** +uint32_t +TimerMatchGet(uint32_t ui32Base, uint32_t ui32Timer) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B)); + + // + // Return the appropriate match value. + // + return((ui32Timer == GPTIMER_A) ? HWREG(ui32Base + GPTIMER_O_TAMATCHR) : + HWREG(ui32Base + GPTIMER_O_TBMATCHR)); +} + +//***************************************************************************** +// +//! Registers an interrupt handler for the timer interrupt +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s); must be one of \b GPTIMER_A, +//! \b GPTIMER_B, or \b GPTIMER_BOTH. +//! \param pfnHandler is a pointer to the function to be called when the timer +//! interrupt occurs. +//! +//! This function sets the handler to be called when a timer interrupt occurs. +//! In addition, this function enables the global interrupt in the interrupt +//! controller; specific timer interrupts must be enabled via TimerIntEnable(). +//! It is the interrupt handler's responsibility to clear the interrupt source +//! via TimerIntClear(). +//! +//! \sa See IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +TimerIntRegister(uint32_t ui32Base, uint32_t ui32Timer, + void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Get the interrupt number for this timer module. + // + ui32Base = ((ui32Base == GPTIMER0_BASE) ? INT_TIMER0A : + ((ui32Base == GPTIMER1_BASE) ? INT_TIMER1A : + ((ui32Base == GPTIMER2_BASE) ? INT_TIMER2A : INT_TIMER3A))); + + // + // Register an interrupt handler for timer A if requested. + // + if(ui32Timer & GPTIMER_A) + { + // + // Register the interrupt handler. + // + IntRegister(ui32Base, pfnHandler); + + // + // Enable the interrupt. + // + IntEnable(ui32Base); + } + + // + // Register an interrupt handler for timer B if requested. + // + if(ui32Timer & GPTIMER_B) + { + // + // Register the interrupt handler. + // + IntRegister(ui32Base + 1, pfnHandler); + + // + // Enable the interrupt. + // + IntEnable(ui32Base + 1); + } +} + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the timer interrupt +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32Timer specifies the timer(s); must be one of \b GPTIMER_A, +//! \b GPTIMER_B, or \b GPTIMER_BOTH. +//! +//! This function clears the handler to be called when a timer interrupt +//! occurs. This function also masks off the interrupt in the interrupt +//! controller so that the interrupt handler no longer is called. +//! +//! \sa See IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +TimerIntUnregister(uint32_t ui32Base, uint32_t ui32Timer) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + ASSERT((ui32Timer == GPTIMER_A) || (ui32Timer == GPTIMER_B) || + (ui32Timer == GPTIMER_BOTH)); + + // + // Get the interrupt number for this timer module. + // + ui32Base = ((ui32Base == GPTIMER0_BASE) ? INT_TIMER0A : + ((ui32Base == GPTIMER1_BASE) ? INT_TIMER1A : + ((ui32Base == GPTIMER2_BASE) ? INT_TIMER2A : INT_TIMER3A))); + + // + // Unregister the interrupt handler for timer A if requested. + // + if(ui32Timer & GPTIMER_A) + { + // + // Disable the interrupt. + // + IntDisable(ui32Base); + + // + // Unregister the interrupt handler. + // + IntUnregister(ui32Base); + } + + // + // Unregister the interrupt handler for timer B if requested. + // + if(ui32Timer & GPTIMER_B) + { + // + // Disable the interrupt. + // + IntDisable(ui32Base + 1); + + // + // Unregister the interrupt handler. + // + IntUnregister(ui32Base + 1); + } +} + +//***************************************************************************** +// +//! Enables individual timer interrupt sources +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32IntFlags is the bit mask of the interrupt sources to be enabled. +//! +//! Enables the indicated timer interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. +//! +//! The \e ui32IntFlags parameter must be the logical OR of any combination of +//! the following: +//! +//! - \b GPTIMER_CAPB_EVENT - Capture B event interrupt +//! - \b GPTIMER_CAPB_MATCH - Capture B match interrupt +//! - \b GPTIMER_TIMB_TIMEOUT - Timer B timeout interrupt +//! - \b GPTIMER_CAPA_EVENT - Capture A event interrupt +//! - \b GPTIMER_CAPA_MATCH - Capture A match interrupt +//! - \b GPTIMER_TIMA_TIMEOUT - Timer A timeout interrupt +//! +//! \return None +// +//***************************************************************************** +void +TimerIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + + // + // Enable the specified interrupts. + // + HWREG(ui32Base + GPTIMER_O_IMR) |= ui32IntFlags; +} + +//***************************************************************************** +// +//! Disables individual timer interrupt sources +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32IntFlags is the bit mask of the interrupt sources to be disabled. +//! +//! Disables the indicated timer interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. +//! +//! The \e ui32IntFlags parameter has the same definition as the \e ui32IntFlags +//! parameter to TimerIntEnable(). +//! +//! \return None +// +//***************************************************************************** +void +TimerIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + + // + // Disable the specified interrupts. + // + HWREG(ui32Base + GPTIMER_O_IMR) &= ~(ui32IntFlags); +} + +//***************************************************************************** +// +//! Gets the current interrupt status +//! +//! \param ui32Base is the base address of the timer module. +//! \param bMasked is false if the raw interrupt status is required and true if +//! the masked interrupt status is required. +//! +//! This function returns the interrupt status for the timer module. Either +//! the raw interrupt status or the status of interrupts that are allowed to +//! reflect to the processor can be returned. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! values described in TimerIntEnable(). +// +//***************************************************************************** +uint32_t +TimerIntStatus(uint32_t ui32Base, bool bMasked) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + return(bMasked ? HWREG(ui32Base + GPTIMER_O_MIS) : + HWREG(ui32Base + GPTIMER_O_RIS)); +} + +//***************************************************************************** +// +//! Clears timer interrupt sources +//! +//! \param ui32Base is the base address of the timer module. +//! \param ui32IntFlags is a bit mask of the interrupt sources to be cleared. +//! +//! The specified timer interrupt sources are cleared, so that they no longer +//! assert. This function must be called in the interrupt handler to keep the +//! interrupt from being triggered again immediately upon exit. +//! +//! The \e ui32IntFlags parameter has the same definition as the \e ui32IntFlags +//! parameter to TimerIntEnable(). +//! +//! \note Because there is a write buffer in the Cortex-M3 processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \return None +// +//***************************************************************************** +void +TimerIntClear(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ui32Base)); + + // + // Clear the requested interrupt sources. + // + HWREG(ui32Base + GPTIMER_O_ICR) = ui32IntFlags; +} + +//***************************************************************************** +// +//! Synchronizes the counters in a set of timers +//! +//! \param ui32Base is the base address of the timer module. This must be the +//! base address of Timer0 (in other words, \b GPTIMER0_BASE). +//! \param ui32Timers is the set of timers to synchronize. +//! +//! This function will synchronize the counters in a specified set of timers. +//! When a timer is running in half-width mode, each half can be included or +//! excluded in the synchronization event. When a timer is running in +//! full-width mode, only the A timer can be synchronized (specifying the B +//! timer has no effect). +//! +//! The \e ui32Timers parameter is the logical OR of any of the following +//! defines: +//! +//! - \b GPTIMER_0A_SYNC +//! - \b GPTIMER_0B_SYNC +//! - \b GPTIMER_1A_SYNC +//! - \b GPTIMER_1B_SYNC +//! - \b GPTIMER_2A_SYNC +//! - \b GPTIMER_2B_SYNC +//! - \b GPTIMER_3A_SYNC +//! - \b GPTIMER_3B_SYNC +//! +//! \note This functionality is not available on all parts. +//! +//! \return None +// +//***************************************************************************** +void +TimerSynchronize(uint32_t ui32Base, uint32_t ui32Timers) +{ + // + // Check the arguments. + // + ASSERT(ui32Base == GPTIMER0_BASE); + + // + // Synchronize the specified timers. + // + HWREG(ui32Base + GPTIMER_O_SYNC) = ui32Timers; +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/gptimer.h b/bsp/boards/mimsy2-cc2538/source/gptimer.h new file mode 100644 index 0000000000..0065ebfa24 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/gptimer.h @@ -0,0 +1,193 @@ +/****************************************************************************** +* Filename: gptimer.h +* Revised: $Date: 2013-02-19 10:35:37 +0100 (Tue, 19 Feb 2013) $ +* Revision: $Revision: 9322 $ +* +* Description: Prototypes for the general purpose timer module +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __GPTIMER_H__ +#define __GPTIMER_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// Values that can be passed to TimerConfigure as the ui32Config parameter. +// +//***************************************************************************** +#define GPTIMER_CFG_ONE_SHOT 0x00000021 // Full-width one-shot timer +#define GPTIMER_CFG_ONE_SHOT_UP 0x00000031 // Full-width one-shot up-count + // timer +#define GPTIMER_CFG_PERIODIC 0x00000022 // Full-width periodic timer +#define GPTIMER_CFG_PERIODIC_UP 0x00000032 // Full-width periodic up-count + // timer +#define GPTIMER_CFG_SPLIT_PAIR 0x04000000 // Two half-width timers +#define GPTIMER_CFG_A_ONE_SHOT 0x00000021 // Timer A one-shot timer +#define GPTIMER_CFG_A_ONE_SHOT_UP 0x00000031 // Timer A one-shot up-count timer +#define GPTIMER_CFG_A_PERIODIC 0x00000022 // Timer A periodic timer +#define GPTIMER_CFG_A_PERIODIC_UP 0x00000032 // Timer A periodic up-count timer +#define GPTIMER_CFG_A_CAP_COUNT 0x00000003 // Timer A event counter +#define GPTIMER_CFG_A_CAP_COUNT_UP 0x00000013 // Timer A event up-counter +#define GPTIMER_CFG_A_CAP_TIME 0x00000007 // Timer A event timer +#define GPTIMER_CFG_A_CAP_TIME_UP 0x00000017 // Timer A event up-count timer +#define GPTIMER_CFG_A_PWM 0x0000000A // Timer A PWM output +#define GPTIMER_CFG_B_ONE_SHOT 0x00002100 // Timer B one-shot timer +#define GPTIMER_CFG_B_ONE_SHOT_UP 0x00003100 // Timer B one-shot up-count timer +#define GPTIMER_CFG_B_PERIODIC 0x00002200 // Timer B periodic timer +#define GPTIMER_CFG_B_PERIODIC_UP 0x00003200 // Timer B periodic up-count timer +#define GPTIMER_CFG_B_CAP_COUNT 0x00000300 // Timer B event counter +#define GPTIMER_CFG_B_CAP_COUNT_UP 0x00001300 // Timer B event up-counter +#define GPTIMER_CFG_B_CAP_TIME 0x00000700 // Timer B event timer +#define GPTIMER_CFG_B_CAP_TIME_UP 0x00001700 // Timer B event up-count timer +#define GPTIMER_CFG_B_PWM 0x00000A00 // Timer B PWM output + +//***************************************************************************** +// +// Values that can be passed to TimerIntEnable, TimerIntDisable, and +// TimerIntClear as the ui32IntFlags parameter, and returned from TimerIntStatus. +// +//***************************************************************************** +#define GPTIMER_TIMB_MATCH 0x00000800 // TimerB match interrupt +#define GPTIMER_CAPB_EVENT 0x00000400 // CaptureB event interrupt +#define GPTIMER_CAPB_MATCH 0x00000200 // CaptureB match interrupt +#define GPTIMER_TIMB_TIMEOUT 0x00000100 // TimerB time out interrupt +#define GPTIMER_TIMA_MATCH 0x00000010 // TimerA match interrupt +#define GPTIMER_RTC_MATCH 0x00000008 // RTC interrupt mask +#define GPTIMER_CAPA_EVENT 0x00000004 // CaptureA event interrupt +#define GPTIMER_CAPA_MATCH 0x00000002 // CaptureA match interrupt +#define GPTIMER_TIMA_TIMEOUT 0x00000001 // TimerA time out interrupt + +//***************************************************************************** +// +// Values that can be passed to TimerControlEvent as the ui32Event parameter. +// +//***************************************************************************** +#define GPTIMER_EVENT_POS_EDGE 0x00000000 // Count positive edges +#define GPTIMER_EVENT_NEG_EDGE 0x00000404 // Count negative edges +#define GPTIMER_EVENT_BOTH_EDGES 0x00000C0C // Count both edges + +//***************************************************************************** +// +// Values that can be passed to most of the timer APIs as the ui32Timer +// parameter. +// +//***************************************************************************** +#define GPTIMER_A 0x000000ff // Timer A +#define GPTIMER_B 0x0000ff00 // Timer B +#define GPTIMER_BOTH 0x0000ffff // Timer Both + +//***************************************************************************** +// +// Values that can be passed to TimerSynchronize as the ui32Timers parameter. +// +//***************************************************************************** +#define GPTIMER_0A_SYNC 0x00000001 // Synchronize Timer 0A +#define GPTIMER_0B_SYNC 0x00000002 // Synchronize Timer 0B +#define GPTIMER_1A_SYNC 0x00000004 // Synchronize Timer 1A +#define GPTIMER_1B_SYNC 0x00000008 // Synchronize Timer 1B +#define GPTIMER_2A_SYNC 0x00000010 // Synchronize Timer 2A +#define GPTIMER_2B_SYNC 0x00000020 // Synchronize Timer 2B +#define GPTIMER_3A_SYNC 0x00000040 // Synchronize Timer 3A +#define GPTIMER_3B_SYNC 0x00000080 // Synchronize Timer 3B + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void TimerEnable(uint32_t ui32Base, uint32_t ui32Timer); +extern void TimerDisable(uint32_t ui32Base, uint32_t ui32Timer); +extern void TimerConfigure(uint32_t ui32Base, uint32_t ui32Config); +extern void TimerControlLevel(uint32_t ui32Base, uint32_t ui32Timer, + bool bInvert); +extern void TimerControlTrigger(uint32_t ui32Base, uint32_t ui32Timer, +bool bEnable); +extern void TimerControlEvent(uint32_t ui32Base, uint32_t ui32Timer, + uint32_t ui32Event); +extern void TimerControlStall(uint32_t ui32Base, uint32_t ui32Timer, + bool bStall); +extern void TimerControlWaitOnTrigger(uint32_t ui32Base, + uint32_t ui32Timer, + bool bWait); +extern void TimerPrescaleSet(uint32_t ui32Base, uint32_t ui32Timer, + uint32_t ui32Value); +extern uint32_t TimerPrescaleGet(uint32_t ui32Base, + uint32_t ui32Timer); +extern void TimerPrescaleMatchSet(uint32_t ui32Base, + uint32_t ui32Timer, + uint32_t ui32Value); +extern uint32_t TimerPrescaleMatchGet(uint32_t ui32Base, + uint32_t ui32Timer); +extern void TimerLoadSet(uint32_t ui32Base, uint32_t ui32Timer, + uint32_t ui32Value); +extern uint32_t TimerLoadGet(uint32_t ui32Base, + uint32_t ui32Timer); +extern uint32_t TimerValueGet(uint32_t ui32Base, + uint32_t ui32Timer); +extern void TimerMatchSet(uint32_t ui32Base, uint32_t ui32Timer, + uint32_t ui32Value); +extern uint32_t TimerMatchGet(uint32_t ui32Base, + uint32_t ui32Timer); +extern void TimerIntRegister(uint32_t ui32Base, uint32_t ui32Timer, + void (*pfnHandler)(void)); +extern void TimerIntUnregister(uint32_t ui32Base, uint32_t ui32Timer); +extern void TimerIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags); +extern void TimerIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags); +extern uint32_t TimerIntStatus(uint32_t ui32Base, bool bMasked); +extern void TimerIntClear(uint32_t ui32Base, uint32_t ui32IntFlags); +extern void TimerSynchronize(uint32_t ui32Base, uint32_t ui32Timers); + + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __GPTIMER_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/i2c_lib.c b/bsp/boards/mimsy2-cc2538/source/i2c_lib.c new file mode 100644 index 0000000000..d70e63f04e --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/i2c_lib.c @@ -0,0 +1,899 @@ +/****************************************************************************** +* Filename: i2c.c +* Revised: $Date: 2013-03-20 14:47:53 +0100 (Wed, 20 Mar 2013) $ +* Revision: $Revision: 9489 $ +* +* Description: Driver for Inter-IC (I2C) bus block. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup i2c_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include +#include +#include "debug.h" +#include "i2c_lib.h" +#include "interrupt.h" + +//***************************************************************************** +// +//! Initializes the I2C master block +//! +//! \param ui32I2CClk is the rate of the clock supplied to the I2C module. +//! \param bFast set up for fast data transfers +//! +//! This function initializes operation of the I2C master block. Upon +//! successful initialization of the I2C block, this functionhas set the +//! bus speed for the master, and has enabled the I2C master block. +//! +//! If the parameter \e bFast is \b true, then the master block will be set up +//! to transfer data at 400 kbps; otherwise, it will be set up to transfer data +//! at 100 kbps. +//! +//! The peripheral clock will be the same as the processor clock. This will be +//! the value returned by SysCtrlClockGet(), or it can be explicitly hardcoded +//! if it is constant and known (to save the code/execution overhead of a call +//! to SysCtrlClockGet()). +//! +//! \return None +// +//***************************************************************************** +void +I2CMasterInitExpClk(uint32_t ui32I2CClk, bool bFast) +{ + uint32_t ui32SCLFreq; + uint32_t ui32TPR; + + // + // Must enable the device before doing anything else. + // + I2CMasterEnable(); + + // + // Get the desired SCL speed. + // + if(bFast == true) + { + ui32SCLFreq = 400000; + } + else + { + ui32SCLFreq = 100000; + } + + // + // Compute the clock divider that achieves the fastest speed less than or + // equal to the desired speed. The numerator is biased to favor a larger + // clock divider so that the resulting clock is always less than or equal + // to the desired clock, never greater. + // + ui32TPR = ((ui32I2CClk + (2 * 10 * ui32SCLFreq) - 1) / (2 * 10 * ui32SCLFreq)) - 1; + HWREG(I2CM_TPR) = ui32TPR; +} + +//***************************************************************************** +// +//! Initializes the I2C slave block +//! +//! \param ui8SlaveAddr 7-bit slave address +//! +//! This function initializes operation of the I2C slave block. Upon +//! successful initialization of the I2C blocks, this function has set +//! the slave address has enabled the I2C slave block. +//! +//! The parameter \e ui8SlaveAddr is the value that will be compared against the +//! slave address sent by an I2C master. +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveInit(uint8_t ui8SlaveAddr) +{ + // + // Check the arguments. + // + ASSERT(!(ui8SlaveAddr & 0x80)); + + // + // Must enable the device before doing anything else. + // + I2CSlaveEnable(); + + // + // Set up the slave address. + // + HWREG(I2CS_OAR) = ui8SlaveAddr; +} + +//***************************************************************************** +// +//! Enables the I2C Master block +//! +//! This function will enable operation of the I2C Master block. +//! +//! \return None +// +//***************************************************************************** +void +I2CMasterEnable(void) +{ + // + // Enable the master block. + // + HWREG(I2CM_CR) |= I2CM_CR_MFE; +} + +//***************************************************************************** +// +//! Enables the I2C slave block +//! +//! This function enables operation of the I2C slave block. +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveEnable(void) +{ + // + // Enable the clock to the slave block. + // + HWREG(I2CM_CR) |= I2CM_CR_SFE; + + // + // Enable the slave. + // + HWREG(I2CS_CTRL) = I2CS_CTRL_DA; +} + +//***************************************************************************** +// +//! Disables the I2C master block +//! +//! This function disables operation of the I2C master block. +//! +//! \return None +// +//***************************************************************************** +void +I2CMasterDisable(void) +{ + // + // Disable the master block. + // + HWREG(I2CM_CR) &= ~(I2CM_CR_MFE); +} + +//***************************************************************************** +// +//! Disables the I2C slave block +//! +//! This function disables operation of the I2C slave block. +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveDisable(void) +{ + // + // Disable the slave. + // + HWREG(I2CS_CTRL) = 0; + + // + // Disable the clock to the slave block. + // + HWREG(I2CM_CR) &= ~(I2CM_CR_SFE); +} + +//***************************************************************************** +// +//! Registers an interrupt handler for the I2C module +//! +//! \param pfnHandler is a pointer to the function to be called when the +//! I2C interrupt occurs. +//! +//! This function sets the handler to be called when an I2C interrupt occurs. +//! This function enables the global interrupt in the interrupt controller; +//! specific I2C interrupts must be enabled through I2CMasterIntEnable() and +//! I2CSlaveIntEnable(). If necessary, the interrupt handler must clear +//! the interrupt source through I2CMasterIntClear() and I2CSlaveIntClear(). +//! +//! \sa See IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +I2CIntRegister(void (*pfnHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(INT_I2C0, pfnHandler); + + // + // Enable the I2C interrupt. + // + IntEnable(INT_I2C0); +} + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the I2C module +//! +//! This function clears the handler to be called when an I2C interrupt +//! occurs. The function also masks off the interrupt in the interrupt +//! controller so that the interrupt handler no longer is called. +//! +//! \sa See IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +I2CIntUnregister(void) +{ + // + // Disable the interrupt. + // + IntDisable(INT_I2C0); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_I2C0); +} + +//***************************************************************************** +// +//! Enables the I2C Master interrupt +//! +//! This function enables the I2C Master interrupt source. +//! +//! \return None +// +//***************************************************************************** +void +I2CMasterIntEnable(void) +{ + // + // Enable the master interrupt. + // + HWREG(I2CM_IMR) = I2CM_IMR_IM; +} + +//***************************************************************************** +// +//! Enables the I2C Slave interrupt +//! +//! This function enables the I2C Slave interrupt source. +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveIntEnable(void) +{ + // + // Enable the slave interrupt. + // + HWREG(I2CS_IMR) |= I2C_SLAVE_INT_DATA; +} + +//***************************************************************************** +// +//! Enables individual I2C slave interrupt sources +//! +//! \param ui32IntFlags is the bit mask of the interrupt sources to be enabled. +//! +//! This function enables the indicated I2C slave interrupt sources. Only the +//! sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! The \e ui32IntFlags parameter is the logical OR of any of the following: +//! +//! - \b I2C_SLAVE_INT_STOP Stop condition detected interrupt +//! - \b I2C_SLAVE_INT_START Start condition detected interrupt +//! - \b I2C_SLAVE_INT_DATA Data interrupt +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveIntEnableEx(uint32_t ui32IntFlags) +{ + // + // Enable the slave interrupt. + // + HWREG(I2CS_IMR) |= ui32IntFlags; +} + +//***************************************************************************** +// +//! Disables the I2C master interrupt +//! +//! This function disables the I2C master interrupt source. +//! +//! \return None +// +//***************************************************************************** +void +I2CMasterIntDisable(void) +{ + // + // Disable the master interrupt. + // + HWREG(I2CM_IMR) = 0; +} + +//***************************************************************************** +// +//! Disables the I2C Slave interrupt +//! +//! This function disables the I2C Slave interrupt source +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveIntDisable(void) +{ + // + // Disable the slave interrupt. + // + HWREG(I2CS_IMR) &= ~I2C_SLAVE_INT_DATA; +} + +//***************************************************************************** +// +//! Disables individual I2C slave interrupt sources +//! +//! \param ui32IntFlags is the bit mask of the interrupt sources to be disabled. +//! +//! This function disables the indicated I2C slave interrupt sources. +//! Only the sources that are enabled can be reflected to the processor +//! interrupt; disabled sources have no effect on the processor. +//! +//! The \e ui32IntFlags parameter has the same definition as the \e ui32IntFlags +//! parameter to I2CSlaveIntEnableEx(). +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveIntDisableEx(uint32_t ui32IntFlags) +{ + // + // Disable the slave interrupt. + // + HWREG(I2CS_IMR) &= ~ui32IntFlags; +} + +//***************************************************************************** +// +//! Gets the current I2C master interrupt status +//! +//! \param bMasked is false if the raw interrupt status is requested and +//! true if the masked interrupt status is requested. +//! +//! This function returns the interrupt status for the I2C master module. +//! Either the raw interrupt status or the status of interrupts that are allowed +//! to reflect to the processor can be returned. +//! +//! \return Returns the current interrupt status, returned as \b true if active +//! or \b false if not active. +// +//***************************************************************************** +bool +I2CMasterIntStatus(bool bMasked) +{ + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return((HWREG(I2CM_MIS)) ? true : false); + } + else + { + return((HWREG(I2CM_RIS)) ? true : false); + } +} + +//***************************************************************************** +// +//! Gets the current I2C slave interrupt status +//! +//! \param bMasked is false if the raw interrupt status is requested and +//! true if the masked interrupt status is requested. +//! +//! This function returns the interrupt status for the I2C slave module. +//! Either the raw interrupt status or the status of interrupts that are +//! allowed to reflect to the processor can be returned. +//! +//! \return Returns the current interrupt status, returned as \b true if active +//! or \b false if not active. +// +//***************************************************************************** +bool +I2CSlaveIntStatus(bool bMasked) +{ + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return((HWREG(I2CS_MIS)) ? true : false); + } + else + { + return((HWREG(I2CS_RIS)) ? true : false); + } +} + +//***************************************************************************** +// +//! Gets the current I2C slave interrupt status +//! +//! \param bMasked is false if the raw interrupt status is requested and +//! true if the masked interrupt status is requested. +//! +//! This function returns the interrupt status for the I2C slave module. Either +//! the raw interrupt status or the status of interrupts that are allowed to +//! reflect to the processor can be returned. +//! +//! \return Returns the current interrupt status, enumerated as a bit field of +//! values described in I2CSlaveIntEnableEx(). +// +//***************************************************************************** +uint32_t +I2CSlaveIntStatusEx(bool bMasked) +{ + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(I2CS_MIS)); + } + else + { + return(HWREG(I2CS_RIS)); + } +} + +//***************************************************************************** +// +//! Clears I2C master interrupt sources +//! +//! This function clears the I2C master interrupt source, so that it no longer +//! asserts. This must be done in the interrupt handler to keep it from being +//! called again immediately upon exit. +//! +//! \note Because there is a write buffer in the Cortex-M3 processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \return None +// +//***************************************************************************** +void +I2CMasterIntClear(void) +{ + // + // Clear the I2C master interrupt source. + // + HWREG(I2CM_ICR) = I2CM_ICR_IC; + + // This might not be needed. It was used on previous revisions of the IP + HWREG(I2CM_MIS) = I2CM_ICR_IC; +} + +//***************************************************************************** +// +//! Clears I2C slave interrupt sources +//! +//! This function clears the I2C slave interrupt source, so that it no longer +//! asserts. This must be done in the interrupt handler to keep it from being +//! recalled immediately upon exit. +//! +//! \note Because there is a write buffer in the Cortex-M3 processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveIntClear(void) +{ + // + // Clear the I2C slave interrupt source. + // + HWREG(I2CS_ICR) = I2CS_ICR_DATAIC; +} + +//***************************************************************************** +// +//! Clears the I2C slave interrupt sources +//! +//! \param ui32IntFlags is a bit mask of the interrupt sources to be cleared. +//! +//! This function clears the specified I2C Slave interrupt sources, so that they +//! no longer assert. This must be done in the interrupt handler to keep it from +//! being called again immediately upon exit. +//! +//! The \e ui32IntFlags parameter has the same definition as the \e ui32IntFlags +//! parameter to I2CSlaveIntEnableEx(). +//! +//! \note Because there is a write buffer in the Cortex-M3 processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveIntClearEx(uint32_t ui32IntFlags) +{ + // + // Clear the I2C slave interrupt source. + // + HWREG(I2CS_ICR) = ui32IntFlags; +} + +//***************************************************************************** +// +//! Sets the address that the I2C master places on the bus +//! +//! \param ui8SlaveAddr 7-bit slave address +//! \param bReceive flag indicating the type of communication with the slave +//! +//! This function sets the address that the I2C master places on the bus +//! when initiating a transaction. When the \e bReceive parameter is set +//! to \b true, the address indicates that the I2C master is initiating a +//! read from the slave; otherwise, the address indicates that the I2C +//! master is initiating a write to the slave. +//! +//! \return None +// +//***************************************************************************** +void +I2CMasterSlaveAddrSet(uint8_t ui8SlaveAddr, bool bReceive) +{ + // + // Check the arguments. + // + ASSERT(!(ui8SlaveAddr & 0x80)); + + // + // Set the address of the slave with which the master will communicate. + // + HWREG(I2CM_SA) = (ui8SlaveAddr << 1) | bReceive; +} + +//***************************************************************************** +// +//! Indicates whether or not the I2C master is busy +//! +//! This function returns an indication of whether or not the I2C master is +//! busy transmitting or receiving data. +//! +//! \return Returns \b true if the I2C master is busy; otherwise, returns +//! \b false +// +//***************************************************************************** +bool +I2CMasterBusy(void) +{ + // + // Return the busy status. + // + if(HWREG(I2CM_STAT) & I2CM_STAT_BUSY) + { + return(true); + } + else + { + return(false); + } +} + +//***************************************************************************** +// +//! Indicates whether or not the I2C bus is busy +//! +//! This function returns an indication of whether or not the I2C bus is busy. +//! This function can be used in a multimaster environment to determine if +//! another master is currently using the bus. +//! +//! \return Returns \b true if the I2C bus is busy; otherwise, returns +//! \b false +// +//***************************************************************************** +bool +I2CMasterBusBusy(void) +{ + // + // Return the bus busy status. + // + if(HWREG(I2CM_STAT) & I2CM_STAT_BUSBSY) + { + return(true); + } + else + { + return(false); + } +} + +//***************************************************************************** +// +//! Controls the state of the I2C master module +//! +//! \param ui32Cmd command to be issued to the I2C master module +//! +//! This function is used to control the state of the master module send and +//! receive operations. The \e ui32Cmd parameter can be one of the following +//! values: +//! +//! - \b I2C_MASTER_CMD_SINGLE_SEND +//! - \b I2C_MASTER_CMD_SINGLE_RECEIVE +//! - \b I2C_MASTER_CMD_BURST_SEND_START +//! - \b I2C_MASTER_CMD_BURST_SEND_CONT +//! - \b I2C_MASTER_CMD_BURST_SEND_FINISH +//! - \b I2C_MASTER_CMD_BURST_SEND_ERROR_STOP +//! - \b I2C_MASTER_CMD_BURST_RECEIVE_START +//! - \b I2C_MASTER_CMD_BURST_RECEIVE_CONT +//! - \b I2C_MASTER_CMD_BURST_RECEIVE_FINISH +//! - \b I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP +//! +//! \return None +// +//***************************************************************************** +void +I2CMasterControl(uint32_t ui32Cmd) +{ + // + // Check the arguments. + // + ASSERT((ui32Cmd == I2C_MASTER_CMD_SINGLE_SEND) || + (ui32Cmd == I2C_MASTER_CMD_SINGLE_RECEIVE) || + (ui32Cmd == I2C_MASTER_CMD_BURST_SEND_START) || + (ui32Cmd == I2C_MASTER_CMD_BURST_SEND_CONT) || + (ui32Cmd == I2C_MASTER_CMD_BURST_SEND_FINISH) || + (ui32Cmd == I2C_MASTER_CMD_BURST_SEND_ERROR_STOP) || + (ui32Cmd == I2C_MASTER_CMD_BURST_RECEIVE_START) || + (ui32Cmd == I2C_MASTER_CMD_BURST_RECEIVE_CONT) || + (ui32Cmd == I2C_MASTER_CMD_BURST_RECEIVE_FINISH) || + (ui32Cmd == I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP)); + + // + // Send the command. + // + HWREG(I2CM_CTRL) = ui32Cmd; +} + +//***************************************************************************** +// +//! Gets the error status of the I2C master module +//! +//! This function is obtains the error status of the master module send +//! and receive operations. +//! +//! \return Returns the error status as one of the following values: +//! +//! - \b I2C_MASTER_ERR_NONE +//! - \b I2C_MASTER_ERR_ADDR_ACK +//! - \b I2C_MASTER_ERR_DATA_ACK +//! - \b I2C_MASTER_ERR_ARB_LOST +// +//***************************************************************************** +uint32_t +I2CMasterErr(void) +{ + uint32_t ui32Err; + + // + // Get the raw error state + // + ui32Err = HWREG(I2CM_STAT); + + // + // If the I2C master is busy, then all the other bit are invalid, and + // don't have an error to report. + // + if(ui32Err & I2CM_STAT_BUSY) + { + return(I2C_MASTER_ERR_NONE); + } + + // + // Check for errors. + // + if(ui32Err & (I2CM_STAT_ERROR | I2CM_STAT_ARBLST)) + { + return(ui32Err & + (I2CM_STAT_ARBLST | I2CM_STAT_DATACK | I2CM_STAT_ADRACK)); + } + else + { + return(I2C_MASTER_ERR_NONE); + } +} + +//***************************************************************************** +// +//! Transmits a byte from the I2C master +//! +//! \param ui8Data data to be transmitted from the I2C master +//! +//! This function places the supplied data into I2C master data register. +//! +//! \return None +// +//***************************************************************************** +void +I2CMasterDataPut(uint8_t ui8Data) +{ + // + // Write the byte. + // + HWREG(I2CM_DR) = ui8Data; +} + +//***************************************************************************** +// +//! Receives a byte that has been sent to the I2C master +//! +//! This function reads a byte of data from the I2C master data register. +//! +//! \return Returns the byte received from by the I2C master, cast as an +//! uint32_t +// +//***************************************************************************** +uint32_t +I2CMasterDataGet(void) +{ + // + // Read a byte. + // + return(HWREG(I2CM_DR)); +} + +//***************************************************************************** +// +//! Gets the I2C slave module status +//! +//! This function returns the action requested from a master, if any. +//! Possible values are: +//! +//! - \b I2C_SLAVE_ACT_NONE +//! - \b I2C_SLAVE_ACT_RREQ +//! - \b I2C_SLAVE_ACT_TREQ +//! - \b I2C_SLAVE_ACT_RREQ_FBR +//! +//! \return Returns \b I2C_SLAVE_ACT_NONE to indicate that no action has been +//! requested of the I2C slave module, \b I2C_SLAVE_ACT_RREQ to indicate that +//! an I2C master has sent data to the I2C slave module, \b I2C_SLAVE_ACT_TREQ +//! to indicate that an I2C master has requested that the I2C slave module send +//! data, and \b I2C_SLAVE_ACT_RREQ_FBR to indicate that an I2C master has sent +//! data to the I2C slave and the first byte following the address of the slave +//! has been received. +// +//***************************************************************************** +uint32_t +I2CSlaveStatus(void) +{ + // + // Return the slave status. + // + return(HWREG(I2CS_STAT)); +} + +//***************************************************************************** +// +//! Transmits a byte from the I2C slave +//! +//! \param ui8Data data to be transmitted from the I2C slave +//! +//! This function places the supplied data into I2C slave data register. +//! +//! \return None +// +//***************************************************************************** +void +I2CSlaveDataPut(uint8_t ui8Data) +{ + // + // Write the byte. + // + HWREG(I2CS_DR) = ui8Data; +} + +//***************************************************************************** +// +//! Receives a byte that has been sent to the I2C slave +//! +//! This function reads a byte of data from the I2C slave data register. +//! +//! \return Returns the byte received from by the I2C slave, cast as an +//! uint32_t. +// +//***************************************************************************** +uint32_t +I2CSlaveDataGet(void) +{ + // + // Read a byte. + // + return(HWREG(I2CS_DR)); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/i2c_lib.h b/bsp/boards/mimsy2-cc2538/source/i2c_lib.h new file mode 100644 index 0000000000..d3f4014889 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/i2c_lib.h @@ -0,0 +1,181 @@ +/****************************************************************************** +* Filename: i2c.h +* Revised: $Date: 2013-01-21 15:25:21 +0100 (Mon, 21 Jan 2013) $ +* Revision: $Revision: 9178 $ +* +* Description: Prototypes for the I2C Driver. +* +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __I2C_H__ +#define __I2C_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// Defines for the API. +// +//***************************************************************************** + +//***************************************************************************** +// +// Interrupt defines. +// +//***************************************************************************** +#define I2C_INT_MASTER 0x00000001 +#define I2C_INT_SLAVE 0x00000002 + +//***************************************************************************** +// +// I2C Master commands. +// +//***************************************************************************** +#define I2C_MASTER_CMD_SINGLE_SEND \ + 0x00000007 +#define I2C_MASTER_CMD_SINGLE_RECEIVE \ + 0x00000007 +#define I2C_MASTER_CMD_BURST_SEND_START \ + 0x00000003 +#define I2C_MASTER_CMD_BURST_SEND_CONT \ + 0x00000001 +#define I2C_MASTER_CMD_BURST_SEND_FINISH \ + 0x00000005 +#define I2C_MASTER_CMD_BURST_SEND_ERROR_STOP \ + 0x00000004 +#define I2C_MASTER_CMD_BURST_RECEIVE_START \ + 0x0000000b +#define I2C_MASTER_CMD_BURST_RECEIVE_CONT \ + 0x00000009 +#define I2C_MASTER_CMD_BURST_RECEIVE_FINISH \ + 0x00000005 +#define I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP \ + 0x00000004 + +//***************************************************************************** +// +// I2C Master error status. +// +//***************************************************************************** +#define I2C_MASTER_ERR_NONE 0 +#define I2C_MASTER_ERR_ADDR_ACK 0x00000004 +#define I2C_MASTER_ERR_DATA_ACK 0x00000008 +#define I2C_MASTER_ERR_ARB_LOST 0x00000010 + +//***************************************************************************** +// +// I2C Slave action requests +// +//***************************************************************************** +#define I2C_SLAVE_ACT_NONE 0 +#define I2C_SLAVE_ACT_RREQ 0x00000001 // Master has sent data +#define I2C_SLAVE_ACT_TREQ 0x00000002 // Master has requested data +#define I2C_SLAVE_ACT_RREQ_FBR 0x00000005 // Master has sent first byte + +//***************************************************************************** +// +// Miscellaneous I2C driver definitions. +// +//***************************************************************************** +#define I2C_MASTER_MAX_RETRIES 1000 // Number of retries + + +//***************************************************************************** +// +// I2C Slave interrupts. +// +//***************************************************************************** +#define I2C_SLAVE_INT_STOP 0x00000004 // Stop Condition Interrupt. +#define I2C_SLAVE_INT_START 0x00000002 // Start Condition Interrupt. +#define I2C_SLAVE_INT_DATA 0x00000001 // Data Interrupt. + + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void I2CIntRegister(void (*pfnHandler)(void)); +extern void I2CIntUnregister(void); +extern bool I2CMasterBusBusy(void); +extern bool I2CMasterBusy(void); +extern void I2CMasterControl(uint32_t ui32Cmd); +extern uint32_t I2CMasterDataGet(void); +extern void I2CMasterDataPut(uint8_t ui8Data); +extern void I2CMasterDisable(void); +extern void I2CMasterEnable(void); +extern uint32_t I2CMasterErr(void); +extern void I2CMasterInitExpClk(uint32_t ui32I2CClk, bool bFast); +extern void I2CMasterIntClear(void); +extern void I2CMasterIntDisable(void); +extern void I2CMasterIntEnable(void); +extern bool I2CMasterIntStatus(bool bMasked); +extern void I2CMasterSlaveAddrSet(uint8_t ui8SlaveAddr, + bool bReceive); +extern uint32_t I2CSlaveDataGet(void); +extern void I2CSlaveDataPut(uint8_t ui8Data); +extern void I2CSlaveDisable(void); +extern void I2CSlaveEnable(void); +extern void I2CSlaveInit(uint8_t ui8SlaveAddr); +extern void I2CSlaveIntClear(void); +extern void I2CSlaveIntDisable(void); +extern void I2CSlaveIntEnable(void); +extern void I2CSlaveIntClearEx(uint32_t ui32IntFlags); +extern void I2CSlaveIntDisableEx(uint32_t ui32IntFlags); +extern void I2CSlaveIntEnableEx(uint32_t ui32IntFlags); +extern bool I2CSlaveIntStatus(bool bMasked); +extern uint32_t I2CSlaveIntStatusEx(bool bMasked); +extern uint32_t I2CSlaveStatus(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __I2C_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/interrupt.c b/bsp/boards/mimsy2-cc2538/source/interrupt.c new file mode 100644 index 0000000000..6a75a9196e --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/interrupt.c @@ -0,0 +1,829 @@ +/****************************************************************************** +* Filename: interrupt.c +* Revised: $Date: 2013-03-20 14:47:53 +0100 (Wed, 20 Mar 2013) $ +* Revision: $Revision: 9489 $ +* +* Description: Driver for the NVIC Interrupt Controller. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup interrupt_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include "cpu.h" +#include "debug.h" +#include "interrupt.h" + +//***************************************************************************** +// +// This is a mapping between priority grouping encodings and the number of +// preemption priority bits. +// +//***************************************************************************** +static const uint32_t g_pui32Priority[] = +{ + NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6, + NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4, NVIC_APINT_PRIGROUP_5_3, + NVIC_APINT_PRIGROUP_6_2, NVIC_APINT_PRIGROUP_7_1 +}; + +//***************************************************************************** +// +// This is a mapping between interrupt number and the register that contains +// the priority encoding for that interrupt. +// +//***************************************************************************** +static const uint32_t g_pui32Regs[] = +{ + 0, NVIC_SYS_PRI1, NVIC_SYS_PRI2, NVIC_SYS_PRI3, NVIC_PRI0, NVIC_PRI1, + NVIC_PRI2, NVIC_PRI3, NVIC_PRI4, NVIC_PRI5, NVIC_PRI6, NVIC_PRI7, + NVIC_PRI8, NVIC_PRI9, NVIC_PRI10, NVIC_PRI11, NVIC_PRI12, NVIC_PRI13, + NVIC_PRI14, NVIC_PRI15, NVIC_PRI16, NVIC_PRI17, NVIC_PRI18, NVIC_PRI19, + NVIC_PRI20, NVIC_PRI21, NVIC_PRI22, NVIC_PRI23, NVIC_PRI24, NVIC_PRI25, + NVIC_PRI26, NVIC_PRI27, NVIC_PRI28, NVIC_PRI29, NVIC_PRI30, NVIC_PRI31, + NVIC_PRI32, NVIC_PRI33, NVIC_PRI34, NVIC_PRI35, NVIC_PRI36 +}; + +//***************************************************************************** +// +// This is a mapping between interrupt number (for the peripheral interrupts +// only) and the register that contains the interrupt enable for that +// interrupt. +// +//***************************************************************************** +static const uint32_t g_pui32EnRegs[] = +{ + NVIC_EN0, NVIC_EN1, NVIC_EN2, NVIC_EN3, NVIC_EN4 +}; + +//***************************************************************************** +// +// This is a mapping between interrupt number (for the peripheral interrupts +// only) and the register that contains the interrupt disable for that +// interrupt. +// +//***************************************************************************** +static const uint32_t g_pui32DisRegs[] = +{ + NVIC_DIS0, NVIC_DIS1, NVIC_DIS2, NVIC_DIS3, NVIC_DIS4 +}; + +//***************************************************************************** +// +// This is a mapping between interrupt number (for the peripheral interrupts +// only) and the register that contains the interrupt pend for that interrupt. +// +//***************************************************************************** +static const uint32_t g_pui32PendRegs[] = +{ + NVIC_PEND0, NVIC_PEND1, NVIC_PEND2, NVIC_PEND3, NVIC_PEND4 +}; + +//***************************************************************************** +// +// This is a mapping between interrupt number (for the peripheral interrupts +// only) and the register that contains the interrupt unpend for that +// interrupt. +// +//***************************************************************************** +static const uint32_t g_pui32UnpendRegs[] = +{ + NVIC_UNPEND0, NVIC_UNPEND1, NVIC_UNPEND2, NVIC_UNPEND3, NVIC_UNPEND4 +}; + +//***************************************************************************** +// +//! \internal +//! The default interrupt handler +//! +//! This is the default interrupt handler for all interrupts. It simply loops +//! forever so that the system state is preserved for observation by a +//! debugger. Since interrupts should be disabled before unregistering the +//! corresponding handler, this should never be called. +//! +//! \return None +// +//***************************************************************************** +static void +IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// The processor vector table +// +// This contains a list of the handlers for the various interrupt sources in +// the system. The layout of this list is defined by the hardware; assertion +// of an interrupt causes the processor to start executing directly at the +// address given in the corresponding location in this list. +// +//***************************************************************************** +#if defined(__ICCARM__) +#pragma data_alignment=1024 +static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) @ "VTABLE"; +#elif defined(__TI_COMPILER_VERSION__) || defined(DOXYGEN) +#pragma DATA_ALIGN(g_pfnRAMVectors, 1024) +#pragma DATA_SECTION(g_pfnRAMVectors, ".vtable") +void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void); +#else +static __attribute__((section("vtable"))) +void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__((aligned(1024))); +#endif + +//***************************************************************************** +// +//! Enables the processor interrupt +//! +//! This function allows the processor to respond to interrupts. This does not +//! affect the set of interrupts enabled in the interrupt controller; it just +//! gates the single interrupt from the controller to the processor. +//! +//! \return Returns \b true if interrupts were disabled when the function was +//! called or \b false if they were initially enabled. +// +//***************************************************************************** +bool +IntMasterEnable(void) +{ + // + // Enable processor interrupts. + // + return(CPUcpsie()); +} + +//***************************************************************************** +// +//! Disables the processor interrupt +//! +//! This function prevents the processor from receiving interrupts. This does +//! not affect the set of interrupts enabled in the interrupt controller; it +//! just gates the single interrupt from the controller to the processor. +//! +//! \return Returns \b true if interrupts were already disabled when the +//! function was called or \b false if they were initially enabled. +// +//***************************************************************************** +bool +IntMasterDisable(void) +{ + // + // Disable processor interrupts. + // + return(CPUcpsid()); +} + +//***************************************************************************** +// +//! Registers a function to be called when an interrupt occurs +//! +//! \param ui32Interrupt specifies the interrupt in question. +//! \param pfnHandler is a pointer to the function to be called. +//! +//! This function specifies the handler function to be called when the +//! given interrupt is asserted to the processor. When the interrupt occurs, +//! if it is enabled (through IntEnable()), the handler function is called in +//! interrupt context. Because the handler function can preempt other code, care +//! must be taken to protect memory or peripherals that are accessed by the +//! handler and other nonhandler code. +//! +//! \note This function (directly or indirectly through a peripheral +//! driver interrupt register function) moves the interrupt vector table from +//! flash to SRAM. Therefore, care must be taken when linking the application +//! to ensure that the SRAM vector table is located at the beginning of SRAM; +//! otherwise NVIC will not look in the correct portion of memory for the +//! vector table (it requires the vector table be on a 1-kB memory alignment). +//! Normally, the SRAM vector table is so placed through the use of linker +//! scripts. See the discussion of compile-time versus runtime interrupt handler +//! registration in the introduction to this chapter. +//! +//! \return None +// +//***************************************************************************** +void +IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void)) +{ + uint32_t ui32Idx, ui32Value; + + // + // Check the arguments. + // + ASSERT(ui32Interrupt < NUM_INTERRUPTS); + + // Check below could be removed in final application +#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP + ASSERT(IntAltMapIsEnabled()); +#else + ASSERT(~IntAltMapIsEnabled()); +#endif + + // + // Make sure that the RAM vector table is correctly aligned. + // + ASSERT(((uint32_t)g_pfnRAMVectors & 0x000003ff) == 0); + + // + // See if the RAM vector table has been initialized. + // + if(HWREG(NVIC_VTABLE) != (uint32_t)g_pfnRAMVectors) + { + // + // Copy the vector table from the beginning of FLASH to the RAM vector + // table. + // + ui32Value = HWREG(NVIC_VTABLE); + for(ui32Idx = 0; ui32Idx < NUM_INTERRUPTS; ui32Idx++) + { + g_pfnRAMVectors[ui32Idx] = (void (*)(void))HWREG((ui32Idx * 4) + + ui32Value); + } + + // + // Point NVIC at the RAM vector table. + // + HWREG(NVIC_VTABLE) = (uint32_t)g_pfnRAMVectors; + } + + // + // Save the interrupt handler. + // + g_pfnRAMVectors[ui32Interrupt] = pfnHandler; +} + +//***************************************************************************** +// +//! Unregisters the function to be called when an interrupt occurs +//! +//! \param ui32Interrupt specifies the interrupt in question. +//! +//! This function indicates that no handler should be called when the +//! given interrupt is asserted to the processor. The interrupt source is +//! automatically disabled (through IntDisable()) if necessary. +//! +//! \sa See IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +IntUnregister(uint32_t ui32Interrupt) +{ + // + // Check the arguments. + // + ASSERT(ui32Interrupt < NUM_INTERRUPTS); + + // + // Check that at least one interrupt was dynamically registered + // (by calling IntRegister()) + // + ASSERT(HWREG(NVIC_VTABLE) == (uint32_t)g_pfnRAMVectors); + + // Check below could be removed in final application +#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP + ASSERT(IntAltMapIsEnabled()); +#else + ASSERT(~IntAltMapIsEnabled()); +#endif + + + // + // Reset the interrupt handler. + // + g_pfnRAMVectors[ui32Interrupt] = IntDefaultHandler; +} + +//***************************************************************************** +// +//! Sets the priority grouping of the interrupt controller +//! +//! \param ui32Bits specifies the number of bits of preemptable priority. +//! +//! This function specifies the split between preemptable priority levels and +//! subpriority levels in the interrupt priority specification. The range of +//! the grouping values depend on the hardware implementation; on +//! the CC2538 device family, 3 bits are available for hardware interrupt +//! prioritization and therefore priority grouping values of three through +//! seven have the same effect. +//! +//! \return None +// +//***************************************************************************** +void +IntPriorityGroupingSet(uint32_t ui32Bits) +{ + // + // Check the arguments. + // + ASSERT(ui32Bits < NUM_PRIORITY); + + // + // Set the priority grouping. + // + HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pui32Priority[ui32Bits]; +} + +//***************************************************************************** +// +//! Gets the priority grouping of the interrupt controller +//! +//! This function returns the split between preemptable priority levels and +//! subpriority levels in the interrupt priority specification. +//! +//! \return Returns the number of bits of preemptable priority +// +//***************************************************************************** +uint32_t +IntPriorityGroupingGet(void) +{ + uint32_t ui32Loop, ui32Value; + + // + // Read the priority grouping. + // + ui32Value = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M; + + // + // Loop through the priority grouping values. + // + for(ui32Loop = 0; ui32Loop < NUM_PRIORITY; ui32Loop++) + { + // + // Stop looping if this value matches. + // + if(ui32Value == g_pui32Priority[ui32Loop]) + { + break; + } + } + + // + // Return the number of priority bits. + // + return(ui32Loop); +} + +//***************************************************************************** +// +//! Sets the priority of an interrupt +//! +//! \param ui32Interrupt specifies the interrupt in question. +//! \param ui8Priority specifies the priority of the interrupt. +//! +//! This function sets the priority of an interrupt. When multiple +//! interrupts are asserted simultaneously, those with the highest priority +//! are processed before the lower priority interrupts. Smaller numbers +//! correspond to higher interrupt priorities; priority 0 is the highest +//! interrupt priority. +//! +//! The hardware priority mechanism will looks only at the upper N bits of the +//! priority level (where N is 3 for the CC2538 device family), so any +//! prioritization must be performed in those bits. The remaining bits can be +//! used to subprioritize the interrupt sources, and may be used by the +//! hardware priority mechanism on a future part. This arrangement allows +//! priorities to migrate to different NVIC implementations without changing +//! the gross prioritization of the interrupts. +//! Thus for CC2538 to set a priority of 3, the parameter \e ui8Priority must +//! be set to (3<<5). +//! +//! \return None +// +//***************************************************************************** +void +IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority) +{ + uint32_t ui32Temp; + + // + // Check the arguments. + // + ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS)); + + // + // Set the interrupt priority. + // + ui32Temp = HWREG(g_pui32Regs[ui32Interrupt >> 2]); + ui32Temp &= ~(0xFF << (8 * (ui32Interrupt & 3))); + ui32Temp |= ui8Priority << (8 * (ui32Interrupt & 3)); + HWREG(g_pui32Regs[ui32Interrupt >> 2]) = ui32Temp; +} + +//***************************************************************************** +// +//! Gets the priority of an interrupt +//! +//! \param ui32Interrupt specifies the interrupt in question. +//! +//! This function gets the priority of an interrupt. See IntPrioritySet() for +//! a definition of the priority value. +//! +//! \return Returns the interrupt priority, or -1 if an invalid interrupt was +//! specified +// +//***************************************************************************** +int32_t +IntPriorityGet(uint32_t ui32Interrupt) +{ + // + // Check the arguments. + // + ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS)); + + // + // Return the interrupt priority. + // + return((HWREG(g_pui32Regs[ui32Interrupt >> 2]) >> (8 * (ui32Interrupt & 3))) & + 0xFF); +} + +//***************************************************************************** +// +//! Enables an interrupt +//! +//! \param ui32Interrupt specifies the interrupt to be enabled. +//! +//! This function enables the specified interrupt in the interrupt controller. +//! Other enables for the interrupt (such as at the peripheral level) are +//! unaffected by this function. +//! +//! \return None +// +//***************************************************************************** +void +IntEnable(uint32_t ui32Interrupt) +{ + // + // Check the arguments. + // + ASSERT(ui32Interrupt < NUM_INTERRUPTS); + + // + // Determine the interrupt to enable. + // + if(ui32Interrupt == FAULT_MPU) + { + // + // Enable the MemManage interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM; + } + else if(ui32Interrupt == FAULT_BUS) + { + // + // Enable the bus fault interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS; + } + else if(ui32Interrupt == FAULT_USAGE) + { + // + // Enable the usage fault interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE; + } + else if(ui32Interrupt == FAULT_SYSTICK) + { + // + // Enable the System Tick interrupt. + // + HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN; + } + else if(ui32Interrupt >= 16) + { + // + // Enable the general interrupt. + // + HWREG(g_pui32EnRegs[(ui32Interrupt - 16) / 32]) = + 1 << ((ui32Interrupt - 16) & 31); + } +} + +//***************************************************************************** +// +//! Disables an interrupt +//! +//! \param ui32Interrupt specifies the interrupt to be disabled. +//! +//! This function disables specified interrupt in the interrupt controller. +//! Other enables for the interrupt (such as at the peripheral level) are +//! unaffected by this function. +//! +//! \return None +// +//***************************************************************************** +void +IntDisable(uint32_t ui32Interrupt) +{ + // + // Check the arguments. + // + ASSERT(ui32Interrupt < NUM_INTERRUPTS); + + // + // Determine the interrupt to disable. + // + if(ui32Interrupt == FAULT_MPU) + { + // + // Disable the MemManage interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM); + } + else if(ui32Interrupt == FAULT_BUS) + { + // + // Disable the bus fault interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS); + } + else if(ui32Interrupt == FAULT_USAGE) + { + // + // Disable the usage fault interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE); + } + else if(ui32Interrupt == FAULT_SYSTICK) + { + // + // Disable the System Tick interrupt. + // + HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN); + } + else if(ui32Interrupt >= 16) + { + // + // Disable the general interrupt. + // + HWREG(g_pui32DisRegs[(ui32Interrupt - 16) / 32]) = + 1 << ((ui32Interrupt - 16) & 31); + } +} + +//***************************************************************************** +// +//! Pends an interrupt +//! +//! \param ui32Interrupt specifies the interrupt to be pended. +//! +//! This function pends the specified interrupt in the interrupt controller. +//! This causes the interrupt controller to execute the corresponding interrupt +//! handler at the next available time, based on the current interrupt state +//! priorities. For example, if called by a higher priority interrupt handler, +//! the specified interrupt handler is not called until after the current +//! interrupt handler executes. The interrupt must have been enabled for +//! it to be called. +//! +//! \return None +// +//***************************************************************************** +void +IntPendSet(uint32_t ui32Interrupt) +{ + // + // Check the arguments. + // + ASSERT(ui32Interrupt < NUM_INTERRUPTS); + + // + // Determine the interrupt to pend. + // + if(ui32Interrupt == FAULT_NMI) + { + // + // Pend the NMI interrupt. + // + HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_NMI_SET; + } + else if(ui32Interrupt == FAULT_PENDSV) + { + // + // Pend the PendSV interrupt. + // + HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PEND_SV; + } + else if(ui32Interrupt == FAULT_SYSTICK) + { + // + // Pend the SysTick interrupt. + // + HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTSET; + } + else if(ui32Interrupt >= 16) + { + // + // Pend the general interrupt. + // + HWREG(g_pui32PendRegs[(ui32Interrupt - 16) / 32]) = + 1 << ((ui32Interrupt - 16) & 31); + } +} + +//***************************************************************************** +// +//! Unpends an interrupt +//! +//! \param ui32Interrupt specifies the interrupt to be unpended. +//! +//! This function unpends the specified interrupt in the interrupt controller. +//! This will cause any previously generated interrupts that have not been +//! handled yet (due to higher priority interrupts or the interrupt no having +//! been enabled yet) to be discarded. +//! +//! \return None +// +//***************************************************************************** +void +IntPendClear(uint32_t ui32Interrupt) +{ + // + // Check the arguments. + // + ASSERT(ui32Interrupt < NUM_INTERRUPTS); + + // + // Determine the interrupt to unpend. + // + if(ui32Interrupt == FAULT_PENDSV) + { + // + // Unpend the PendSV interrupt. + // + HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_UNPEND_SV; + } + else if(ui32Interrupt == FAULT_SYSTICK) + { + // + // Unpend the SysTick interrupt. + // + HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR; + } + else if(ui32Interrupt >= 16) + { + // + // Unpend the general interrupt. + // + HWREG(g_pui32UnpendRegs[(ui32Interrupt - 16) / 32]) = + 1 << ((ui32Interrupt - 16) & 31); + } +} + +//***************************************************************************** +// +//! Sets the priority masking level +//! +//! \param ui32PriorityMask is the priority level that will be masked. +//! +//! This function sets the interrupt priority masking level so that all +//! interrupts at the specified or lesser priority level is masked. This +//! can be used to globally disable a set of interrupts with priority below +//! a predetermined threshold. A value of 0 disables priority +//! masking. +//! +//! Smaller numbers correspond to higher interrupt priorities. For example, +//! a priority level mask of 4 allows interrupts of priority level 0-3, +//! and interrupts with a numerical priority of 4 and greater are blocked. +//! +//! The hardware priority mechanism looks only at the upper N bits of the +//! priority level (where N is 3 for the CC2538 device family), so any +//! prioritization must be performed in those bits. +//! +//! \return None +// +//***************************************************************************** +void +IntPriorityMaskSet(uint32_t ui32PriorityMask) +{ + CPUbasepriSet(ui32PriorityMask); +} + +//***************************************************************************** +// +//! Gets the priority masking level +//! +//! This function gets the current setting of the interrupt priority masking +//! level. The value returned is the priority level such that all interrupts +//! of that priority and lesser priorities are masked. A value of 0 disables +//! priority masking. +//! +//! Smaller numbers correspond to higher interrupt priorities. For example, +//! a priority level mask of 4 allows interrupts of priority level 0-3, +//! and interrupts with a numerical priority of 4 and greater will be blocked. +//! +//! The hardware priority mechanism looks only at the upper N bits of the +//! priority level (where N is 3 for the CC2538 device family), so any +//! prioritization must be performed in those bits. +//! +//! \return Returns the value of the interrupt priority level mask +// +//***************************************************************************** +uint32_t +IntPriorityMaskGet(void) +{ + return(CPUbasepriGet()); +} + +//***************************************************************************** +// +//! Enables the alternate interrupt mapping +//! +//! This function enables the alternate (that is, smaller) interrupt map. +//! +//! \sa See also IntAltMapDisable() and IntAltMapIsEnabled(). +//! +//! \return None +// +//***************************************************************************** +void IntAltMapEnable(void) +{ + HWREG(SYS_CTRL_I_MAP) |= SYS_CTRL_I_MAP_ALTMAP; +} + +//***************************************************************************** +// +//! Disable the alternate interrupt mapping +//! +//! This function disables the alternate (that is, smaller) interrupt map. +//! +//! \sa See also IntAltMapDisable() and IntAltMapIsEnabled(). +//! +//! \return None +// +//***************************************************************************** +void IntAltMapDisable(void) +{ + HWREG(SYS_CTRL_I_MAP) &= ~SYS_CTRL_I_MAP_ALTMAP; +} + +//***************************************************************************** +// +//! Checks to see if the Alternate Interrupt Mapping is in use +//! +//! \sa See also IntAltMapDisable() and IntAltMapIsEnabled(). +//! +//! \return Returns \b true if the Alternate Mapping is in use and \b false +//! otherwise. +// +//***************************************************************************** +bool IntAltMapIsEnabled(void) +{ + if(HWREG(SYS_CTRL_I_MAP) & SYS_CTRL_I_MAP_ALTMAP) + { + return (true); + } + else + { + return (false); + } +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/interrupt.h b/bsp/boards/mimsy2-cc2538/source/interrupt.h new file mode 100644 index 0000000000..2c22284d41 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/interrupt.h @@ -0,0 +1,99 @@ +/****************************************************************************** +* Filename: interrupt.h +* Revised: $Date: 2013-01-25 10:58:16 +0100 (Fri, 25 Jan 2013) $ +* Revision: $Revision: 9248 $ +* +* Description: Prototypes for the NVIC Interrupt Controller Driver. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// Macro to generate an interrupt priority mask based on the number of bits +// of priority supported by the hardware. +// +//***************************************************************************** +#define INT_PRIORITY_MASK ((0xFF << (8 - NUM_PRIORITY_BITS)) & 0xFF) + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern bool IntMasterEnable(void); +extern bool IntMasterDisable(void); +extern void IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void)); +extern void IntUnregister(uint32_t ui32Interrupt); +extern void IntPriorityGroupingSet(uint32_t ui32Bits); +extern uint32_t IntPriorityGroupingGet(void); +extern void IntPrioritySet(uint32_t ui32Interrupt, + uint8_t ui8Priority); +extern int32_t IntPriorityGet(uint32_t ui32Interrupt); +extern void IntEnable(uint32_t ui32Interrupt); +extern void IntDisable(uint32_t ui32Interrupt); +extern void IntPendSet(uint32_t ui32Interrupt); +extern void IntPendClear(uint32_t ui32Interrupt); +extern void IntPriorityMaskSet(uint32_t ui32PriorityMask); +extern uint32_t IntPriorityMaskGet(void); + +extern void IntAltMapEnable(void); +extern void IntAltMapDisable(void); +extern bool IntAltMapIsEnabled(void); + + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __INTERRUPT_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/ioc.c b/bsp/boards/mimsy2-cc2538/source/ioc.c new file mode 100644 index 0000000000..4469245982 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/ioc.c @@ -0,0 +1,865 @@ +/****************************************************************************** +* Filename: ioc.c +* Revised: $Date: 2013-03-22 15:36:20 +0100 (Fri, 22 Mar 2013) $ +* Revision: $Revision: 9511 $ +* +* Description: Driver for the I/O controller. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup ioc_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include "debug.h" +#include "ioc.h" +#include "gpio.h" + +//***************************************************************************** +// +// This is the mapping between a pin number within port A and the corresponding +// override register. +// +//***************************************************************************** +static const uint32_t g_pui32IOCPortAOverrideReg[] = +{ + IOC_PA0_OVER, IOC_PA1_OVER, IOC_PA2_OVER, IOC_PA3_OVER, + IOC_PA4_OVER, IOC_PA5_OVER, IOC_PA6_OVER, IOC_PA7_OVER +}; + +//***************************************************************************** +// +// This is the mapping between a pin number within port B and the corresponding +// override register. +// +//***************************************************************************** +static const uint32_t g_pui32IOCPortBOverrideReg[] = +{ + IOC_PB0_OVER, IOC_PB1_OVER, IOC_PB2_OVER, IOC_PB3_OVER, + IOC_PB4_OVER, IOC_PB5_OVER, IOC_PB6_OVER, IOC_PB7_OVER +}; + +//***************************************************************************** +// +// This is the mapping between a pin number within port C and the corresponding +// override register. +// +//***************************************************************************** +static const uint32_t g_pui32IOCPortCOverrideReg[] = +{ + IOC_PC0_OVER, IOC_PC1_OVER, IOC_PC2_OVER, IOC_PC3_OVER, + IOC_PC4_OVER, IOC_PC5_OVER, IOC_PC6_OVER, IOC_PC7_OVER +}; + +//***************************************************************************** +// +// This is the mapping between a pin number within port D and the corresponding +// override register. +// +//***************************************************************************** +static const uint32_t g_pui32IOCPortDOverrideReg[] = +{ + IOC_PD0_OVER, IOC_PD1_OVER, IOC_PD2_OVER, IOC_PD3_OVER, + IOC_PD4_OVER, IOC_PD5_OVER, IOC_PD6_OVER, IOC_PD7_OVER +}; + +//***************************************************************************** +// +// This is the mapping between a pin number within port A and the corresponding +// signal select register. +// +//***************************************************************************** +static const uint32_t g_pui32IOCPortASignSelectReg[] = +{ + IOC_PA0_SEL, IOC_PA1_SEL, IOC_PA2_SEL, IOC_PA3_SEL, + IOC_PA4_SEL, IOC_PA5_SEL, IOC_PA6_SEL, IOC_PA7_SEL +}; + +//***************************************************************************** +// +// This is the mapping between a pin number within port B and the corresponding +// signal select register. +// +//***************************************************************************** +static const uint32_t g_pui32IOCPortBSignSelectReg[] = +{ + IOC_PB0_SEL, IOC_PB1_SEL, IOC_PB2_SEL, IOC_PB3_SEL, + IOC_PB4_SEL, IOC_PB5_SEL, IOC_PB6_SEL, IOC_PB7_SEL +}; + +//***************************************************************************** +// +// This is the mapping between a pin number within port C and the corresponding +// signal select register. +// +//***************************************************************************** +static const uint32_t g_pui32IOCPortCSignSelectReg[] = +{ + IOC_PC0_SEL, IOC_PC1_SEL, IOC_PC2_SEL, IOC_PC3_SEL, + IOC_PC4_SEL, IOC_PC5_SEL, IOC_PC6_SEL, IOC_PC7_SEL +}; + +//***************************************************************************** +// +// This is the mapping between a pin number within port D and the corresponding +// signal select register. +// +//***************************************************************************** +static const uint32_t g_pui32IOCPortDSignSelectReg[] = +{ + IOC_PD0_SEL, IOC_PD1_SEL, IOC_PD2_SEL, IOC_PD3_SEL, + IOC_PD4_SEL, IOC_PD5_SEL, IOC_PD6_SEL, IOC_PD7_SEL +}; + +//***************************************************************************** +// +// Defined values for the port select registers. +// (The registers are in the addr range: IOC_UARTRXD_UART0 - IOC_GPT3OCP2). +// +//***************************************************************************** +#define IOC_PAD_IN_SEL_PA0 0x00000000 // PA0 +#define IOC_PAD_IN_SEL_PA1 0x00000001 // PA1 +#define IOC_PAD_IN_SEL_PA2 0x00000002 // PA2 +#define IOC_PAD_IN_SEL_PA3 0x00000003 // PA3 +#define IOC_PAD_IN_SEL_PA4 0x00000004 // PA4 +#define IOC_PAD_IN_SEL_PA5 0x00000005 // PA5 +#define IOC_PAD_IN_SEL_PA6 0x00000006 // PA6 +#define IOC_PAD_IN_SEL_PA7 0x00000007 // PA7 +#define IOC_PAD_IN_SEL_PB0 0x00000008 // PB0 +#define IOC_PAD_IN_SEL_PB1 0x00000009 // PB1 +#define IOC_PAD_IN_SEL_PB2 0x0000000A // PB2 +#define IOC_PAD_IN_SEL_PB3 0x0000000B // PB3 +#define IOC_PAD_IN_SEL_PB4 0x0000000C // PB4 +#define IOC_PAD_IN_SEL_PB5 0x0000000D // PB5 +#define IOC_PAD_IN_SEL_PB6 0x0000000E // PB6 +#define IOC_PAD_IN_SEL_PB7 0x0000000F // PB7 +#define IOC_PAD_IN_SEL_PC0 0x00000010 // PC0 +#define IOC_PAD_IN_SEL_PC1 0x00000011 // PC1 +#define IOC_PAD_IN_SEL_PC2 0x00000012 // PC2 +#define IOC_PAD_IN_SEL_PC3 0x00000013 // PC3 +#define IOC_PAD_IN_SEL_PC4 0x00000014 // PC4 +#define IOC_PAD_IN_SEL_PC5 0x00000015 // PC5 +#define IOC_PAD_IN_SEL_PC6 0x00000016 // PC6 +#define IOC_PAD_IN_SEL_PC7 0x00000017 // PC7 +#define IOC_PAD_IN_SEL_PD0 0x00000018 // PD0 +#define IOC_PAD_IN_SEL_PD1 0x00000019 // PD1 +#define IOC_PAD_IN_SEL_PD2 0x0000001A // PD2 +#define IOC_PAD_IN_SEL_PD3 0x0000001B // PD3 +#define IOC_PAD_IN_SEL_PD4 0x0000001C // PD4 +#define IOC_PAD_IN_SEL_PD5 0x0000001D // PD5 +#define IOC_PAD_IN_SEL_PD6 0x0000001E // PD6 +#define IOC_PAD_IN_SEL_PD7 0x0000001F // PD7 + + +//***************************************************************************** +// +//! Mux desired on-chip peripheral output signal to the desired port pin(s). +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the port pin(s). +//! \param ui32OutputSignal is the desired peripheral output signal to drive the +//! desired port pin(s). +//! +//! This function routes the desired on-chip peripheral signal to the +//! desired pin(s) on the selected GPIO port. Functions are available within +//! the GPIO device driver that can set the peripheral signal to be under +//! hardware control. The IOCPadConfigSet() function can be used to set the pin +//! drive type on the desired port pin. +//! +//! The \e ui32OutputSignal parameter is an enumerated type that controls which +//! peripheral output signal to route to the desired port pin(s). +//! This parameter can have any of the following values: +//! +//! - \b IOC_MUX_OUT_SEL_UART0_TXD +//! - \b IOC_MUX_OUT_SEL_UART1_RTS +//! - \b IOC_MUX_OUT_SEL_UART1_TXD +//! - \b IOC_MUX_OUT_SEL_SSI0_TXD +//! - \b IOC_MUX_OUT_SEL_SSI0_CLKOUT +//! - \b IOC_MUX_OUT_SEL_SSI0_FSSOUT +//! - \b IOC_MUX_OUT_SEL_SSI0_STXSER_EN +//! - \b IOC_MUX_OUT_SEL_SSI1_TXD +//! - \b IOC_MUX_OUT_SEL_SSI1_CLKOUT +//! - \b IOC_MUX_OUT_SEL_SSI1_FSSOUT +//! - \b IOC_MUX_OUT_SEL_SSI1_STXSER_EN +//! - \b IOC_MUX_OUT_SEL_I2C_CMSSDA +//! - \b IOC_MUX_OUT_SEL_I2C_CMSSCL +//! - \b IOC_MUX_OUT_SEL_GPT0_ICP1 +//! - \b IOC_MUX_OUT_SEL_GPT0_ICP2 +//! - \b IOC_MUX_OUT_SEL_GPT1_ICP1 +//! - \b IOC_MUX_OUT_SEL_GPT1_ICP2 +//! - \b IOC_MUX_OUT_SEL_GPT2_ICP1 +//! - \b IOC_MUX_OUT_SEL_GPT2_ICP2 +//! - \b IOC_MUX_OUT_SEL_GPT3_ICP1 +//! - \b IOC_MUX_OUT_SEL_GPT3_ICP2 +//! +//! The pin(s) in \e ui8Pins are specified using a bit-packed byte, where each +//! bit that is set identifies the pin to be accessed, and where bit 0 of the +//! byte represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so +//! on. +//! +//! \return None +// +//***************************************************************************** +void +IOCPinConfigPeriphOutput(uint32_t ui32Port, uint8_t ui8Pins, + uint32_t ui32OutputSignal) +{ + uint32_t ui32PortAddr; + uint32_t ui32PinNo; + uint32_t ui32PinBit; + + // + // Check the arguments + // + ASSERT((ui32Port == GPIO_A_BASE) || (ui32Port == GPIO_B_BASE) || + (ui32Port == GPIO_C_BASE) || (ui32Port == GPIO_D_BASE)); + ASSERT(ui8Pins != 0); + + // + // Initialize to default value + // + ui32PortAddr = IOC_PA0_SEL; + + // + // Look for specified port pins to be configured, multiple pins are allowed + // + for(ui32PinNo = 0; ui32PinNo < 8; ui32PinNo++) + { + ui32PinBit = (ui8Pins >> ui32PinNo) & 0x00000001; + if(ui32PinBit != 0) + { + // + // Find register addresses for configuring specified port pin + // + switch(ui32Port) + { + case GPIO_A_BASE: + ui32PortAddr = g_pui32IOCPortASignSelectReg[ui32PinNo]; + break; + + case GPIO_B_BASE: + ui32PortAddr = g_pui32IOCPortBSignSelectReg[ui32PinNo]; + break; + + case GPIO_C_BASE: + ui32PortAddr = g_pui32IOCPortCSignSelectReg[ui32PinNo]; + break; + + case GPIO_D_BASE: + ui32PortAddr = g_pui32IOCPortDSignSelectReg[ui32PinNo]; + break; + + default: + // Default to port A pin 0 + ui32PortAddr = IOC_PA0_SEL; + break; + } + + // + // Set the mux for the desired port pin to select the desired + // peripheral output signal + // + HWREG(ui32PortAddr) = ui32OutputSignal; + } + } +} + +//***************************************************************************** +// +//! Mux the desired port pin to the desired on-chip peripheral input signal +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pin is the bit-packed representation of the desired port pin. +//! \param ui32PinSelectReg is the address of the IOC mux-register for the +//! desired peripheral input signal to which the desired port pin shall be +//! routed. +//! +//! This function routes the desired port pin to the desired on-chip +//! peripheral input signal. Functions are available within the GPIO device +//! driver that set the peripheral signal to be under hardware control and +//! configures the pin drive type on the desired port pin. +//! +//! The parameter \e ui32PinSelectReg is an enumerated data type that can be one +//! of the following values: +//! +//! - \b IOC_UARTRXD_UART0 +//! - \b IOC_UARTCTS_UART1 +//! - \b IOC_UARTRXD_UART1 +//! - \b IOC_CLK_SSI_SSI0 +//! - \b IOC_SSIRXD_SSI0 +//! - \b IOC_SSIFSSIN_SSI0 +//! - \b IOC_CLK_SSIIN_SSI0 +//! - \b IOC_CLK_SSI_SSI1 +//! - \b IOC_SSIRXD_SSI1 +//! - \b IOC_SSIFSSIN_SSI1 +//! - \b IOC_CLK_SSIIN_SSI1 +//! - \b IOC_I2CMSSDA +//! - \b IOC_I2CMSSCL +//! - \b IOC_GPT0OCP1 +//! - \b IOC_GPT0OCP2 +//! - \b IOC_GPT1OCP1 +//! - \b IOC_GPT1OCP2 +//! - \b IOC_GPT2OCP1 +//! - \b IOC_GPT2OCP2 +//! - \b IOC_GPT3OCP1 +//! - \b IOC_GPT3OCP2 +//! +//! The pin in ui8Pin is specified using a bit-packed byte, where the bit that +//! is set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return None +// +//***************************************************************************** +void +IOCPinConfigPeriphInput(uint32_t ui32Port, uint8_t ui8Pin, + uint32_t ui32PinSelectReg) +{ + uint32_t ui32PortPin; + + // + //Set initial values + // + ui32PortPin = IOC_PAD_IN_SEL_PA0; + + // + // Check the arguments + // + ASSERT((ui32Port == GPIO_A_BASE) || (ui32Port == GPIO_B_BASE) || + (ui32Port == GPIO_C_BASE) || (ui32Port == GPIO_D_BASE)); + ASSERT((ui8Pin == GPIO_PIN_0) || (ui8Pin == GPIO_PIN_1) || + (ui8Pin == GPIO_PIN_2) || (ui8Pin == GPIO_PIN_3) || + (ui8Pin == GPIO_PIN_4) || (ui8Pin == GPIO_PIN_5) || + (ui8Pin == GPIO_PIN_6) || (ui8Pin == GPIO_PIN_7)); + ASSERT((ui32PinSelectReg == IOC_UARTRXD_UART0) || + (ui32PinSelectReg == IOC_UARTCTS_UART1) || + (ui32PinSelectReg == IOC_UARTRXD_UART1) || + (ui32PinSelectReg == IOC_CLK_SSI_SSI0) || + (ui32PinSelectReg == IOC_SSIRXD_SSI0) || + (ui32PinSelectReg == IOC_SSIFSSIN_SSI0) || + (ui32PinSelectReg == IOC_CLK_SSIIN_SSI0) || + (ui32PinSelectReg == IOC_CLK_SSI_SSI1) || + (ui32PinSelectReg == IOC_SSIRXD_SSI1) || + (ui32PinSelectReg == IOC_SSIFSSIN_SSI1) || + (ui32PinSelectReg == IOC_CLK_SSIIN_SSI1) || + (ui32PinSelectReg == IOC_I2CMSSDA) || + (ui32PinSelectReg == IOC_I2CMSSCL) || + (ui32PinSelectReg == IOC_GPT0OCP1) || + (ui32PinSelectReg == IOC_GPT0OCP2) || + (ui32PinSelectReg == IOC_GPT1OCP1) || + (ui32PinSelectReg == IOC_GPT1OCP2) || + (ui32PinSelectReg == IOC_GPT2OCP1) || + (ui32PinSelectReg == IOC_GPT2OCP2) || + (ui32PinSelectReg == IOC_GPT3OCP1) || + (ui32PinSelectReg == IOC_GPT3OCP2)); + + switch(ui32Port) + { + case GPIO_A_BASE: + if(ui8Pin == GPIO_PIN_0) + { + ui32PortPin = IOC_PAD_IN_SEL_PA0; + } + if(ui8Pin == GPIO_PIN_1) + { + ui32PortPin = IOC_PAD_IN_SEL_PA1; + } + if(ui8Pin == GPIO_PIN_2) + { + ui32PortPin = IOC_PAD_IN_SEL_PA2; + } + if(ui8Pin == GPIO_PIN_3) + { + ui32PortPin = IOC_PAD_IN_SEL_PA3; + } + if(ui8Pin == GPIO_PIN_4) + { + ui32PortPin = IOC_PAD_IN_SEL_PA4; + } + if(ui8Pin == GPIO_PIN_5) + { + ui32PortPin = IOC_PAD_IN_SEL_PA5; + } + if(ui8Pin == GPIO_PIN_6) + { + ui32PortPin = IOC_PAD_IN_SEL_PA6; + } + if(ui8Pin == GPIO_PIN_7) + { + ui32PortPin = IOC_PAD_IN_SEL_PA7; + } + break; + + case GPIO_B_BASE: + if(ui8Pin == GPIO_PIN_0) + { + ui32PortPin = IOC_PAD_IN_SEL_PB0; + } + if(ui8Pin == GPIO_PIN_1) + { + ui32PortPin = IOC_PAD_IN_SEL_PB1; + } + if(ui8Pin == GPIO_PIN_2) + { + ui32PortPin = IOC_PAD_IN_SEL_PB2; + } + if(ui8Pin == GPIO_PIN_3) + { + ui32PortPin = IOC_PAD_IN_SEL_PB3; + } + if(ui8Pin == GPIO_PIN_4) + { + ui32PortPin = IOC_PAD_IN_SEL_PB4; + } + if(ui8Pin == GPIO_PIN_5) + { + ui32PortPin = IOC_PAD_IN_SEL_PB5; + } + if(ui8Pin == GPIO_PIN_6) + { + ui32PortPin = IOC_PAD_IN_SEL_PB6; + } + if(ui8Pin == GPIO_PIN_7) + { + ui32PortPin = IOC_PAD_IN_SEL_PB7; + } + break; + + case GPIO_C_BASE: + if(ui8Pin == GPIO_PIN_0) + { + ui32PortPin = IOC_PAD_IN_SEL_PC0; + } + if(ui8Pin == GPIO_PIN_1) + { + ui32PortPin = IOC_PAD_IN_SEL_PC1; + } + if(ui8Pin == GPIO_PIN_2) + { + ui32PortPin = IOC_PAD_IN_SEL_PC2; + } + if(ui8Pin == GPIO_PIN_3) + { + ui32PortPin = IOC_PAD_IN_SEL_PC3; + } + if(ui8Pin == GPIO_PIN_4) + { + ui32PortPin = IOC_PAD_IN_SEL_PC4; + } + if(ui8Pin == GPIO_PIN_5) + { + ui32PortPin = IOC_PAD_IN_SEL_PC5; + } + if(ui8Pin == GPIO_PIN_6) + { + ui32PortPin = IOC_PAD_IN_SEL_PC6; + } + if(ui8Pin == GPIO_PIN_7) + { + ui32PortPin = IOC_PAD_IN_SEL_PC7; + } + break; + + case GPIO_D_BASE: + if(ui8Pin == GPIO_PIN_0) + { + ui32PortPin = IOC_PAD_IN_SEL_PD0; + } + if(ui8Pin == GPIO_PIN_1) + { + ui32PortPin = IOC_PAD_IN_SEL_PD1; + } + if(ui8Pin == GPIO_PIN_2) + { + ui32PortPin = IOC_PAD_IN_SEL_PD2; + } + if(ui8Pin == GPIO_PIN_3) + { + ui32PortPin = IOC_PAD_IN_SEL_PD3; + } + if(ui8Pin == GPIO_PIN_4) + { + ui32PortPin = IOC_PAD_IN_SEL_PD4; + } + if(ui8Pin == GPIO_PIN_5) + { + ui32PortPin = IOC_PAD_IN_SEL_PD5; + } + if(ui8Pin == GPIO_PIN_6) + { + ui32PortPin = IOC_PAD_IN_SEL_PD6; + } + if(ui8Pin == GPIO_PIN_7) + { + ui32PortPin = IOC_PAD_IN_SEL_PD7; + } + break; + + default: + // Default to port A pin 0 + ui32PortPin = IOC_PAD_IN_SEL_PA0; + break; + } + + // + // Set the mux for the desired peripheral inputsignal to select the + // the desired port pin. + // + HWREG(ui32PinSelectReg) = ui32PortPin; +} + +//***************************************************************************** +// +//! Set desired drive type on the pad for the desired port pin(s). +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pins is the bit-packed representation of the port pin(s). +//! \param ui32PinDrive is the drive configuration of the desired port +//! pin. +//! +//! This function sets the desired pin drive type for the desired pin(s) +//! on the selected GPIO port. +//! +//! The \e ui32PinDrive parameter controls the configuration of the pin drive on +//! the pad for the desired pin(s). The parameter is the logical OR of any of +//! the following: +//! +//! - \b IOC_OVERRIDE_OE +//! - \b IOC_OVERRIDE_PUE +//! - \b IOC_OVERRIDE_PDE +//! - \b IOC_OVERRIDE_ANA +//! - \b IOC_OVERRIDE_DIS +//! +//! where \b IOC_OVERRIDE_OE is the output enable bit connected directly +//! to the output enable pin for the IO driver cell, after it is ORed +//! with any OE signal from the desired peripheral. The OE is driven from the +//! SSI, I2C and GPT peripherals. \b IOC_OVERRIDE_PUE is the enable bit for +//! the pull-up. \b IOC_OVERRIDE_PDE is the enable bit for the pull-down. +//! \b IOC_OVERRIDE_ANA must be set for the analog signal. +//! +//! The pin(s) in \e ui8Pins are specified using a bit-packed byte, where each +//! bit that is set identifies the pin to be accessed, and where bit 0 of the +//! byte represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so +//! on. +//! +//! \note PC0 through PC3 are bidirectional high-drive pad-cells. They do not +//! support on-die pullup or pulldown resistors or analog connectivity. +//! For these four pins the \e ui32PinDrive parameter must be set to either +//! \b IOC_OVERRIDE_OE or IOC_OVERRIDE_DIS. +//! +//! \return None +// +//***************************************************************************** +void +IOCPadConfigSet(uint32_t ui32Port, uint8_t ui8Pins, + uint32_t ui32PinDrive) +{ + uint32_t ui32OverrideRegAddr; + uint32_t ui32PinNo; + uint32_t ui32PinBit; + + // + // Check the arguments + // + ASSERT((ui32Port == GPIO_A_BASE) || (ui32Port == GPIO_B_BASE) || + (ui32Port == GPIO_C_BASE) || (ui32Port == GPIO_D_BASE)); + ASSERT(ui8Pins != 0); + ASSERT((ui32PinDrive == IOC_OVERRIDE_OE) || + (ui32PinDrive == IOC_OVERRIDE_PUE) || + (ui32PinDrive == IOC_OVERRIDE_PDE) || + (ui32PinDrive == IOC_OVERRIDE_ANA) || + (ui32PinDrive == IOC_OVERRIDE_DIS)); + // + // PC0-PC3 does not support on-die pullup, pulldown or analog connectivity. + // + ASSERT(!((ui32Port == GPIO_C_BASE) && ((ui8Pins & 0xf) > 0) && + ((ui32PinDrive == IOC_OVERRIDE_PUE) || + (ui32PinDrive == IOC_OVERRIDE_PDE) || + (ui32PinDrive == IOC_OVERRIDE_ANA)))); + + // + // Initialize to default value + // + ui32OverrideRegAddr = IOC_PA0_SEL; + + // + // Look for specified port pins to be configured, multiple pins are allowed + // + for(ui32PinNo = 0; ui32PinNo < 8; ui32PinNo++) + { + ui32PinBit = (ui8Pins >> ui32PinNo) & 0x00000001; + if(ui32PinBit != 0) + { + // + // Find register addresses for configuring specified port pin + // + switch(ui32Port) + { + case GPIO_A_BASE: + ui32OverrideRegAddr = g_pui32IOCPortAOverrideReg[ui32PinNo]; + break; + + case GPIO_B_BASE: + ui32OverrideRegAddr = g_pui32IOCPortBOverrideReg[ui32PinNo]; + break; + + case GPIO_C_BASE: + ui32OverrideRegAddr = g_pui32IOCPortCOverrideReg[ui32PinNo]; + break; + + case GPIO_D_BASE: + ui32OverrideRegAddr = g_pui32IOCPortDOverrideReg[ui32PinNo]; + break; + + default: + // Default to port A pin 0 + ui32OverrideRegAddr = IOC_PA0_OVER; + break; + } + + // + // Set desired pin drive for the desired port pin + // + HWREG(ui32OverrideRegAddr) = ui32PinDrive; + } + } +} + +//***************************************************************************** +// +//! Get drive type on the pad for the desired port pin. +//! +//! \param ui32Port is the base address of the GPIO port. +//! \param ui8Pin is the bit-packed representation of the port pin. +//! +//! This function returns the configured pin drive type for the desired +//! pin on the selected GPIO port. +//! +//! The pin in \e ui8Pin is specified using a bit-packed byte, where the bit +//! that is set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, and so on. +//! +//! \return Returns the logical OR of the enumerated data types described for +//! \e ui32PinDrive parameter in IOCPadConfigSet(). +//! +//! \sa IOCPadConfigSet() +// +//***************************************************************************** +uint32_t +IOCPadConfigGet(uint32_t ui32Port, uint8_t ui8Pin) +{ + uint32_t ui32OverrideRegAddr; + + // + //Set initial values + // + ui32OverrideRegAddr = IOC_PA0_OVER; + + // + // Check the arguments + // + ASSERT((ui32Port == GPIO_A_BASE) || (ui32Port == GPIO_B_BASE) || + (ui32Port == GPIO_C_BASE) || (ui32Port == GPIO_D_BASE)); + ASSERT((ui8Pin == GPIO_PIN_0) || (ui8Pin == GPIO_PIN_1) || + (ui8Pin == GPIO_PIN_2) || (ui8Pin == GPIO_PIN_3) || + (ui8Pin == GPIO_PIN_4) || (ui8Pin == GPIO_PIN_5) || + (ui8Pin == GPIO_PIN_6) || (ui8Pin == GPIO_PIN_7)); + + // + // Find the address of the override register for the desired pin + // + switch(ui32Port) + { + case GPIO_A_BASE: + if(ui8Pin == GPIO_PIN_0) + { + ui32OverrideRegAddr = IOC_PA0_OVER; + } + if(ui8Pin == GPIO_PIN_1) + { + ui32OverrideRegAddr = IOC_PA1_OVER; + } + if(ui8Pin == GPIO_PIN_2) + { + ui32OverrideRegAddr = IOC_PA2_OVER; + } + if(ui8Pin == GPIO_PIN_3) + { + ui32OverrideRegAddr = IOC_PA3_OVER; + } + if(ui8Pin == GPIO_PIN_4) + { + ui32OverrideRegAddr = IOC_PA4_OVER; + } + if(ui8Pin == GPIO_PIN_5) + { + ui32OverrideRegAddr = IOC_PA5_OVER; + } + if(ui8Pin == GPIO_PIN_6) + { + ui32OverrideRegAddr = IOC_PA6_OVER; + } + if(ui8Pin == GPIO_PIN_7) + { + ui32OverrideRegAddr = IOC_PA7_OVER; + } + break; + + case GPIO_B_BASE: + if(ui8Pin == GPIO_PIN_0) + { + ui32OverrideRegAddr = IOC_PB0_OVER; + } + if(ui8Pin == GPIO_PIN_1) + { + ui32OverrideRegAddr = IOC_PB1_OVER; + } + if(ui8Pin == GPIO_PIN_2) + { + ui32OverrideRegAddr = IOC_PB2_OVER; + } + if(ui8Pin == GPIO_PIN_3) + { + ui32OverrideRegAddr = IOC_PB3_OVER; + } + if(ui8Pin == GPIO_PIN_4) + { + ui32OverrideRegAddr = IOC_PB4_OVER; + } + if(ui8Pin == GPIO_PIN_5) + { + ui32OverrideRegAddr = IOC_PB5_OVER; + } + if(ui8Pin == GPIO_PIN_6) + { + ui32OverrideRegAddr = IOC_PB6_OVER; + } + if(ui8Pin == GPIO_PIN_7) + { + ui32OverrideRegAddr = IOC_PB7_OVER; + } + break; + + case GPIO_C_BASE: + if(ui8Pin == GPIO_PIN_0) + { + ui32OverrideRegAddr = IOC_PC0_OVER; + } + if(ui8Pin == GPIO_PIN_1) + { + ui32OverrideRegAddr = IOC_PC1_OVER; + } + if(ui8Pin == GPIO_PIN_2) + { + ui32OverrideRegAddr = IOC_PC2_OVER; + } + if(ui8Pin == GPIO_PIN_3) + { + ui32OverrideRegAddr = IOC_PC3_OVER; + } + if(ui8Pin == GPIO_PIN_4) + { + ui32OverrideRegAddr = IOC_PC4_OVER; + } + if(ui8Pin == GPIO_PIN_5) + { + ui32OverrideRegAddr = IOC_PC5_OVER; + } + if(ui8Pin == GPIO_PIN_6) + { + ui32OverrideRegAddr = IOC_PC6_OVER; + } + if(ui8Pin == GPIO_PIN_7) + { + ui32OverrideRegAddr = IOC_PC7_OVER; + } + break; + + case GPIO_D_BASE: + if(ui8Pin == GPIO_PIN_0) + { + ui32OverrideRegAddr = IOC_PD0_OVER; + } + if(ui8Pin == GPIO_PIN_1) + { + ui32OverrideRegAddr = IOC_PD1_OVER; + } + if(ui8Pin == GPIO_PIN_2) + { + ui32OverrideRegAddr = IOC_PD2_OVER; + } + if(ui8Pin == GPIO_PIN_3) + { + ui32OverrideRegAddr = IOC_PD3_OVER; + } + if(ui8Pin == GPIO_PIN_4) + { + ui32OverrideRegAddr = IOC_PD4_OVER; + } + if(ui8Pin == GPIO_PIN_5) + { + ui32OverrideRegAddr = IOC_PD5_OVER; + } + if(ui8Pin == GPIO_PIN_6) + { + ui32OverrideRegAddr = IOC_PD6_OVER; + } + if(ui8Pin == GPIO_PIN_7) + { + ui32OverrideRegAddr = IOC_PD7_OVER; + } + break; + + default: + // Default to port A pin 0 + ui32OverrideRegAddr = IOC_PA0_OVER; + break; + } + + // + // Return pin drive type + // + return(HWREG(ui32OverrideRegAddr)); +} +//***************************************************************************** +// +//! Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/ioc.h b/bsp/boards/mimsy2-cc2538/source/ioc.h new file mode 100644 index 0000000000..f5b450a854 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/ioc.h @@ -0,0 +1,139 @@ +/****************************************************************************** +* Filename: ioc.h +* Revised: $Date: 2013-01-21 15:25:21 +0100 (Mon, 21 Jan 2013) $ +* Revision: $Revision: 9178 $ +* +* Description: Prototypes for the I/O driver. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __IOC_H__ +#define __IOC_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// The following values define the bit field for the ui8Pins and ui8Pin arguments +// to all of the APIs. +// +//***************************************************************************** +#define IOC_PIN_0 0x00000001 // IO pin 0 +#define IOC_PIN_1 0x00000002 // IO pin 1 +#define IOC_PIN_2 0x00000004 // IO pin 2 +#define IOC_PIN_3 0x00000008 // IO pin 3 +#define IOC_PIN_4 0x00000010 // IO pin 4 +#define IOC_PIN_5 0x00000020 // IO pin 5 +#define IOC_PIN_6 0x00000040 // IO pin 6 +#define IOC_PIN_7 0x00000080 // IO pin 7 + +//***************************************************************************** +// +// Defined values for the ui32OutputSignal parameter of the +// IOCPinConfigPeriphOutput() function. These are the valid values for the +// signal select registers. +// (The registers are in the addr range: IOC_PA0 - IOC_PD7). +// +//***************************************************************************** +#define IOC_MUX_OUT_SEL_UART0_TXD 0x00000000 // iuarttxd_uart0 +#define IOC_MUX_OUT_SEL_UART1_RTS 0x00000001 // iuartrts_uart1 +#define IOC_MUX_OUT_SEL_UART1_TXD 0x00000002 // iuarttxd_uart1 +#define IOC_MUX_OUT_SEL_SSI0_TXD 0x00000003 // issitxd_ssi0 +#define IOC_MUX_OUT_SEL_SSI0_CLKOUT 0x00000004 // issiclkout_ssi0 +#define IOC_MUX_OUT_SEL_SSI0_FSSOUT 0x00000005 // issifssout_ssi0 +#define IOC_MUX_OUT_SEL_SSI0_STXSER_EN 0x00000006 // istxser_en_ssi0 +#define IOC_MUX_OUT_SEL_SSI1_TXD 0x00000007 // issitxd_ssi1 +#define IOC_MUX_OUT_SEL_SSI1_CLKOUT 0x00000008 // issiclkout_ssi1 +#define IOC_MUX_OUT_SEL_SSI1_FSSOUT 0x00000009 // issifssout_ssi1 +#define IOC_MUX_OUT_SEL_SSI1_STXSER_EN 0x0000000A // istxser_en_ssi1 +#define IOC_MUX_OUT_SEL_I2C_CMSSDA 0x0000000B // ii2cmssda +#define IOC_MUX_OUT_SEL_I2C_CMSSCL 0x0000000C // ii2cmsscl +#define IOC_MUX_OUT_SEL_GPT0_ICP1 0x0000000D // gpt0icp1 +#define IOC_MUX_OUT_SEL_GPT0_ICP2 0x0000000E // gpt0icp2 +#define IOC_MUX_OUT_SEL_GPT1_ICP1 0x0000000F // gpt1icp1 +#define IOC_MUX_OUT_SEL_GPT1_ICP2 0x00000010 // gpt1icp2 +#define IOC_MUX_OUT_SEL_GPT2_ICP1 0x00000011 // gpt2icp1 +#define IOC_MUX_OUT_SEL_GPT2_ICP2 0x00000012 // gpt2icp2 +#define IOC_MUX_OUT_SEL_GPT3_ICP1 0x00000013 // gpt3icp1 +#define IOC_MUX_OUT_SEL_GPT3_ICP2 0x00000014 // gpt3icp2 + +//***************************************************************************** +// +// Defined bits in the value for the pin drive type returned by the +// IOCPadConfigGet() function and used in the ui32PinDrive parameter for the +// IOCPadConfigSet() function. +// +//***************************************************************************** +#define IOC_OVERRIDE_DIS 0x00000000 // PAD Config Override Disabled +#define IOC_OVERRIDE_ANA 0x00000001 // PAD Config Override Analog Enable +#define IOC_OVERRIDE_PDE 0x00000002 // PAD Config Override Pull Down Enable +#define IOC_OVERRIDE_PUE 0x00000004 // PAD Config Override Pull Up Enable +#define IOC_OVERRIDE_OE 0x00000008 // PAD Config Override Output Enable + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void IOCPinConfigPeriphOutput(uint32_t ui32Port, + uint8_t ui8Pins, + uint32_t ui32OutputSignal); +extern void IOCPinConfigPeriphInput(uint32_t ui32Port, + uint8_t ui8Pin, + uint32_t ui32PinSelectReg); +extern void IOCPadConfigSet(uint32_t ui32Port, uint8_t ui8Pins, + uint32_t ui32PinDrive); +extern uint32_t IOCPadConfigGet(uint32_t ui32Port, + uint8_t ui8Pin); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __IOC_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/pka.c b/bsp/boards/mimsy2-cc2538/source/pka.c new file mode 100644 index 0000000000..7af58767c8 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/pka.c @@ -0,0 +1,1987 @@ +/****************************************************************************** +* Filename: pka.c +* Revised: $Date: 2012-10-01 11:15:04 -0700 (Mon, 01 Oct 2012) $ +* Revision: $Revision: 31660 $ +* +* Description: Driver for the PKA HW module. +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup pka_driver +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include +#include "interrupt.h" +#include "pka.h" +#include "sys_ctrl.h" +#include "debug.h" + +//***************************************************************************** +// +// Macro definition for NULL +// +//***************************************************************************** + +#ifndef NULL +#define NULL ((void*)0) +#endif + +//***************************************************************************** +// +// Define for the maximum curve size supported by the PKA module in 32 bit +// word. +// \note PKA hardware module can support upto 384 bit curve size due to the +// 2K of PKA RAM. +// +//***************************************************************************** +#define PKA_MAX_CURVE_SIZE_32_BIT_WORD \ + 12 + +//***************************************************************************** +// +// Define for the maximum length of the big number supported by the PKA module +// in 32 bit word. +// +//***************************************************************************** +#define PKA_MAX_LEN_IN_32_BIT_WORD \ + PKA_MAX_CURVE_SIZE_32_BIT_WORD + +//***************************************************************************** +// +// Define for the PKA RAM size. +// +//**************************************************************************** +#define PKA_RAM_SIZE 2000 + + +//***************************************************************************** +// +//! Enables the PKA interrupt. +//! +//! This function enables the PKA interrupt. +//! +//! \return None. +// +//***************************************************************************** +void +PKAEnableInt(void) +{ + // + // Enable the PKA interrupt. + // + IntEnable(INT_PKA); +} + +//***************************************************************************** +// +//! Disables the PKA interrupt. +//! +//! This function disables the PKA interrupt. +//! +//! \return None. +// +//***************************************************************************** +void +PKADisableInt( void ) +{ + // + // Disables the PKA interrupt. + // + IntDisable(INT_PKA); +} + +//***************************************************************************** +// +//! Clears the PKA interrupt. +//! +//! This function unpends PKA interrupt. This will cause any previously +//! generated PKA interrupts that have not been handled yet to be discarded. +//! +//! \return None. +// +//***************************************************************************** +void +PKAClearInt(void) +{ + // + // UnPends the PKA interrupt. + // + IntPendClear(INT_PKA); +} + +//***************************************************************************** +// +//! Registers an interrupt handler for PKA interrupt. +//! +//! \param pfnHandler is a pointer to the function to be called when the +//! PKA interrupt occurs. +//! +//! This function does the actual registering of the interrupt handler. This +//! will not enable the PKA interrupt in the interrupt controller, a call to +//! the function \sa PKAEnableInt() is needed to enable the PKA interrupt. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +void +PKARegInt(void (*pfnHandler)(void)) +{ + // + // Register the interrupt handler. + // + IntRegister(INT_PKA, pfnHandler); +} + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the PKA interrupt. +//! +//! This function deregisters the interrupt service routine. This function +//! will not disable the interrupt and an explicit call to \sa PKADisableInt() +//! is needed. +//! +//! \return None. +// +//***************************************************************************** +void +PKAUnRegInt(void) +{ + // + // Unregister the interrupt handler. + // + IntUnregister(INT_PKA); +} + +//***************************************************************************** +// +//! Provides the PKA operation status. +//! +//! This function provides information on whether any PKA operation is in +//! progress or not. This function allows to check the PKA operation status +//! before starting any new PKA operation. +//! +//! \return Returns: +//! - \b PKA_STATUS_INPRG if the PKA operation is in progress. +//! - \b PKA_STATUS_OPERATION_NOT_INPRG if the PKA operation is not in progress. +// +//***************************************************************************** +tPKAStatus +PKAGetOpsStatus(void) +{ + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + else + { + return (PKA_STATUS_OPERATION_NOT_INPRG); + } +} + +//***************************************************************************** +// +//! Starts the big number modulus operation. +//! +//! \param pui32BNum is the pointer to the big number on which modulo operation +//! needs to be carried out. +//! \param ui8BNSize is the size of the big number \sa pui32BNum in 32-bit +//! word. +//! \param pui32Modulus is the pointer to the divisor. +//! \param ui8ModSize is the size of the divisor \sa pui32Modulus. +//! \param pui32ResultVector is the pointer to the result vector location +//! which will be set by this function. +//! +//! This function starts the modulo operation on the big num \sa pui32BNum +//! using the divisor \sa pui32Modulus. The PKA RAM location where the result +//! will be available is stored in \sa pui32ResultVector. +//! +//!\return Returns: +//! - \b PKA_STATUS_SUCCESS if successful in starting the operation. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy doing +//! some other operation. +// +//***************************************************************************** +tPKAStatus +PKABigNumModStart(uint32_t* pui32BNum, uint8_t ui8BNSize, + uint32_t* pui32Modulus, uint8_t ui8ModSize, + uint32_t* pui32ResultVector) +{ + uint8_t extraBuf; + uint32_t offset; + int i; + + // + // Check the arguments. + // + ASSERT(NULL != pui32BNum); + ASSERT(NULL != pui32Modulus); + ASSERT(NULL != pui32ResultVector); + + // + // make sure no operation is in progress. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // calculate the extra buffer requirement. + // + extraBuf = 2 + ui8ModSize % 2; + + offset = 0; + + // + // Update the A ptr with the offset address of the PKA RAM location + // where the number will be stored. + // + HWREG( (PKA_APTR) ) = offset >>2; + + // + // Load the number in PKA RAM + // + for(i = 0; i < ui8BNSize; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = pui32BNum[i]; + } + + // + // determine the offset for the next data input. + // + offset += 4 * (i + ui8BNSize % 2); + + // + // Update the B ptr with the offset address of the PKA RAM location + // where the divisor will be stored. + // + HWREG( (PKA_BPTR) ) = offset >> 2; + + // + // Load the divisor in PKA RAM. + // + for(i = 0; i < ui8ModSize; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = pui32Modulus[i]; + } + + // + // determine the offset for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Copy the result vector address location. + // + *pui32ResultVector = PKA_RAM_BASE + offset; + + // + // Load C ptr with the result location in PKA RAM + // + HWREG( (PKA_CPTR) ) = offset >> 2; + + // + // Load A length registers with Big number length in 32 bit words. + // + HWREG( (PKA_ALENGTH) ) = ui8BNSize; + + // + // Load B length registers Divisor length in 32-bit words. + // + HWREG( (PKA_BLENGTH) ) = ui8ModSize; + + // + // Start the PKCP modulo operation by setting the PKA Function register. + // + HWREG( (PKA_FUNCTION) ) = (PKA_FUNCTION_RUN | PKA_FUNCTION_MODULO); + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Gets the result of the big number modulus operation. +//! +//! \param pui32ResultBuf is the pointer to buffer where the result needs to +//! be stored. +//! \param ui8Size is the size of the provided buffer in 32 bit size word. +//! \param ui32ResVectorLoc is the address of the result location which +//! was provided by the start function \sa PKABigNumModStart(). +//! +//! This function gets the result of the big number modulus operation which was +//! previously started using the function \sa PKABigNumModStart(). +//! +//! \return Returns: +//! - \b PKA_STATUS_SUCCESS if successful. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy doing +//! the operation. +//! - \b PKA_STATUS_RESULT_0 if the result is all zeroes. +//! - \b PKA_STATUS_BUF_UNDERFLOW, if the \e ui8Size is less than the length +//! of the result. +// +//***************************************************************************** +tPKAStatus +PKABigNumModGetResult(uint32_t* pui32ResultBuf,uint8_t ui8Size, + uint32_t ui32ResVectorLoc) +{ + uint32_t regMSWVal; + uint32_t len; + int i; + + // + // Check the arguments. + // + ASSERT(NULL != pui32ResultBuf); + ASSERT((ui32ResVectorLoc > PKA_RAM_BASE) && + (ui32ResVectorLoc < (PKA_RAM_BASE + PKA_RAM_SIZE))); + + // + // verify that the operation is complete. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Get the MSW register value. + // + regMSWVal = HWREG(PKA_DIVMSW); + + // + // Check to make sure that the result vector is not all zeroes. + // + if(regMSWVal & PKA_DIVMSW_RESULT_IS_ZERO) + { + return (PKA_STATUS_RESULT_0); + } + + // + // Get the length of the result. + // + len = ((regMSWVal & PKA_DIVMSW_MSW_ADDRESS_M) + 1) - + ((ui32ResVectorLoc - PKA_RAM_BASE) >> 2); + + // + // If the size of the buffer provided is less than the result length than + // return error. + // + if(ui8Size < len) + { + return (PKA_STATUS_BUF_UNDERFLOW); + } + + // + // copy the result from vector C into the pResult. + // + for(i = 0; i < len; i++) + { + pui32ResultBuf[i]= HWREG( (ui32ResVectorLoc + 4*i) ); + } + + return (PKA_STATUS_SUCCESS); +} // PKABigNumModGetResult() + +//***************************************************************************** +// +//! Starts the comparison of two big numbers. +//! +//! \param pui32BNum1 is the pointer to the first big number. +//! \param pui32BNum2 is the pointer to the second big number. +//! \param ui8Size is the size of the big number in 32 bit size word. +//! +//! This function starts the comparison of two big numbers pointed by +//! \e pui32BNum1 and \e pui32BNum2. +//! Note this function expects the size of the two big numbers equal. +//! +//!\return Returns: +//! - \b PKA_STATUS_SUCCESS if successful in starting the operation. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy doing +//! some other operation. +// +//***************************************************************************** +tPKAStatus +PKABigNumCmpStart(uint32_t* pui32BNum1, uint32_t* pui32BNum2, uint8_t ui8Size) +{ + uint32_t offset; + int i; + + // + // Check the arguments. + // + ASSERT(NULL != pui32BNum1); + ASSERT(NULL != pui32BNum2); + + offset = 0; + + // + // Make sure no operation is in progress. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Update the A ptr with the offset address of the PKA RAM location + // where the first big number will be stored. + // + HWREG( (PKA_APTR) ) = offset >> 2; + + // + // Load the first big number in PKA RAM. + // + for(i = 0; i < ui8Size; i++) + { + HWREG( (PKA_RAM_BASE + offset + 4*i) ) = pui32BNum1[i]; + } + + // + // Determine the offset in PKA RAM for the next pointer. + // + offset += 4 * (i + ui8Size % 2); + + // + // Update the B ptr with the offset address of the PKA RAM location + // where the second big number will be stored. + // + HWREG( (PKA_BPTR) ) = offset >> 2; + + // + // Load the second big number in PKA RAM. + // + for(i = 0; i < ui8Size; i++) + { + HWREG( (PKA_RAM_BASE + offset + 4*i) ) = pui32BNum2[i]; + } + + // + // Load length registers in 32 bit word size. + // + HWREG( (PKA_ALENGTH) ) = ui8Size; + + // + // Set the PKA Function register for the Compare operation + // and start the operation. + // + HWREG( (PKA_FUNCTION) ) = (PKA_FUNCTION_RUN | PKA_FUNCTION_COMPARE); + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Gets the result of the comparison operation of two big numbers. +//! +//! This function provides the results of the comparison of two big numbers +//! which was started using the \sa PKABigNumCmpStart(). +//! +//! \return Returns: +//! - \b PKA_STATUS_OPERATION_INPRG if the operation is in progress. +//! - \b PKA_STATUS_SUCCESS if the two big numbers are equal. +//! - \b PKA_STATUS_A_GR_B if the first number is greater than the second. +//! - \b PKA_STATUS_A_LT_B if the first number is less than the second. +// +//***************************************************************************** +tPKAStatus +PKABigNumCmpGetResult(void) +{ + tPKAStatus status; + + // + // verify that the operation is complete. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + status = PKA_STATUS_OPERATION_INPRG; + return (status); + } + + // + // Check the COMPARE register. + // + switch(HWREG(PKA_COMPARE)) + { + case PKA_COMPARE_A_EQUALS_B: + status = PKA_STATUS_SUCCESS; + break; + + case PKA_COMPARE_A_GREATER_THAN_B: + status = PKA_STATUS_A_GR_B; + break; + + case PKA_COMPARE_A_LESS_THAN_B: + status = PKA_STATUS_A_LT_B; + break; + + default: + status = PKA_STATUS_FAILURE; + break; + } + + return (status); +} + +//***************************************************************************** +// +//! Starts the big number inverse modulo operation. +//! +//! \param pui32BNum is the pointer to the buffer containing the big number +//! (dividend). +//! \param ui8BNSize is the size of the \e pui32BNum in 32 bit word. +//! \param pui32Modulus is the pointer to the buffer containing the divisor. +//! \param ui8Size is the size of the divisor in 32 bit word. +//! \param pui32ResultVector is the pointer to the result vector location +//! which will be set by this function. +//! +//! This function starts the the inverse modulo operation on \e pui32BNum +//! using the divisor \e pui32Modulus. +//! +//!\return Returns: +//! - \b PKA_STATUS_SUCCESS if successful in starting the operation. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy doing +//! some other operation. +// +//***************************************************************************** +tPKAStatus +PKABigNumInvModStart(uint32_t* pui32BNum, uint8_t ui8BNSize, + uint32_t* pui32Modulus, uint8_t ui8Size, + uint32_t* pui32ResultVector) +{ + uint32_t offset; + int i; + + // + // Check the arguments. + // + ASSERT(NULL != pui32BNum); + ASSERT(NULL != pui32Modulus); + ASSERT(NULL != pui32ResultVector); + + offset = 0; + + // + // Make sure no operation is in progress. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Update the A ptr with the offset address of the PKA RAM location + // where the number will be stored. + // + HWREG( (PKA_APTR) ) = offset >>2; + + // + // Load the \e pui32BNum number in PKA RAM. + // + for(i = 0; i < ui8BNSize; i++) + { + HWREG( (PKA_RAM_BASE + offset + 4*i) ) = pui32BNum[i]; + } + + // + // Determine the offset for next data. + // + offset += 4 * (i + ui8BNSize % 2); + + // + // Update the B ptr with the offset address of the PKA RAM location + // where the modulus will be stored. + // + HWREG( (PKA_BPTR) ) = offset >> 2; + + // + // Load the \e pui32Modulus divisor in PKA RAM. + // + for(i = 0; i < ui8Size; i++) + { + HWREG( (PKA_RAM_BASE + offset + 4*i) ) = pui32Modulus[i]; + } + + // + // Determine the offset for result data. + // + offset += 4 * (i + ui8Size % 2); + + // + // Copy the result vector address location. + // + *pui32ResultVector = PKA_RAM_BASE + offset; + + // + // Load D ptr with the result location in PKA RAM. + // + HWREG( (PKA_DPTR) ) = offset >> 2; + + // + // Load the respective length registers. + // + HWREG( (PKA_ALENGTH) ) = ui8BNSize; + HWREG( (PKA_BLENGTH) ) = ui8Size; + + // + // set the PKA function to InvMod operation and the start the operation. + // + HWREG( (PKA_FUNCTION) ) = 0x0000F000; + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Gets the result of the big number inverse modulo operation. +//! +//! \param pui32ResultBuf is the pointer to buffer where the result needs to be +//! stored. +//! \param ui8Size is the size of the provided buffer in 32 bit ui8Size +//! word. +//! \param ui32ResVectorLoc is the address of the result location which +//! was provided by the start function \sa PKABigNumInvModStart(). +//! +//! This function gets the result of the big number inverse modulo operation +//! previously started using the function \sa PKABigNumInvModStart(). +//! +//! \return Returns: +//! - \b PKA_STATUS_SUCCESS if the operation is successful. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy performing +//! the operation. +//! - \b PKA_STATUS_RESULT_0 if the result is all zeroes. +//! - \b PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less +//! then the result. +// +//***************************************************************************** +tPKAStatus +PKABigNumInvModGetResult(uint32_t* pui32ResultBuf, uint8_t ui8Size, + uint32_t ui32ResVectorLoc) +{ + uint32_t regMSWVal; + uint32_t len; + int i; + + // + // Check the arguments. + // + ASSERT(NULL != pui32ResultBuf); + ASSERT((ui32ResVectorLoc > PKA_RAM_BASE) && + (ui32ResVectorLoc < (PKA_RAM_BASE + PKA_RAM_SIZE))); + + // + // Verify that the operation is complete. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Get the MSW register value. + // + regMSWVal = HWREG(PKA_MSW); + + // + // Check to make sure that the result vector is not all zeroes. + // + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) + { + return (PKA_STATUS_RESULT_0); + } + + // + // Get the length of the result + // + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) - + ((ui32ResVectorLoc - PKA_RAM_BASE) >> 2); + + // + // Check if the provided buffer length is adequate to store the result + // data. + // + if(ui8Size < len) + { + return (PKA_STATUS_BUF_UNDERFLOW); + } + + // + // Copy the result from vector C into the \e pui32ResultBuf. + for(i = 0; i < len; i++) + { + pui32ResultBuf[i]= HWREG( (ui32ResVectorLoc + 4*i) ); + } + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Starts the big number multiplication. +//! +//! \param pui32Xplicand is the pointer to the buffer containing the big +//! number multiplicand. +//! \param ui8XplicandSize is the size of the multiplicand in 32-bit word. +//! \param pui32Xplier is the pointer to the buffer containing the big +//! number multiplier. +//! \param ui8XplierSize is the size of the multiplier in 32-bit word. +//! \param pui32ResultVector is the pointer to the result vector location +//! which will be set by this function. +//! +//! This function starts the multiplication of the two big numbers. +//! +//!\return Returns: +//! - \b PKA_STATUS_SUCCESS if successful in starting the operation. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy doing +//! some other operation. +// +//***************************************************************************** +tPKAStatus +PKABigNumMultiplyStart(uint32_t* pui32Xplicand, uint8_t ui8XplicandSize, + uint32_t* pui32Xplier, uint8_t ui8XplierSize, + uint32_t* pui32ResultVector) +{ + uint32_t offset; + int i; + + // + // Check for the arguments. + // + ASSERT(NULL != pui32Xplicand); + ASSERT(NULL != pui32Xplier); + ASSERT(NULL != pui32ResultVector); + + offset = 0; + + // + // Make sure no operation is in progress. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Update the A ptr with the offset address of the PKA RAM location + // where the multiplicand will be stored. + // + HWREG( (PKA_APTR) ) = offset >> 2; + + // + // Load the multiplicand in PKA RAM. + // + for(i = 0; i < ui8XplicandSize; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = *pui32Xplicand; + pui32Xplicand++; + } + + // + // Determine the offset for the next data. + // + offset += 4 * (i + (ui8XplicandSize % 2)); + + // + // Update the B ptr with the offset address of the PKA RAM location + // where the multiplier will be stored. + // + HWREG( (PKA_BPTR) ) = offset >> 2; + + // + // Load the multiplier in PKA RAM. + // + for(i = 0; i < ui8XplierSize; i++) + { + HWREG( (PKA_RAM_BASE + offset + 4*i) ) = *pui32Xplier; + pui32Xplier++; + } + + // + // Determine the offset for the next data. + // + offset += 4 * (i + (ui8XplierSize % 2)); + + // + // Copy the result vector address location. + // + *pui32ResultVector = PKA_RAM_BASE + offset; + + // + // Load C ptr with the result location in PKA RAM. + // + HWREG( (PKA_CPTR) ) = offset >> 2; + + // + // Load the respective length registers. + // + HWREG( (PKA_ALENGTH) ) = ui8XplicandSize; + HWREG( (PKA_BLENGTH) ) = ui8XplierSize; + + // + // Set the PKA function to the multiplication and start it. + // + HWREG( (PKA_FUNCTION) ) = (PKA_FUNCTION_RUN | PKA_FUNCTION_MULTIPLY); + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Gets the results of the big number multiplication. +//! +//! \param pui32ResultBuf is the pointer to buffer where the result needs to be +//! stored. +//! \param pui32Len is the address of the variable containing the length of the +//! buffer. After the operation, the actual length of the resultant is stored +//! at this address. +//! \param ui32ResVectorLoc is the address of the result location which +//! was provided by the start function \sa PKABigNumMultiplyStart(). +//! +//! This function gets the result of the multiplication of two big numbers +//! operation previously started using the function \sa +//! PKABigNumMultiplyStart(). +//! +//! \return Returns: +//! - \b PKA_STATUS_SUCCESS if the operation is successful. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy performing +//! the operation. +//! - \b PKA_STATUS_RESULT_0 if the result is all zeroes. +//! - \b PKA_STATUS_FAILURE if the operation is not successful. +//! - \b PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less +//! then the length of the result. +// +//***************************************************************************** +tPKAStatus +PKABigNumMultGetResult(uint32_t* pui32ResultBuf, uint32_t* pui32Len, + uint32_t ui32ResVectorLoc) +{ + uint32_t regMSWVal; + uint32_t len; + int i; + + // + // Check for arguments. + // + ASSERT(NULL != pui32ResultBuf); + ASSERT(NULL != pui32Len); + ASSERT((ui32ResVectorLoc > PKA_RAM_BASE) && + (ui32ResVectorLoc < (PKA_RAM_BASE + PKA_RAM_SIZE))); + + // + // Verify that the operation is complete. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Get the MSW register value. + // + regMSWVal = HWREG(PKA_MSW); + + // + // Check to make sure that the result vector is not all zeroes. + // + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) + { + return (PKA_STATUS_RESULT_0); + } + + // + // Get the length of the result. + // + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) - + ((ui32ResVectorLoc - PKA_RAM_BASE) >> 2); + + // + // Make sure that the length of the supplied result buffer is adequate + // to store the resultant. + // + if(*pui32Len < len) + { + return (PKA_STATUS_BUF_UNDERFLOW); + } + + // + // Copy the resultant length. + // + *pui32Len = len; + + // + // Copy the result from vector C into the pResult. + // + for(i = 0; i < *pui32Len; i++) + { + pui32ResultBuf[i]= HWREG( (ui32ResVectorLoc + 4*i) ); + } + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Starts the addition of two big number. +//! +//! \param pui32BN1 is the pointer to the buffer containing the first +//! big mumber. +//! \param ui8BN1Size is the size of the first big number in 32-bit word. +//! \param pui32BN2 is the pointer to the buffer containing the second +//! big number. +//! \param ui8BN2Size is the size of the second big number in 32-bit word. +//! \param pui32ResultVector is the pointer to the result vector location +//! which will be set by this function. +//! +//! This function starts the addition of the two big numbers. +//! +//!\return Returns: +//! - \b PKA_STATUS_SUCCESS if successful in starting the operation. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy doing +//! some other operation. +// +//***************************************************************************** +tPKAStatus +PKABigNumAddStart(uint32_t* pui32BN1, uint8_t ui8BN1Size, + uint32_t* pui32BN2, uint8_t ui8BN2Size, + uint32_t* pui32ResultVector) +{ + uint32_t offset; + int i; + + // + // Check for arguments. + // + ASSERT(NULL != pui32BN1); + ASSERT(NULL != pui32BN2); + ASSERT(NULL != pui32ResultVector); + + offset = 0; + + // + // Make sure no operation is in progress. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Update the A ptr with the offset address of the PKA RAM location + // where the big number 1 will be stored. + // + HWREG( (PKA_APTR) ) = offset >> 2; + + // + // Load the big number 1 in PKA RAM. + // + for(i = 0; i < ui8BN1Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = pui32BN1[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + (ui8BN1Size % 2)); + + // + // Update the B ptr with the offset address of the PKA RAM location + // where the big number 2 will be stored. + // + HWREG( (PKA_BPTR) ) = offset >> 2; + + // + // Load the big number 2 in PKA RAM. + // + for(i = 0; i < ui8BN2Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = pui32BN2[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + (ui8BN2Size % 2)); + + // + // Copy the result vector address location. + // + *pui32ResultVector = PKA_RAM_BASE + offset; + + // + // Load C ptr with the result location in PKA RAM. + // + HWREG( (PKA_CPTR) ) = offset >> 2; + + // + // Load respective length registers. + // + HWREG( (PKA_ALENGTH) ) = ui8BN1Size; + HWREG( (PKA_BLENGTH) ) = ui8BN2Size; + + // + // Set the function for the add operation and start the operation. + // + HWREG( (PKA_FUNCTION) ) = (PKA_FUNCTION_RUN | PKA_FUNCTION_ADD); + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Gets the result of the addition operation on two big number. +//! +//! \param pui32ResultBuf is the pointer to buffer where the result +//! needs to be stored. +//! \param pui32Len is the address of the variable containing the length of +//! the buffer. After the operation the actual length of the resultant is +//! stored at this address. +//! \param ui32ResVectorLoc is the address of the result location which +//! was provided by the start function \sa PKABigNumAddStart(). +//! +//! This function gets the result of the addition operation on two big numbers, +//! previously started using the function \sa PKABigNumAddStart(). +//! +//! \return Returns: +//! - \b PKA_STATUS_SUCCESS if the operation is successful. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy performing +//! the operation. +//! - \b PKA_STATUS_RESULT_0 if the result is all zeroes. +//! - \b PKA_STATUS_FAILURE if the operation is not successful. +//! - \b PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less +//! then the length of the result. +// +//***************************************************************************** +tPKAStatus +PKABigNumAddGetResult(uint32_t* pui32ResultBuf, uint32_t* pui32Len, + uint32_t ui32ResVectorLoc) +{ + uint32_t regMSWVal; + uint32_t len; + int i; + + // + // Check for the arguments. + // + ASSERT(NULL != pui32ResultBuf); + ASSERT(NULL != pui32Len); + ASSERT((ui32ResVectorLoc > PKA_RAM_BASE) && + (ui32ResVectorLoc < (PKA_RAM_BASE + PKA_RAM_SIZE))); + + // + // Verify that the operation is complete. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Get the MSW register value. + // + regMSWVal = HWREG(PKA_MSW); + + // + // Check to make sure that the result vector is not all zeroes. + // + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) + { + return (PKA_STATUS_RESULT_0); + } + + // + // Get the length of the result. + // + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) - + ((ui32ResVectorLoc - PKA_RAM_BASE) >> 2); + + // + // Make sure that the supplied result buffer is adequate to store the + // resultant data. + // + if(*pui32Len < len) + { + return (PKA_STATUS_BUF_UNDERFLOW); + } + + // + // Copy the length. + // + *pui32Len = len; + + // + // Copy the result from vector C into the provided buffer. + for(i = 0; i < *pui32Len; i++) + { + pui32ResultBuf[i] = HWREG( (ui32ResVectorLoc + 4*i) ); + } + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Starts ECC Multiplication. +//! +//! \param pui32Scalar is pointer to the buffer containing the scalar +//! value to be multiplied. +//! \param ptEcPt is the pointer to the structure containing the +//! elliptic curve point to be multiplied. The point should be on the given +//! curve. +//! \param ptCurve is the pointer to the structure containing the curve +//! info. +//! \param pui32ResultVector is the pointer to the result vector location +//! which will be set by this function. +//! +//! This function starts the Elliptical curve cryptography (ECC) point +//! multiplication operation on the EC point and the scalar value. +//! +//!\return Returns: +//! - \b PKA_STATUS_SUCCESS if successful in starting the operation. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy doing +//! some other operation. +// +//***************************************************************************** +tPKAStatus +PKAECCMultiplyStart(uint32_t* pui32Scalar, tECPt* ptEcPt, + tECCCurveInfo* ptCurve, uint32_t* pui32ResultVector) +{ + uint8_t extraBuf; + uint32_t offset; + int i; + + // + // Check for the arguments. + // + ASSERT(NULL != pui32Scalar); + ASSERT(NULL != ptEcPt); + ASSERT(NULL != ptEcPt->pui32X); + ASSERT(NULL != ptEcPt->pui32Y); + ASSERT(NULL != ptCurve); + ASSERT(ptCurve->ui8Size <= PKA_MAX_CURVE_SIZE_32_BIT_WORD); + ASSERT(NULL != pui32ResultVector); + + offset = 0; + + // + // Make sure no PKA operation is in progress. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Calculate the extra buffer requirement. + // + extraBuf = 2 + ptCurve->ui8Size % 2; + + // + // Update the A ptr with the offset address of the PKA RAM location + // where the scalar will be stored. + // + HWREG((PKA_APTR)) = offset >> 2; + + // + // Load the scalar in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = *pui32Scalar++; + } + + // + // Determine the offset for the next data. + // + offset += 4 * (i + (ptCurve->ui8Size % 2)); + + // + // Update the B ptr with the offset address of the PKA RAM location + // where the curve parameters will be stored. + // + HWREG((PKA_BPTR)) = offset >> 2; + + // + // Write curve parameter 'p' as 1st part of vector B immediately + // following vector A at PKA RAM + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = + (uint32_t)ptCurve->pui32Prime[i]; + } + + // + // Determine the offset for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Copy curve parameter 'a' in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = (uint32_t)ptCurve->pui32A[i]; + } + + // + // Determine the offset for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Copy curve parameter 'b' in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = (uint32_t)ptCurve->pui32B[i]; + } + + // + // Determine the offset for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Update the C ptr with the offset address of the PKA RAM location + // where the Gx, Gy will be stored. + // + HWREG((PKA_CPTR)) = offset >> 2; + + // + // Write elliptic curve point x co-ordinate value. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = ptEcPt->pui32X[i]; + } + + // + // Determine the offset for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Write elliptic curve point y co-ordinate value. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = ptEcPt->pui32Y[i]; + } + + // + // Determine the offset for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Update the result location. + // + *pui32ResultVector = PKA_RAM_BASE + offset; + + // + // Load D ptr with the result location in PKA RAM. + // + HWREG(PKA_DPTR) = offset >> 2; + + // + // Load length registers. + // + HWREG(PKA_ALENGTH) = ptCurve->ui8Size; + HWREG(PKA_BLENGTH) = ptCurve->ui8Size; + + // + // set the PKA function to ECC-MULT and start the operation. + // + HWREG(PKA_FUNCTION) = 0x0000D000; + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Gets the result of ECC Multiplication +//! +//! \param ptOutEcPt is the pointer to the structure where the resultant EC +//! point will be stored. The callee is responsible to allocate the space for +//! the ec point structure and the x and y co-ordinate as well. +//! \param ui32ResVectorLoc is the address of the result location which +//! was provided by the start function \sa PKAECCMultiplyStart(). +//! +//! This function gets the result of ecc point multiplication operation on the +//! ec point and the scalar value, previously started using the function +//! \sa PKAECCMultiplyStart(). +//! +//! \return Returns: +//! - \b PKA_STATUS_SUCCESS if the operation is successful. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy performing +//! the operation. +//! - \b PKA_STATUS_RESULT_0 if the result is all zeroes. +//! - \b PKA_STATUS_FAILURE if the operation is not successful. +// +//***************************************************************************** +tPKAStatus +PKAECCMultiplyGetResult(tECPt* ptOutEcPt, uint32_t ui32ResVectorLoc) +{ + int i; + uint32_t addr; + uint32_t regMSWVal; + uint32_t len; + + // + // Check for the arguments. + // + ASSERT(NULL != ptOutEcPt); + ASSERT(NULL != ptOutEcPt->pui32X); + ASSERT(NULL != ptOutEcPt->pui32Y); + ASSERT((ui32ResVectorLoc > PKA_RAM_BASE) && + (ui32ResVectorLoc < (PKA_RAM_BASE + PKA_RAM_SIZE))); + + // + // Verify that the operation is completed. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + if(HWREG(PKA_SHIFT) == 0x00000000) + { + // + // Get the MSW register value. + // + regMSWVal = HWREG(PKA_MSW); + + // + // Check to make sure that the result vector is not all zeroes. + // + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) + { + return (PKA_STATUS_RESULT_0); + } + + // + // Get the length of the result + // + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) - + ((ui32ResVectorLoc - PKA_RAM_BASE) >> 2); + + addr = ui32ResVectorLoc; + + // + // copy the x co-ordinate value of the result from vector D into + // the \e ptOutEcPt. + // + for(i = 0; i < len; i++) + { + ptOutEcPt->pui32X[i] = HWREG(addr + 4*i); + } + + addr += 4 * (i + 2 + len % 2); + + // + // copy the y co-ordinate value of the result from vector D into + // the \e ptOutEcPt. + // + for(i = 0; i < len; i++) + { + ptOutEcPt->pui32Y[i] = HWREG(addr + 4*i); + } + + return (PKA_STATUS_SUCCESS); + } + else + { + return (PKA_STATUS_FAILURE); + } +} + +//***************************************************************************** +// +//! Starts the ECC Multiplication with Generator point. +//! +//! \param pui32Scalar is the to pointer to the buffer containing the scalar +//! value. +//! \param ptCurve is the pointer to the structure containing the curve +//! info. +//! \param pui32ResultVector is the pointer to the result vector location +//! which will be set by this function. +//! +//! This function starts the ecc point multiplication operation of the +//! scalar value with the well known generator point of the given curve. +//! +//!\return Returns: +//! - \b PKA_STATUS_SUCCESS if successful in starting the operation. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy doing +//! some other operation. +// +//***************************************************************************** +tPKAStatus +PKAECCMultGenPtStart(uint32_t* pui32Scalar, tECCCurveInfo* ptCurve, + uint32_t* pui32ResultVector) +{ + uint8_t extraBuf; + uint32_t offset; + int i; + + // + // check for the arguments. + // + ASSERT(NULL != pui32Scalar); + ASSERT(NULL != ptCurve); + ASSERT(ptCurve->ui8Size <= PKA_MAX_CURVE_SIZE_32_BIT_WORD); + ASSERT(NULL != pui32ResultVector); + + offset = 0; + + // + // Make sure no operation is in progress. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Calculate the extra buffer requirement. + // + extraBuf = 2 + ptCurve->ui8Size % 2; + + // + // Update the A ptr with the offset address of the PKA RAM location + // where the scalar will be stored. + // + HWREG(PKA_APTR) = offset >> 2; + + // + // Load the scalar in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = *pui32Scalar++; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + (ptCurve->ui8Size % 2)); + + // + // Update the B ptr with the offset address of the PKA RAM location + // where the curve parameters will be stored. + // + HWREG(PKA_BPTR) = offset >> 2; + + // + // Write curve parameter 'p' as 1st part of vector B. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = + (uint32_t)ptCurve->pui32Prime[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Write curve parameter 'a' in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = (uint32_t)ptCurve->pui32A[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // write curve parameter 'b' in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = (uint32_t)ptCurve->pui32B[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Update the C ptr with the offset address of the PKA RAM location + // where the Gx, Gy will be stored. + // + HWREG(PKA_CPTR) = offset >> 2; + + // + // Write x co-ordinate value of the Generator point in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = (uint32_t)ptCurve->pui32Gx[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Write y co-ordinate value of the Generator point in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = (uint32_t)ptCurve->pui32Gy[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Update the result location. + // + *pui32ResultVector = PKA_RAM_BASE + offset; + + // + // Load D ptr with the result location in PKA RAM. + // + HWREG(PKA_DPTR) = offset >> 2; + + // + // Load length registers. + // + HWREG(PKA_ALENGTH) = ptCurve->ui8Size; + HWREG(PKA_BLENGTH) = ptCurve->ui8Size; + + // + // Set the PKA function to ECC-MULT and start the operation. + // + HWREG( (PKA_FUNCTION) ) = 0x0000D000; + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Gets the result of ECC Multiplication with Generator point. +//! +//! \param ptOutEcPt is the pointer to the structure where the resultant EC +//! point will be stored. The callee is responsible to allocate the space for +//! the ec point structure and the x and y co-ordinate as well. +//! \param ui32ResVectorLoc is the address of the result location which +//! was provided by the start function \sa PKAECCMultGenPtStart(). +//! +//! This function gets the result of ecc point multiplication operation on the +//! scalar point and the known generator point on the curve, previously started +//! using the function \sa PKAECCMultGenPtStart(). +//! +//! \return Returns: +//! - \b PKA_STATUS_SUCCESS if the operation is successful. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy performing +//! the operation. +//! - \b PKA_STATUS_RESULT_0 if the result is all zeroes. +//! - \b PKA_STATUS_FAILURE if the operation is not successful. +// +//***************************************************************************** +tPKAStatus +PKAECCMultGenPtGetResult(tECPt* ptOutEcPt, uint32_t ui32ResVectorLoc) +{ + int i; + uint32_t regMSWVal; + uint32_t addr; + uint32_t len; + + // + // Check for the arguments. + // + ASSERT(NULL != ptOutEcPt); + ASSERT(NULL != ptOutEcPt->pui32X); + ASSERT(NULL != ptOutEcPt->pui32Y); + ASSERT((ui32ResVectorLoc > PKA_RAM_BASE) && + (ui32ResVectorLoc < (PKA_RAM_BASE + PKA_RAM_SIZE))); + + // + // Verify that the operation is completed. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + if(HWREG(PKA_SHIFT) == 0x00000000) + { + // + // Get the MSW register value. + // + regMSWVal = HWREG(PKA_MSW); + + // + // Check to make sure that the result vector is not all zeroes. + // + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) + { + return (PKA_STATUS_RESULT_0); + } + + // + // Get the length of the result. + // + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) - + ((ui32ResVectorLoc - PKA_RAM_BASE) >> 2); + + addr = ui32ResVectorLoc; + + // + // Copy the x co-ordinate value of the result from vector D into the + // EC point. + // + for(i = 0; i < len; i++) + { + ptOutEcPt->pui32X[i] = HWREG( (addr + 4*i) ); + } + + addr += 4 * (i + 2 + len % 2); + + // + // Copy the y co-ordinate value of the result from vector D into the + // EC point. + // + for(i = 0; i < len; i++) + { + ptOutEcPt->pui32Y[i] = HWREG( (addr + 4*i) ); + } + + return (PKA_STATUS_SUCCESS); + } + else + { + return (PKA_STATUS_FAILURE); + } +} + +//***************************************************************************** +// +//! Starts the ECC Addition. +//! +//! \param ptEcPt1 is the pointer to the structure containing the first +//! ecc point. +//! \param ptEcPt2 is the pointer to the structure containing the +//! second ecc point. +//! \param ptCurve is the pointer to the structure containing the curve +//! info. +//! \param pui32ResultVector is the pointer to the result vector location +//! which will be set by this function. +//! +//! This function starts the ecc point addition operation on the +//! two given ec points and generates the resultant ecc point. +//! +//!\return Returns: +//! - \b PKA_STATUS_SUCCESS if successful in starting the operation. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy doing +//! some other operation. +// +//***************************************************************************** +tPKAStatus +PKAECCAddStart(tECPt* ptEcPt1, tECPt* ptEcPt2,tECCCurveInfo* ptCurve, + uint32_t* pui32ResultVector) +{ + uint8_t extraBuf; + uint32_t offset; + int i; + + // + // Check for the arguments. + // + ASSERT(NULL != ptEcPt1); + ASSERT(NULL != ptEcPt1->pui32X); + ASSERT(NULL != ptEcPt1->pui32Y); + ASSERT(NULL != ptEcPt2); + ASSERT(NULL != ptEcPt2->pui32X); + ASSERT(NULL != ptEcPt2->pui32Y); + ASSERT(NULL != ptCurve); + ASSERT(NULL != pui32ResultVector); + + offset = 0; + + // + // Make sure no operation is in progress. + // + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + // + // Calculate the extra buffer requirement. + // + extraBuf = 2 + ptCurve->ui8Size % 2; + + // + // Update the A ptr with the offset address of the PKA RAM location + // where the first ecPt will be stored. + // + HWREG(PKA_APTR) = offset >> 2; + + // + // Load the x co-ordinate value of the first EC point in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = ptEcPt1->pui32X[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Load the y co-ordinate value of the first EC point in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = ptEcPt1->pui32Y[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Update the B ptr with the offset address of the PKA RAM location + // where the curve parameters will be stored. + // + HWREG(PKA_BPTR) = offset >> 2; + + // + // Write curve parameter 'p' as 1st part of vector B + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = + (uint32_t)ptCurve->pui32Prime[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Write curve parameter 'a'. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = (uint32_t)ptCurve->pui32A[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Update the C ptr with the offset address of the PKA RAM location + // where the ecPt2 will be stored. + // + HWREG(PKA_CPTR) = offset >> 2; + + // + // Load the x co-ordinate value of the second EC point in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = ptEcPt2->pui32X[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Load the y co-ordinate value of the second EC point in PKA RAM. + // + for(i = 0; i < ptCurve->ui8Size; i++) + { + HWREG((PKA_RAM_BASE + offset + 4*i)) = ptEcPt2->pui32Y[i]; + } + + // + // Determine the offset in PKA RAM for the next data. + // + offset += 4 * (i + extraBuf); + + // + // Copy the result vector location. + // + *pui32ResultVector = PKA_RAM_BASE + offset; + + // + // Load D ptr with the result location in PKA RAM. + // + HWREG(PKA_DPTR) = offset >> 2; + + // + // Load length registers. + // + HWREG(PKA_BLENGTH) = ptCurve->ui8Size; + + // + // Set the PKA Function to ECC-ADD and start the operation. + // + HWREG( (PKA_FUNCTION) ) = 0x0000B000; + + return (PKA_STATUS_SUCCESS); +} + +//***************************************************************************** +// +//! Gets the result of the ECC Addition +//! +//! \param ptOutEcPt is the pointer to the structure where the resultant +//! point will be stored. The callee is responsible to allocate memory, +//! for the ec point structure including the memory for x and y +//! co-ordinate values. +//! \param ui32ResVectorLoc is the address of the result location which +//! was provided by the function \sa PKAECCAddStart(). +//! +//! This function gets the result of ecc point addition operation on the +//! on the two given ec points, previously started using the function \sa +//! PKAECCAddStart(). +//! +//! \return Returns: +//! - \b PKA_STATUS_SUCCESS if the operation is successful. +//! - \b PKA_STATUS_OPERATION_INPRG, if the PKA hw module is busy performing +//! the operation. +//! - \b PKA_STATUS_RESULT_0 if the result is all zeroes. +//! - \b PKA_STATUS_FAILURE if the operation is not successful. +// +//***************************************************************************** +tPKAStatus +PKAECCAddGetResult(tECPt* ptOutEcPt, uint32_t ui32ResVectorLoc) +{ + uint32_t regMSWVal; + uint32_t addr; + int i; + uint32_t len; + + // + // Check for the arguments. + // + ASSERT(NULL != ptOutEcPt); + ASSERT(NULL != ptOutEcPt->pui32X); + ASSERT(NULL != ptOutEcPt->pui32Y); + ASSERT((ui32ResVectorLoc > PKA_RAM_BASE) && + (ui32ResVectorLoc < (PKA_RAM_BASE + PKA_RAM_SIZE))); + + if((HWREG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) + { + return (PKA_STATUS_OPERATION_INPRG); + } + + if(HWREG(PKA_SHIFT) == 0x00000000) + { + // + // Get the MSW register value. + // + regMSWVal = HWREG(PKA_MSW); + + // + // Check to make sure that the result vector is not all zeroes. + // + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) + { + return (PKA_STATUS_RESULT_0); + } + + // + // Get the length of the result. + // + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) - + ((ui32ResVectorLoc - PKA_RAM_BASE) >> 2); + + addr = ui32ResVectorLoc; + + // + // Copy the x co-ordinate value of result from vector D into the + // the output EC Point. + // + for(i = 0; i < len; i++) + { + ptOutEcPt->pui32X[i] = HWREG((addr + 4*i)); + } + + addr += 4 * (i + 2 + len % 2); + + // + // Copy the y co-ordinate value of result from vector D into the + // the output EC Point. + // + for(i = 0; i < len; i++) + { + ptOutEcPt->pui32Y[i] = HWREG((addr + 4*i)); + } + + return (PKA_STATUS_SUCCESS); + } + else + { + return (PKA_STATUS_FAILURE); + } +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + diff --git a/bsp/boards/mimsy2-cc2538/source/pka.h b/bsp/boards/mimsy2-cc2538/source/pka.h new file mode 100644 index 0000000000..cbedc2009c --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/pka.h @@ -0,0 +1,170 @@ +/****************************************************************************** +* Filename: pka.h +* Revised: $Date: 2012-10-01 11:15:04 -0700 (Mon, 01 Oct 2012) $ +* Revision: $Revision: 31660 $ +* +* Description: Type definition and function prototypes needed to +* interface with the public key accelerator hardware +* engine on CC2538. +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __PKA_H__ +#define __PKA_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "ecc_curveinfo.h" + +//***************************************************************************** +// +// Function return values +// +//***************************************************************************** +#define PKA_STATUS_SUCCESS 0 // Success +#define PKA_STATUS_FAILURE 1 // Failure +#define PKA_STATUS_INVALID_PARAM 2 // Invalid parameter +#define PKA_STATUS_BUF_UNDERFLOW 3 // Buffer underflow +#define PKA_STATUS_RESULT_0 4 // Result is all zeros +#define PKA_STATUS_A_GR_B 5 // Big number compare return status if + // the first big num is greater than + // the second. +#define PKA_STATUS_A_LT_B 6 // Big number compare return status if + // the first big num is less than the + // second. +#define PKA_STATUS_OPERATION_INPRG 7 // PKA operation is in progress. +#define PKA_STATUS_OPERATION_NOT_INPRG 8 // No PKA operation is in progress. + +//***************************************************************************** +// +// A structure containing the pointers to the values of x and y co-ordinates of +// the Elliptical Curve point. +// +//***************************************************************************** +typedef struct _ECPt +{ + // + // Pointer to value of the x co-ordinate of the ec point. + // + uint32_t* pui32X; + + // + // Pointer to value of the y co-ordinate of the ec point. + // + uint32_t* pui32Y; +} +tECPt; + +//***************************************************************************** +// +// PKA function return type. +// +//***************************************************************************** +typedef uint8_t tPKAStatus; + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void PKAEnableInt(void); +extern void PKADisableInt(void); +extern void PKAClearInt(void); +extern void PKARegInt(void(*pfnHandler)(void)); +extern void PKAUnRegInt(void); +extern tPKAStatus PKAGetOpsStatus(void); +extern tPKAStatus PKABigNumModStart(uint32_t* pui32BNum, uint8_t ui8BNSize, + uint32_t* pui32Modulus, uint8_t ui8ModSize, + uint32_t* pui32ResultVector); +extern tPKAStatus PKABigNumModGetResult(uint32_t* pui32ResultBuf, + uint8_t ui8Size, + uint32_t ui32ResVectorLoc); +extern tPKAStatus PKABigNumCmpStart(uint32_t* pui32BNum1, uint32_t* pui32BNum2, + uint8_t ui8Size); +extern tPKAStatus PKABigNumCmpGetResult(void); +extern tPKAStatus PKABigNumInvModStart(uint32_t* pui32BNum, uint8_t ui8BNSize, + uint32_t* pui32Modulus, uint8_t ui8Size, + uint32_t* pui32ResultVector); +extern tPKAStatus PKABigNumInvModGetResult(uint32_t* pui32ResultBuf, + uint8_t ui8Size, + uint32_t ui32ResVectorLoc); +extern tPKAStatus PKABigNumMultiplyStart(uint32_t* pui32Xplicand, + uint8_t ui8XplicandSize, + uint32_t* pui32Xplier, + uint8_t ui8XplierSize, + uint32_t* pui32ResultVector); +extern tPKAStatus PKABigNumMultGetResult(uint32_t* pui32ResultBuf, + uint32_t* pui32Len, + uint32_t ui32ResVectorLoc); +extern tPKAStatus PKABigNumAddStart(uint32_t* pui32BN1, uint8_t ui8BN1Size, + uint32_t* pui32BN2, uint8_t ui8BN2Size, + uint32_t* pui32ResultVector); +extern tPKAStatus PKABigNumAddGetResult(uint32_t* pui32ResultBuf, + uint32_t* pui32Len, + uint32_t ui32resVectorLoc); +extern tPKAStatus PKAECCMultiplyStart(uint32_t* pui32Scalar, + tECPt* ptEcPt, + tECCCurveInfo* ptCurve, + uint32_t* pui32ResultVector); +extern tPKAStatus PKAECCMultiplyGetResult(tECPt* ptOutEcPt, + uint32_t ui32ResVectorLoc); +extern tPKAStatus PKAECCMultGenPtStart(uint32_t* pui32Scalar, + tECCCurveInfo* ptCurve, + uint32_t* pui32ResultVector); +extern tPKAStatus PKAECCMultGenPtGetResult(tECPt* ptOutEcPt, + uint32_t pui32ResVectorLoc); +extern tPKAStatus PKAECCAddStart(tECPt* ptEcPt1, tECPt* ptEcPt2, + tECCCurveInfo* ptCurve, + uint32_t* pui32ResultVector); +extern tPKAStatus PKAECCAddGetResult(tECPt* ptOutEcPt, uint32_t ui32ResultLoc); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __PKA_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/rom.h b/bsp/boards/mimsy2-cc2538/source/rom.h new file mode 100644 index 0000000000..03c9335b67 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/rom.h @@ -0,0 +1,117 @@ +/****************************************************************************** +* Filename: rom.h +* Revised: $Date: 2012-10-03 22:23:04 +0200 (on, 03 okt 2012) $ +* Revision: $Revision: 8460 $ +* +* Description: Prototypes for the ROM utility functions. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __ROM_H__ +#define __ROM_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +// +// Start address of the ROM hard API access table (located after the ROM FW rev field) +// +#define ROM_API_TABLE_ADDR 0x00000048 + +// +// ROM utility function interface types +// +typedef uint32_t (* volatile FPTR_CRC32_T) (uint8_t* /*pData*/, uint32_t /*byteCount*/); +typedef uint32_t (* volatile FPTR_GETFLSIZE_T) (void); +typedef uint32_t (* volatile FPTR_GETCHIPID_T) (void); +typedef int32_t (* volatile FPTR_PAGEERASE_T) (uint32_t /*FlashAddr*/, uint32_t /*Size*/); +typedef int32_t (* volatile FPTR_PROGFLASH_T) (uint32_t* /*pRamData*/, uint32_t /*FlashAdr*/, uint32_t /*ByteCount*/); +typedef void (* volatile FPTR_RESETDEV_T) (void); +typedef void* (* volatile FPTR_MEMSET_T) (void* /*s*/, int32_t /*c*/, uint32_t /*n*/); +typedef void* (* volatile FPTR_MEMCPY_T) (void* /*s1*/, const void* /*s2*/, uint32_t /*n*/); +typedef int32_t (* volatile FPTR_MEMCMP_T) (const void* /*s1*/, const void* /*s2*/, uint32_t /*n*/); +typedef void* (* volatile FPTR_MEMMOVE_T) (void* /*s1*/, const void* /*s2*/, uint32_t /*n*/); + +// +// ROM Hard-API access table type +// +typedef struct + { + FPTR_CRC32_T Crc32; + FPTR_GETFLSIZE_T GetFlashSize; + FPTR_GETCHIPID_T GetChipId; + FPTR_PAGEERASE_T PageErase; + FPTR_PROGFLASH_T ProgramFlash; + FPTR_RESETDEV_T ResetDevice; + FPTR_MEMSET_T memset; + FPTR_MEMCPY_T memcpy; + FPTR_MEMCMP_T memcmp; + FPTR_MEMMOVE_T memmove; + } ROM_API_T; + +// +// Pointer to the ROM API table +// +#define P_ROM_API ((ROM_API_T*) ROM_API_TABLE_ADDR) + +#define ROM_Crc32(a,b) P_ROM_API->Crc32(a,b) +#define ROM_GetFlashSize() P_ROM_API->GetFlashSize() +#define ROM_GetChipId() P_ROM_API->GetChipId() +#define ROM_PageErase(a,b) P_ROM_API->PageErase(a,b) +#define ROM_ProgramFlash(a,b,c) P_ROM_API->ProgramFlash(a,b,c) +#define ROM_ResetDevice() P_ROM_API->ResetDevice() +#define ROM_Memset(a,b,c) P_ROM_API->memset(a,b,c) +#define ROM_Memcpy(a,b,c) P_ROM_API->memcpy(a,b,c) +#define ROM_Memcmp(a,b,c) P_ROM_API->memcmp(a,b,c) +#define ROM_Memmove(a,b,c) P_ROM_API->memmove(a,b,c) + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __ROM_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/sha256.c b/bsp/boards/mimsy2-cc2538/source/sha256.c new file mode 100644 index 0000000000..d8a0b4aba2 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/sha256.c @@ -0,0 +1,465 @@ +/****************************************************************************** +* Filename: sha256.c +* Revised: $Date: 2013-04-03 14:12:40 +0200 (Wed, 03 Apr 2013) $ +* Revision: $Revision: 9611 $ +* +* Description: Support for Hardware SHA 256 +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup sha256_api +//! @{ +// +//***************************************************************************** + +#include "aes.h" +#include "sha256.h" +#include + +static uint8_t SHA256HashResume(tSHA256State * psMd, uint8_t *ui8In, uint8_t *ui8Out); +static uint8_t SHA256HashNew(tSHA256State * psMd, uint8_t *ui8In, uint8_t *ui8Out); + +//***************************************************************************** +// +//! SHA256init initializes the hash state. +//! +//! \param psMd is the pointer to hash state you wish to initialize. +//! +//! For the pointer to hash state parameter \e psMd the calling function has to +//! allocate the hash state structure and pass the pointer to the structure. +//! +//! \return SHA256_SUCCESS if successful. +// +//***************************************************************************** +uint8_t SHA256Init(tSHA256State * psMd) +{ + if(psMd == NULL) + { + return (SHA256_NULL_ERROR); + } + + psMd->curlen = 0; + psMd->length = 0; + psMd->new_digest = true; + psMd->final_digest = false; + return (SHA256_SUCCESS); +} + +//***************************************************************************** +// +//! SHA256Process processes a block of memory through the hash. This +//! function must be called only after SHA256init(). +//! +//! \param psMd is the pointer to hash state. +//! \param ui8In is the pointer to the data to hash. +//! \param ui32InLen is the length of the data to hash ui8In bytes (octets). +//! +//! For the pointer to hash state parameter \e psMd the calling function must +//! allocate the hash state structure and pass the pointer to the structure. +//! +//! \return SHA256_SUCCESS if successful. +// +//***************************************************************************** +uint8_t SHA256Process(tSHA256State * psMd, uint8_t *ui8In, uint32_t ui32InLen) +{ + uint8_t ui8Err; + uint32_t ui32N, ui32I; + + if(psMd == NULL) + { + return (SHA256_NULL_ERROR); + } + if(ui8In == NULL) + { + return (SHA256_NULL_ERROR); + } + + if(psMd->curlen > sizeof(psMd->buf)) + { + return (SHA256_INVALID_PARAM); + } + + g_ui8CurrentAESOp = AES_SHA256; + if(ui32InLen > 0 && psMd->new_digest == true) + { + if(psMd->curlen == 0 && ui32InLen > SHA256_BLOCK_SIZE) + { + for(ui32I = 0; ui32I < SHA256_BLOCK_SIZE; ui32I++) + { + psMd->buf[psMd->curlen + ui32I] = ui8In[ui32I]; + } + if((ui8Err = SHA256HashNew(psMd, (uint8_t *)psMd->buf, + (uint8_t *)psMd->state)) != SHA256_SUCCESS) + { + g_ui8CurrentAESOp = AES_NONE; + return (ui8Err); + } + psMd->new_digest = false; + psMd->length += SHA256_BLOCK_SIZE * 8; + ui32InLen -= SHA256_BLOCK_SIZE; + ui8In += SHA256_BLOCK_SIZE; + + } + else + { + ui32N = MIN(ui32InLen, (SHA256_BLOCK_SIZE - psMd->curlen)); + for(ui32I = 0; ui32I < ui32N; ui32I++) + { + psMd->buf[psMd->curlen + ui32I] = ui8In[ui32I]; + } + psMd->curlen += ui32N; + ui8In += ui32N; + ui32InLen -= ui32N; + if(psMd->curlen == SHA256_BLOCK_SIZE && ui32InLen > 0) + { + if((ui8Err = SHA256HashNew(psMd, (uint8_t *)psMd->buf, + (uint8_t *)psMd->state)) != SHA256_SUCCESS) + { + g_ui8CurrentAESOp = AES_NONE; + return (ui8Err); + } + psMd->new_digest = false; + psMd->length += 8 * SHA256_BLOCK_SIZE; + psMd->curlen = 0; + } + } + } + + while(ui32InLen > 0 && psMd->new_digest == false) + { + if(psMd->curlen == 0 && ui32InLen > SHA256_BLOCK_SIZE) + { + for(ui32I = 0; ui32I < SHA256_BLOCK_SIZE; ui32I++) + { + psMd->buf[psMd->curlen + ui32I] = ui8In[ui32I]; + } + if((ui8Err = SHA256HashResume(psMd, (uint8_t *)psMd->buf, + (uint8_t *)psMd->state)) != SHA256_SUCCESS) + { + g_ui8CurrentAESOp = AES_NONE; + return (ui8Err); + } + psMd->length += SHA256_BLOCK_SIZE * 8; + ui8In += SHA256_BLOCK_SIZE; + ui32InLen -= SHA256_BLOCK_SIZE; + } + else + { + ui32N = MIN(ui32InLen, (SHA256_BLOCK_SIZE - psMd->curlen)); + for(ui32I = 0; ui32I < ui32N; ui32I++) + { + psMd->buf[psMd->curlen + ui32I] = ui8In[ui32I]; + } + psMd->curlen += ui32N; + ui8In += ui32N; + ui32InLen -= ui32N; + if(psMd->curlen == SHA256_BLOCK_SIZE && ui32InLen > 0) + { + if((ui8Err = SHA256HashResume(psMd, (uint8_t *) psMd->buf, + (uint8_t *)psMd->state)) != SHA256_SUCCESS) + { + g_ui8CurrentAESOp = AES_NONE; + return (ui8Err); + } + psMd->length += 8 * SHA256_BLOCK_SIZE; + psMd->curlen = 0; + } + } + } + g_ui8CurrentAESOp = AES_NONE; + return (SHA256_SUCCESS); +} + +//***************************************************************************** +// +//! SHA256Done function terminates hash session to get the digest. This +//! function must be called only after SHA256Process(). +//! +//! \param psMd is the pointer to hash state. +//! \param ui8Out is the pointer to hash. +//! +//! For the pointer to hash state parameter \e psMd the calling function has to +//! allocate the hash state structure and pass the pointer to the structure. +//! +//! \return SHA256_SUCCESS if successful. +// +//***************************************************************************** +uint8_t SHA256Done(tSHA256State * psMd, uint8_t *ui8Out) +{ + uint8_t ui8Err; + if(psMd == NULL || ui8Out == NULL) + { + return (SHA256_NULL_ERROR); + } + + if(psMd->curlen > sizeof(psMd->buf)) + { + return (SHA256_INVALID_PARAM); + } + + g_ui8CurrentAESOp = AES_SHA256; + + // increase the length of the message + psMd->length += psMd->curlen * 8; + psMd->final_digest = true; + if(psMd->new_digest == true) + { + if((ui8Err = SHA256HashNew(psMd, (uint8_t *)psMd->buf, + (uint8_t *)ui8Out)) != SHA256_SUCCESS) + { + g_ui8CurrentAESOp = AES_NONE; + return (ui8Err); + } + } + else + { + if((ui8Err = SHA256HashResume(psMd, (uint8_t *)psMd->buf, + (uint8_t *)ui8Out)) != SHA256_SUCCESS) + { + g_ui8CurrentAESOp = AES_NONE; + return (ui8Err); + } + } + psMd->new_digest = false; + psMd->final_digest = false; + + g_ui8CurrentAESOp = AES_NONE; + return (SHA256_SUCCESS); +} + +//***************************************************************************** +// +//! SHA256HashNew function is to start a new Hash session in hardware. +//! +//! \param psMd is the hash state. +//! \param ui8In is the pointer to input message. +//! \param ui8Out is the destination of the hash (32 bytes). +//! +//! \return SHA256_SUCCESS if successful. +// +//***************************************************************************** +uint8_t SHA256HashNew(tSHA256State * psMd, uint8_t *ui8In, uint8_t *ui8Out) +{ + // workaround for AES registers not retained after PM2 + IntDisable(INT_AES); + HWREG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + HWREG(AES_CTRL_INT_EN) = (AES_CTRL_INT_EN_RESULT_AV | + AES_CTRL_INT_EN_DMA_IN_DONE); + + // configure master control module + // enable DMA path to the SHA-256 engine + Digest readout + HWREG(AES_CTRL_ALG_SEL) = (AES_CTRL_ALG_SEL_TAG | AES_CTRL_ALG_SEL_HASH); + // clear any outstanding events + HWREG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV; + + // configure hash engine + // indicate start of a new hash session and SHA256 + HWREG(AES_HASH_MODE_IN) = (AES_HASH_MODE_IN_SHA256_MODE | + AES_HASH_MODE_IN_NEW_HASH); + + // if the final digest is required (pad the input DMA data), + // write the following register + // + if(psMd->final_digest) + { + // write length of the message (lo) + HWREG(AES_HASH_LENGTH_IN_L) = (uint32_t)psMd->length; + // write length of the message (hi) + HWREG(AES_HASH_LENGTH_IN_H) = (uint32_t)(psMd->length >> 16); + // pad the DMA-ed data + HWREG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE; + } + + // enable DMA channel 0 for message data + HWREG(AES_DMAC_CH0_CTRL) |= AES_DMAC_CH0_CTRL_EN; + // base address of the data in ext. memory + HWREG(AES_DMAC_CH0_EXTADDR) = (uint32_t)ui8In; + if(psMd->final_digest) + { + // input data length in bytes, equal to the message + HWREG(AES_DMAC_CH0_DMALENGTH) = psMd->curlen; + } + else + { + HWREG(AES_DMAC_CH0_DMALENGTH) = SHA256_BLOCK_SIZE; + } + + // enable DMA channel 1 for result digest + HWREG(AES_DMAC_CH1_CTRL) |= AES_DMAC_CH1_CTRL_EN; + // base address of the digest buffer + HWREG(AES_DMAC_CH1_EXTADDR) = (uint32_t)ui8Out; + // length of the result digest + HWREG(AES_DMAC_CH1_DMALENGTH) = SHA256_OUTPUT_LEN; + + // wait for completion of the operation + do + { + ASM_NOP; + } + while(!(HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)); + + + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) + { + return (AES_DMA_BUS_ERROR); + } + + // clear the interrupt + HWREG(AES_CTRL_INT_CLR) = (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + // disable master control/DMA clock + HWREG(AES_CTRL_ALG_SEL) = 0x00000000; + // clear mode + HWREG(AES_AES_CTRL) = 0x00000000; + + return (SHA256_SUCCESS); +} + +//***************************************************************************** +// +//! SHA256HashResume function resumes an already started hash session in +//! hardware. +//! +//! \param psMd is the hash state. +//! \param ui8In is the pointer to the input message. +//! \param ui8Out is the pointer to the destination of the hash (32 bytes). +//! +//! \return SHA256_SUCCESS if successful. +// +//***************************************************************************** +uint8_t SHA256HashResume(tSHA256State * psMd, uint8_t *ui8In, uint8_t *ui8Out) +{ + IntDisable(INT_AES); + // workaround for AES registers not retained after PM2 + HWREG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + HWREG(AES_CTRL_INT_EN) = (AES_CTRL_INT_EN_RESULT_AV | + AES_CTRL_INT_EN_DMA_IN_DONE); + + // configure master control module and enable + // the DMA path to the SHA-256 engine + // + HWREG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_HASH; + + // clear any outstanding events + HWREG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV; + + // configure hash engine + // indicate the start of a resumed hash session and SHA256 + HWREG(AES_HASH_MODE_IN) = AES_HASH_MODE_IN_SHA256_MODE; + + // if the final digest is required (pad the input DMA data) + if(psMd->final_digest) + { + // write length of the message (lo) + HWREG(AES_HASH_LENGTH_IN_L) = (uint32_t)psMd->length; + // write length of the message (hi) + HWREG(AES_HASH_LENGTH_IN_H) = (uint32_t)(psMd->length >> 16); + } + + // write the initial digest + HWREG(AES_HASH_DIGEST_A) = (uint32_t)psMd->state[0]; + HWREG(AES_HASH_DIGEST_B) = (uint32_t)psMd->state[1]; + HWREG(AES_HASH_DIGEST_C) = (uint32_t)psMd->state[2]; + HWREG(AES_HASH_DIGEST_D) = (uint32_t)psMd->state[3]; + HWREG(AES_HASH_DIGEST_E) = (uint32_t)psMd->state[4]; + HWREG(AES_HASH_DIGEST_F) = (uint32_t)psMd->state[5]; + HWREG(AES_HASH_DIGEST_G) = (uint32_t)psMd->state[6]; + HWREG(AES_HASH_DIGEST_H) = (uint32_t)psMd->state[7]; + + // If final digest, pad the DMA-ed data + if(psMd->final_digest) + { + HWREG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE; + } + + // enable DMA channel 0 for message data + HWREG(AES_DMAC_CH0_CTRL) |= AES_DMAC_CH0_CTRL_EN; + // base address of the data in ext. memory + HWREG(AES_DMAC_CH0_EXTADDR) = (uint32_t)ui8In; + // input data length in bytes, equal to the message + if(psMd->final_digest) + { + HWREG(AES_DMAC_CH0_DMALENGTH) = psMd->curlen; + } + else + { + HWREG(AES_DMAC_CH0_DMALENGTH) = SHA256_BLOCK_SIZE; + } + + // wait for completion of the operation + do + { + ASM_NOP; + } + while(!(HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)); + + // check for any DMA Bus errors + if((HWREG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR)) + { + return (AES_DMA_BUS_ERROR); + } + + // read digest + ((uint32_t *)ui8Out)[0] = HWREG(AES_HASH_DIGEST_A); + ((uint32_t *)ui8Out)[1] = HWREG(AES_HASH_DIGEST_B); + ((uint32_t *)ui8Out)[2] = HWREG(AES_HASH_DIGEST_C); + ((uint32_t *)ui8Out)[3] = HWREG(AES_HASH_DIGEST_D); + ((uint32_t *)ui8Out)[4] = HWREG(AES_HASH_DIGEST_E); + ((uint32_t *)ui8Out)[5] = HWREG(AES_HASH_DIGEST_F); + ((uint32_t *)ui8Out)[6] = HWREG(AES_HASH_DIGEST_G); + ((uint32_t *)ui8Out)[7] = HWREG(AES_HASH_DIGEST_H); + + // acknowledge reading of the digest + HWREG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_OUTPUT_FULL; + + // clear the interrupt + HWREG(AES_CTRL_INT_CLR) = (AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV); + // acknowledge result and clear interrupts + // disable master control/DMA clock + HWREG(AES_CTRL_ALG_SEL) = 0x00000000; + // clear mode + HWREG(AES_AES_CTRL) = 0x00000000; + + return (SHA256_SUCCESS); +} + +//***************************************************************************** +// +//! Close the Doxygen group. +//! @} +// +//***************************************************************************** + diff --git a/bsp/boards/mimsy2-cc2538/source/sha256.h b/bsp/boards/mimsy2-cc2538/source/sha256.h new file mode 100644 index 0000000000..1a1823a04c --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/sha256.h @@ -0,0 +1,96 @@ +/****************************************************************************** +* Filename: sha256.c +* Revised: $Date: 2013-03-22 16:13:31 +0100 (Fri, 22 Mar 2013) $ +* Revision: $Revision: 9513 $ +* +* Description: Header file for hardware SHA 256 +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __SHA256_H__ +#define __SHA256_H__ + +#include + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// General constants +// +//***************************************************************************** +#define SHA256_BLOCK_SIZE 64 +#define SHA256_OUTPUT_LEN 32 +#define HASH_SHA256_MAX_BLOCK_LEN 64 + +// SHA256 structures +typedef struct { + uint64_t length; + uint32_t state[8]; + uint32_t curlen; + uint8_t buf[64]; + uint8_t new_digest; + uint8_t final_digest; +} tSHA256State; + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +// SHA256 functions +extern uint8_t SHA256Init(tSHA256State *psMd); +extern uint8_t SHA256Process(tSHA256State *psMd, + uint8_t *ui8In, + uint32_t ui32InLen); +extern uint8_t SHA256Done(tSHA256State *psMd, uint8_t *ui8Out); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __SHA256_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/sleepmode.c b/bsp/boards/mimsy2-cc2538/source/sleepmode.c new file mode 100644 index 0000000000..12d26b16a2 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/sleepmode.c @@ -0,0 +1,303 @@ +/****************************************************************************** +* Filename: sleepmode.c +* Revised: $Date: 2013-03-22 16:13:31 +0100 (Fri, 22 Mar 2013) $ +* Revision: $Revision: 9513 $ +* +* Description: Driver for the Sleep Mode Timer Module. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup sleepmodetimer_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include "debug.h" +#include "interrupt.h" +#include "sleepmode.h" + +//***************************************************************************** +// +//! Registers an interrupt handler for Sleep Mode Timer interrupt +//! +//! \param pfnHandler is a pointer to the function to be called when the +//! Sleep Mode Timer interrupt occurs. +//! +//! This function does the actual registering of the interrupt handler, thus +//! enabling the global interrupt in the interrupt controller. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +SleepModeIntRegister(void (*pfnHandler)(void)) +{ + // + // Register the interrupt handler. + // + IntRegister(INT_SMTIM, pfnHandler); + + // + // Enable the sleep mode timer interrupt. + // + IntEnable(INT_SMTIM); +} + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the sleep mode timer interrupt +//! +//! This function does the actual unregistering of the interrupt handler. This +//! function clears the handler to be called when a compare +//! interrupt occurs and masks off the interrupt in the interrupt controller +//! so that the interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +SleepModeIntUnregister(void) +{ + // + // Disable the interrupt. + // + IntDisable(INT_SMTIM); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_SMTIM); +} + +//***************************************************************************** +// +//! Get current value of the sleep mode timer +//! +//! This function returns the current value of the sleep mode timer (that is, +//! the timer count) +//! +//! \return Current value of the sleep mode timer +// +//***************************************************************************** +uint32_t +SleepModeTimerCountGet(void) +{ + uint32_t ui32Val; + + ui32Val = HWREG(SMWDTHROSC_ST0); + ui32Val |= HWREG(SMWDTHROSC_ST1) << 8; + ui32Val |= HWREG(SMWDTHROSC_ST2) << 16; + ui32Val |= HWREG(SMWDTHROSC_ST3) << 24; + + return ui32Val; +} + + +//***************************************************************************** +// +//! Selects capture port and pin +//! +//! \param ui32Port is the port. +//! \param ui32Pin is the pin number. +//! +//! This function sets the port and pin on which values are to be captured. +//! +//! The \e ui32Port argument must be only one of the following values: +//! \b SLEEPMODE_PORT_A, \b SLEEPMODE_PORT_B, +//! \b SLEEPMODE_PORT_C, \b SLEEPMODE_PORT_D, +//! \b SLEEPMODE_PORT_USB. +//! +//! The \e ui32Pin argument must be only one of the following values: +//! \b SLEEPMODE_PIN_0, \b SLEEPMODE_PIN_1, \b SLEEPMODE_PIN_2, +//! \b SLEEPMODE_PIN_3, \b SLEEPMODE_PIN_4, \b SLEEPMODE_PIN_5, +//! \b SLEEPMODE_PIN_6, \b SLEEPMODE_PIN_7. +//! +//! \note if \e ui32Port is set to \b SLEEPMODE_PORT_USB, only \e ui32Pin +//! \b SLEEPMODE_PIN_0 can be used. +//! +//! \return None +// +//***************************************************************************** +void +SleepModeCaptureConfig(uint32_t ui32Port, uint32_t ui32Pin) +{ + uint32_t ui32Val; + + ASSERT(ui32Port == SLEEPMODE_PORT_A || + ui32Port == SLEEPMODE_PORT_B || + ui32Port == SLEEPMODE_PORT_C || + ui32Port == SLEEPMODE_PORT_D || + (ui32Port == SLEEPMODE_PORT_USB && ui32Pin == SLEEPMODE_PIN_0)); + + ASSERT(ui32Pin == SLEEPMODE_PIN_0 || + ui32Pin == SLEEPMODE_PIN_1 || + ui32Pin == SLEEPMODE_PIN_2 || + ui32Pin == SLEEPMODE_PIN_3 || + ui32Pin == SLEEPMODE_PIN_4 || + ui32Pin == SLEEPMODE_PIN_5 || + ui32Pin == SLEEPMODE_PIN_6 || + ui32Pin == SLEEPMODE_PIN_7); + + + ui32Val = HWREG(SMWDTHROSC_STCC); + ui32Val &= ~(SMWDTHROSC_STCC_PORT_M | SMWDTHROSC_STCC_PIN_M); + ui32Val |= ui32Port | ui32Pin; + HWREG(SMWDTHROSC_STCC) = ui32Val; + +} + +//***************************************************************************** +// +//! Set compare value of the sleep mode timer +//! +//! \param ui32Compare is a 32-bit compare value. +//! +//! This function sets the compare value of the sleep mode timer. +//! A timer compare interrupt is generated when the timer value is equal to +//! the compare value. +//! +//! \note When setting a new compare value, the value must be at least 5 more +//! than the current sleep timer value. Otherwise, the timer compare event +//! might be lost. +//! +//! \return None +// +//***************************************************************************** +void +SleepModeTimerCompareSet(uint32_t ui32Compare) +{ + // + // Wait for ST0, ST3 regs to be ready for writing + // + while(!(HWREG(SMWDTHROSC_STLOAD) & SMWDTHROSC_STLOAD_STLOAD)) + { + } + + HWREG(SMWDTHROSC_ST3) = (ui32Compare >> 24) & 0x000000ff; + HWREG(SMWDTHROSC_ST2) = (ui32Compare >> 16) & 0x000000ff; + HWREG(SMWDTHROSC_ST1) = (ui32Compare >> 8) & 0x000000ff; + HWREG(SMWDTHROSC_ST0) = ui32Compare & 0x000000ff; +} + + +//***************************************************************************** +// +//! Get last capture value +//! +//! This function returns the last captured value. +//! +//! \note The captured value is one more than the value at the instant for the +//! event on the I/O pin. Software should therefore subtract 1 from the +//! captured value if absolute timing is required. +//! +//! \sa SleepModeCaptureNew(), SleepModeCaptureIsValid() +//! +//! \return Last captured value +// +//***************************************************************************** +uint32_t +SleepModeCaptureGet(void) +{ + uint32_t ui32Val; + + ui32Val = HWREG(SMWDTHROSC_STCV0); + ui32Val |= HWREG(SMWDTHROSC_STCV1) << 8; + ui32Val |= HWREG(SMWDTHROSC_STCV2) << 16; + ui32Val |= HWREG(SMWDTHROSC_STCV3) << 24; + + return ui32Val; +} + +//***************************************************************************** +// +//! Checks if capture value has been updated +//! +//! This function returns true if a value has been captured. +//! +//! \sa SleepModeCaptureGet(), SleepModeCaptureNew() +//! +//! \return Returns true if capture value has been updated +// +//***************************************************************************** +bool +SleepModeCaptureIsValid(void) +{ + bool bValid; + + bValid = HWREG(SMWDTHROSC_STCS) & SMWDTHROSC_STCS_VALID; + + return bValid; +} + +//***************************************************************************** +// +//! Prepares for a new value to be captured +//! +//! This function prepares the capture logic to capture a new value. +//! +//! The relevant pin interrupt flag must be cleared after calling this +//! function using IntPendClear(). +//! +//! \sa SleepModeCaptureGet(), SleepModeCaptureIsValid() +//! +//! \return None +// +//***************************************************************************** +void +SleepModeCaptureNew(void) +{ + uint32_t ui32Val; + + ui32Val = HWREG(SMWDTHROSC_STCS); + ui32Val &= ~SMWDTHROSC_STCS_VALID; + HWREG(SMWDTHROSC_STCS) = ui32Val; +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + diff --git a/bsp/boards/mimsy2-cc2538/source/sleepmode.h b/bsp/boards/mimsy2-cc2538/source/sleepmode.h new file mode 100644 index 0000000000..13249ac57a --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/sleepmode.h @@ -0,0 +1,101 @@ +/****************************************************************************** +* Filename: sleepmode.h +* Revised: $Date: 2013-01-21 15:25:21 +0100 (Mon, 21 Jan 2013) $ +* Revision: $Revision: 9178 $ +* +* Description: Prototypes for the Sleep Mode Timer API. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __SLEEPMODE_H__ +#define __SLEEPMODE_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// The following are values that can be passed to the SleepModeCaptureConfig +// function. +// +//***************************************************************************** +#define SLEEPMODE_PORT_A 0x00000000 // Capture Port A +#define SLEEPMODE_PORT_B 0x00000008 // Capture Port B +#define SLEEPMODE_PORT_C 0x00000010 // Capture Port C +#define SLEEPMODE_PORT_D 0x00000018 // Capture Port D +#define SLEEPMODE_PORT_USB 0x00000020 // Capture Port USB + +#define SLEEPMODE_PIN_0 0x00000000 // Capture Pin 0 +#define SLEEPMODE_PIN_1 0x00000001 // Capture Pin 1 (not valid with USB) +#define SLEEPMODE_PIN_2 0x00000002 // Capture Pin 2 (not valid with USB) +#define SLEEPMODE_PIN_3 0x00000003 // Capture Pin 3 (not valid with USB) +#define SLEEPMODE_PIN_4 0x00000004 // Capture Pin 4 (not valid with USB) +#define SLEEPMODE_PIN_5 0x00000005 // Capture Pin 5 (not valid with USB) +#define SLEEPMODE_PIN_6 0x00000006 // Capture Pin 6 (not valid with USB) +#define SLEEPMODE_PIN_7 0x00000007 // Capture Pin 7 (not valid with USB) + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +extern void SleepModeIntRegister(void (*pfnHandler)(void)); +extern void SleepModeIntUnregister(void); +extern uint32_t SleepModeTimerCountGet(void); +extern void SleepModeTimerCompareSet(uint32_t ui32Compare); +extern void SleepModeCaptureConfig(uint32_t ui32Port, uint32_t ui32Pin); +extern void SleepModeCaptureNew(void); +extern uint32_t SleepModeCaptureGet(void); +extern bool SleepModeCaptureIsValid(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __SLEEPMODE_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/ssi.c b/bsp/boards/mimsy2-cc2538/source/ssi.c new file mode 100644 index 0000000000..5edb794ad8 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/ssi.c @@ -0,0 +1,774 @@ +/****************************************************************************** +* Filename: ssi.c +* Revised: $Date: 2013-03-20 14:47:53 +0100 (Wed, 20 Mar 2013) $ +* Revision: $Revision: 9489 $ +* +* Description: Driver for Synchronous Serial Interface. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup ssi_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include "debug.h" +#include "interrupt.h" +#include "ssi.h" + +//***************************************************************************** +// +//! Configures the synchronous serial interface +//! +//! \param ui32Base specifies the SSI module base address. +//! \param ui32SSIClk is the rate of the clock supplied to the SSI module. +//! \param ui32Protocol specifies the data transfer protocol. +//! \param ui32Mode specifies the mode of operation. +//! \param ui32BitRate specifies the clock rate. +//! \param ui32DataWidth specifies number of bits transferred per frame. +//! +//! This function configures the synchronous serial interface. It sets +//! the SSI protocol, mode of operation, bit rate, and data width. +//! +//! The \e ui32Protocol parameter defines the data frame format. The +//! \e ui32Protocol parameter can be one of the following values: +//! \b SSI_FRF_MOTO_MODE_0, \b SSI_FRF_MOTO_MODE_1, \b SSI_FRF_MOTO_MODE_2, +//! \b SSI_FRF_MOTO_MODE_3, \b SSI_FRF_TI, or \b SSI_FRF_NMW. The Motorola +//! frame formats imply the following polarity and phase configurations: +//! +//!
+//! Polarity Phase       Mode
+//!   0       0   SSI_FRF_MOTO_MODE_0
+//!   0       1   SSI_FRF_MOTO_MODE_1
+//!   1       0   SSI_FRF_MOTO_MODE_2
+//!   1       1   SSI_FRF_MOTO_MODE_3
+//! 
+//! +//! The \e ui32Mode parameter defines the operating mode of the SSI module. The +//! SSI module can operate as a master or slave; if a slave, the SSI can be +//! configured to disable output on its serial output line. The \e ui32Mode +//! parameter can be one of the following values: \b SSI_MODE_MASTER, +//! \b SSI_MODE_SLAVE, or \b SSI_MODE_SLAVE_OD. +//! +//! The \e ui32BitRate parameter defines the bit rate for the SSI. This bit rate +//! must satisfy the following clock ratio criteria: +//! +//! - FSSI >= 2 * bit rate (master mode) +//! - FSSI >= 12 * bit rate (slave modes) +//! +//! where FSSI is the frequency of the clock supplied to the SSI module. +//! +//! The \e ui32DataWidth parameter defines the width of the data transfers, and +//! can be a value between 4 and 16, inclusive. +//! +//! The peripheral clock is set in the System Control module. The frequency of +//! the system clock is the value returned by SysCtrlClockGet() or +//! SysCtrlIOClockGet() depending on the chosen clock source as set by +//! SSIClockSourceSet(), or it can be explicitly hard coded if it is constant +//! and known (to save the code/execution overhead of a call to +//! SysCtrlClockGet() or SysCtrlIOClockGet()). +//! +//! \return None +// +//***************************************************************************** +void +SSIConfigSetExpClk(uint32_t ui32Base, uint32_t ui32SSIClk, + uint32_t ui32Protocol, uint32_t ui32Mode, + uint32_t ui32BitRate, uint32_t ui32DataWidth) +{ + uint32_t ui32MaxBitRate; + uint32_t ui32RegVal; + uint32_t ui32PreDiv; + uint32_t ui32SCR; + uint32_t ui32SPH_SPO; + + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + ASSERT((ui32Protocol == SSI_FRF_MOTO_MODE_0) || + (ui32Protocol == SSI_FRF_MOTO_MODE_1) || + (ui32Protocol == SSI_FRF_MOTO_MODE_2) || + (ui32Protocol == SSI_FRF_MOTO_MODE_3) || + (ui32Protocol == SSI_FRF_TI) || + (ui32Protocol == SSI_FRF_NMW)); + ASSERT((ui32Mode == SSI_MODE_MASTER) || + (ui32Mode == SSI_MODE_SLAVE) || + (ui32Mode == SSI_MODE_SLAVE_OD)); + ASSERT(((ui32Mode == SSI_MODE_MASTER) && (ui32BitRate <= (ui32SSIClk / 2))) || + ((ui32Mode != SSI_MODE_MASTER) && (ui32BitRate <= (ui32SSIClk / 12)))); + ASSERT((ui32SSIClk / ui32BitRate) <= (254 * 256)); + ASSERT((ui32DataWidth >= 4) && (ui32DataWidth <= 16)); + + // + // Set the mode. + // + ui32RegVal = (ui32Mode == SSI_MODE_SLAVE_OD) ? SSI_CR1_SOD : 0; + ui32RegVal |= (ui32Mode == SSI_MODE_MASTER) ? 0 : SSI_CR1_MS; + HWREG(ui32Base + SSI_O_CR1) = ui32RegVal; + + // + // Set the clock predivider. + // + ui32MaxBitRate = ui32SSIClk / ui32BitRate; + ui32PreDiv = 0; + do + { + ui32PreDiv += 2; + ui32SCR = (ui32MaxBitRate / ui32PreDiv) - 1; + } + while(ui32SCR > 255); + HWREG(ui32Base + SSI_O_CPSR) = ui32PreDiv; + + // + // Set protocol and clock rate. + // + ui32SPH_SPO = (ui32Protocol & 3) << 6; + ui32Protocol &= SSI_CR0_FRF_M; + ui32RegVal = (ui32SCR << 8) | ui32SPH_SPO | ui32Protocol | (ui32DataWidth - 1); + HWREG(ui32Base + SSI_O_CR0) = ui32RegVal; +} + +//***************************************************************************** +// +//! Enables the synchronous serial interface +//! +//! \param ui32Base specifies the SSI module base address. +//! +//! This function enables operation of the synchronous serial interface. The +//! synchronous serial interface must be configured before it is enabled. +//! +//! \return None +// +//***************************************************************************** +void +SSIEnable(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Read-modify-write the enable bit. + // + HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_SSE; +} + +//***************************************************************************** +// +//! Disables the synchronous serial interface +//! +//! \param ui32Base specifies the SSI module base address. +//! +//! This function disables operation of the synchronous serial interface. +//! +//! \return None +// +//***************************************************************************** +void +SSIDisable(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Read-modify-write the enable bit. + // + HWREG(ui32Base + SSI_O_CR1) &= ~(SSI_CR1_SSE); +} + +//***************************************************************************** +// +//! Registers an interrupt handler for the synchronous serial interface +//! +//! \param ui32Base specifies the SSI module base address. +//! \param pfnHandler is a pointer to the function to be called when the +//! synchronous serial interface interrupt occurs. +//! +//! This sets the handler to be called when an SSI interrupt +//! occurs. This will enable the global interrupt in the interrupt controller; +//! specific SSI interrupts must be enabled via SSIIntEnable(). If necessary, +//! it is the interrupt handler's responsibility to clear the interrupt source +//! via SSIIntClear(). +//! +//! \sa See IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +SSIIntRegister(uint32_t ui32Base, void (*pfnHandler)(void)) +{ + uint32_t ui32Int; + + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Determine the interrupt number based on the SSI port. + // + ui32Int = (ui32Base == SSI0_BASE) ? INT_SSI0 : INT_SSI1; + + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(ui32Int, pfnHandler); + + // + // Enable the synchronous serial interface interrupt. + // + IntEnable(ui32Int); +} + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the synchronous serial interface +//! +//! \param ui32Base specifies the SSI module base address. +//! +//! This function will clear the handler to be called when a SSI +//! interrupt occurs. This will also mask off the interrupt in the interrupt +//! controller so that the interrupt handler no longer is called. +//! +//! \sa See IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +SSIIntUnregister(uint32_t ui32Base) +{ + uint32_t ui32Int; + + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Determine the interrupt number based on the SSI port. + // + ui32Int = (ui32Base == SSI0_BASE) ? INT_SSI0 : INT_SSI1; + + // + // Disable the interrupt. + // + IntDisable(ui32Int); + + // + // Unregister the interrupt handler. + // + IntUnregister(ui32Int); +} + +//***************************************************************************** +// +//! Enables individual SSI interrupt sources +//! +//! \param ui32Base specifies the SSI module base address. +//! \param ui32IntFlags is a bit mask of the interrupt sources to be enabled. +//! +//! Enables the indicated SSI interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. The \e ui32IntFlags parameter can be any of the +//! \b SSI_TXFF, \b SSI_RXFF, \b SSI_RXTO, or \b SSI_RXOR values. +//! +//! \return None +// +//***************************************************************************** +void +SSIIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Enable the specified interrupts. + // + HWREG(ui32Base + SSI_O_IM) |= ui32IntFlags; +} + +//***************************************************************************** +// +//! Disables individual SSI interrupt sources +//! +//! \param ui32Base specifies the SSI module base address. +//! \param ui32IntFlags is a bit mask of the interrupt sources to be disabled. +//! +//! Disables the indicated SSI interrupt sources. The \e ui32IntFlags parameter +//! can be any of the \b SSI_TXFF, \b SSI_RXFF, \b SSI_RXTO, or \b SSI_RXOR +//! values. +//! +//! \return None +// +//***************************************************************************** +void +SSIIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Disable the specified interrupts. + // + HWREG(ui32Base + SSI_O_IM) &= ~(ui32IntFlags); +} + +//***************************************************************************** +// +//! Gets the current interrupt status +//! +//! \param ui32Base specifies the SSI module base address. +//! \param bMasked is \b false if the raw interrupt status is required or +//! \b true if the masked interrupt status is required. +//! +//! This function returns the interrupt status for the SSI module. Either the +//! raw interrupt status or the status of interrupts that are allowed to +//! reflect to the processor can be returned. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! \b SSI_TXFF, \b SSI_RXFF, \b SSI_RXTO, and \b SSI_RXOR. +// +//***************************************************************************** +uint32_t +SSIIntStatus(uint32_t ui32Base, bool bMasked) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(ui32Base + SSI_O_MIS)); + } + else + { + return(HWREG(ui32Base + SSI_O_RIS)); + } +} + +//***************************************************************************** +// +//! Clears SSI interrupt sources +//! +//! \param ui32Base specifies the SSI module base address. +//! \param ui32IntFlags is a bit mask of the interrupt sources to be cleared. +//! +//! The specified SSI interrupt sources are cleared so that they no longer +//! assert. This function must be called in the interrupt handler to keep the +//! interrupts from being recognized again immediately upon exit. The +//! \e ui32IntFlags parameter can consist of either or both the \b SSI_RXTO and +//! \b SSI_RXOR values. +//! +//! \note Because there is a write buffer in the Cortex-M3 processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \return None +// +//***************************************************************************** +void +SSIIntClear(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Clear the requested interrupt sources. + // + HWREG(ui32Base + SSI_O_ICR) = ui32IntFlags; +} + +//***************************************************************************** +// +//! Puts a data element into the SSI transmit FIFO +//! +//! \param ui32Base specifies the SSI module base address. +//! \param ui32Data is the data to be transmitted over the SSI interface. +//! +//! This function places the supplied data into the transmit FIFO of the +//! specified SSI module. +//! +//! \note The upper 32 - N bits of the \e ui32Data are discarded by the hardware, +//! where N is the data width as configured by SSIConfigSetExpClk(). For +//! example, if the interface is configured for 8-bit data width, the upper 24 +//! bits of \e ui32Data are discarded. +//! +//! \return None +// +//***************************************************************************** +void +SSIDataPut(uint32_t ui32Base, uint32_t ui32Data) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + ASSERT((ui32Data & (0xfffffffe << (HWREG(ui32Base + SSI_O_CR0) & + SSI_CR0_DSS_M))) == 0); + + // + // Wait until there is space. + // + while(!(HWREG(ui32Base + SSI_O_SR) & SSI_SR_TNF)) + { + } + + // + // Write the data to the SSI. + // + HWREG(ui32Base + SSI_O_DR) = ui32Data; +} + +//***************************************************************************** +// +//! Puts a data element into the SSI transmit FIFO +//! +//! \param ui32Base specifies the SSI module base address. +//! \param ui32Data is the data to be transmitted over the SSI interface. +//! +//! This function places the supplied data into the transmit FIFO of the +//! specified SSI module. If there is no space in the FIFO, then this function +//! returns a zero. +//! +//! \note The upper 32 - N bits of the \e ui32Data are discarded by the hardware, +//! where N is the data width as configured by SSIConfigSetExpClk(). For +//! example, if the interface is configured for 8-bit data width, the upper 24 +//! bits of \e ui32Data are discarded. +//! +//! \return Returns the number of elements written to the SSI transmit FIFO. +// +//***************************************************************************** +int32_t +SSIDataPutNonBlocking(uint32_t ui32Base, uint32_t ui32Data) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + ASSERT((ui32Data & (0xfffffffe << (HWREG(ui32Base + SSI_O_CR0) & + SSI_CR0_DSS_M))) == 0); + + // + // Check for space to write. + // + if(HWREG(ui32Base + SSI_O_SR) & SSI_SR_TNF) + { + HWREG(ui32Base + SSI_O_DR) = ui32Data; + return(1); + } + else + { + return(0); + } +} + +//***************************************************************************** +// +//! Gets a data element from the SSI receive FIFO +//! +//! \param ui32Base specifies the SSI module base address. +//! \param pui32Data is a pointer to a storage location for data that was +//! received over the SSI interface. +//! +//! This function gets received data from the receive FIFO of the specified +//! SSI module and places that data into the location specified by the +//! \e pui32Data parameter. +//! +//! \note Only the lower N bits of the value written to \e pui32Data contain +//! valid data, where N is the data width as configured by +//! SSIConfigSetExpClk(). For example, if the interface is configured for +//! 8-bit data width, only the lower 8 bits of the value written to \e pui32Data +//! contain valid data. +//! +//! \return None +// +//***************************************************************************** +void +SSIDataGet(uint32_t ui32Base, uint32_t *pui32Data) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Wait until there is data to be read. + // + while(!(HWREG(ui32Base + SSI_O_SR) & SSI_SR_RNE)) + { + } + + // + // Read data from SSI. + // + *pui32Data = HWREG(ui32Base + SSI_O_DR); +} + +//***************************************************************************** +// +//! Gets a data element from the SSI receive FIFO +//! +//! \param ui32Base specifies the SSI module base address. +//! \param pui32Data is a pointer to a storage location for data that was +//! received over the SSI interface. +//! +//! This function gets received data from the receive FIFO of the specified SSI +//! module and places that data into the location specified by the \e ui32Data +//! parameter. If there is no data in the FIFO, then this function returns a +//! zero. +//! +//! \note Only the lower N bits of the value written to \e pui32Data contain +//! valid data, where N is the data width as configured by +//! SSIConfigSetExpClk(). For example, if the interface is configured for +//! 8-bit data width, only the lower 8 bits of the value written to \e pui32Data +//! contain valid data. +//! +//! \return Returns the number of elements read from the SSI receive FIFO. +// +//***************************************************************************** +int32_t +SSIDataGetNonBlocking(uint32_t ui32Base, uint32_t *pui32Data) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Check for data to read. + // + if(HWREG(ui32Base + SSI_O_SR) & SSI_SR_RNE) + { + *pui32Data = HWREG(ui32Base + SSI_O_DR); + return(1); + } + else + { + return(0); + } +} + +//***************************************************************************** +// +//! Enable SSI DMA operation +//! +//! \param ui32Base is the base address of the SSI port. +//! \param ui32DMAFlags is a bit mask of the DMA features to enable. +//! +//! The specified SSI DMA features are enabled. The SSI can be +//! configured to use DMA for transmit and/or receive data transfers. +//! The \e ui32DMAFlags parameter is the logical OR of any of the following +//! values: +//! +//! - SSI_DMA_RX - enable DMA for receive +//! - SSI_DMA_TX - enable DMA for transmit +//! +//! \note The uDMA controller must also be set up before DMA can be used +//! with the SSI. +//! +//! \return None +// +//***************************************************************************** +void +SSIDMAEnable(uint32_t ui32Base, uint32_t ui32DMAFlags) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Set the requested bits in the SSI DMA control register. + // + HWREG(ui32Base + SSI_O_DMACTL) |= ui32DMAFlags; +} + +//***************************************************************************** +// +//! Disable SSI DMA operation +//! +//! \param ui32Base is the base address of the SSI port. +//! \param ui32DMAFlags is a bit mask of the DMA features to disable. +//! +//! This function is used to disable SSI DMA features that were enabled +//! by SSIDMAEnable(). The specified SSI DMA features are disabled. The +//! \e ui32DMAFlags parameter is the logical OR of any of the following values: +//! +//! - SSI_DMA_RX - disable DMA for receive +//! - SSI_DMA_TX - disable DMA for transmit +//! +//! \return None +// +//***************************************************************************** +void +SSIDMADisable(uint32_t ui32Base, uint32_t ui32DMAFlags) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Clear the requested bits in the SSI DMA control register. + // + HWREG(ui32Base + SSI_O_DMACTL) &= ~ui32DMAFlags; +} + +//***************************************************************************** +// +//! Determines whether the SSI transmitter is busy or not +//! +//! \param ui32Base is the base address of the SSI port. +//! +//! Allows the caller to determine whether all transmitted bytes have cleared +//! the transmitter hardware. If \b false is returned, then the transmit FIFO +//! is empty and all bits of the last transmitted word have left the hardware +//! shift register. +//! +//! \return Returns \b true if the SSI is transmitting or \b false if all +//! transmissions are complete. +// +//***************************************************************************** +bool +SSIBusy(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Determine if the SSI is busy. + // + return((HWREG(ui32Base + SSI_O_SR) & SSI_SR_BSY) ? true : false); +} + +//***************************************************************************** +// +//! Sets the data clock source for the specified SSI peripheral +//! +//! \param ui32Base is the base address of the SSI port. +//! \param ui32Source is the baud clock source for the SSI. +//! +//! This function allows the baud clock source for the SSI to be selected. +//! The possible clock source are the system clock (\b SSI_CLOCK_SYSTEM) or +//! the precision internal oscillator (\b SSI_CLOCK_PIOSC), i.e. the IO clock +//! in the SysCtrl. +//! If \b SSI_CLOCK_SYSTEM is chosen, the IO clock frequency must thus be +//! queried by SysCtrlClockSet(). +//! If \b SSI_CLOCK_PIOSC the SysCtrlIOClockSet() function must be used. +//! +//! Changing the baud clock source will change the data rate generated by the +//! SSI. Therefore, the data rate should be reconfigured after any change to +//! the SSI clock source. +//! +//! \return None +// +//***************************************************************************** +void +SSIClockSourceSet(uint32_t ui32Base, uint32_t ui32Source) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + ASSERT((ui32Source == SSI_CLOCK_SYSTEM) || (ui32Source == SSI_CLOCK_PIOSC)); + + // + // Set the SSI clock source. + // + HWREG(ui32Base + SSI_O_CC) = ui32Source; +} + +//***************************************************************************** +// +//! Gets the data clock source for the specified SSI peripheral +//! +//! \param ui32Base is the base address of the SSI port. +//! +//! This function returns the data clock source for the specified SSI. The +//! possible data clock source are the system clock (\b SSI_CLOCK_SYSTEM) or +//! the precision internal oscillator (\b SSI_CLOCK_PIOSC). +//! +//! \return None +// +//***************************************************************************** +uint32_t +SSIClockSourceGet(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE)); + + // + // Return the SSI clock source. + // + return(HWREG(ui32Base + SSI_O_CC)); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/ssi.h b/bsp/boards/mimsy2-cc2538/source/ssi.h new file mode 100644 index 0000000000..c8e09edda9 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/ssi.h @@ -0,0 +1,137 @@ +/****************************************************************************** +* Filename: ssi.h +* Revised: $Date: 2013-01-25 10:58:16 +0100 (Fri, 25 Jan 2013) $ +* Revision: $Revision: 9248 $ +* +* Description: Prototypes for the Synchronous Serial Interface Driver. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __SSI_H__ +#define __SSI_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// Values that can be passed to SSIIntEnable, SSIIntDisable, and SSIIntClear +// as the ui32IntFlags parameter, and returned by SSIIntStatus. +// +//***************************************************************************** +#define SSI_TXFF 0x00000008 // TX FIFO half full or less +#define SSI_RXFF 0x00000004 // RX FIFO half full or more +#define SSI_RXTO 0x00000002 // RX timeout +#define SSI_RXOR 0x00000001 // RX overrun + +//***************************************************************************** +// +// Values that can be passed to SSIConfigSetExpClk. +// +//***************************************************************************** +#define SSI_FRF_MOTO_MODE_0 0x00000000 // Moto fmt, polarity 0, phase 0 +#define SSI_FRF_MOTO_MODE_1 0x00000002 // Moto fmt, polarity 0, phase 1 +#define SSI_FRF_MOTO_MODE_2 0x00000001 // Moto fmt, polarity 1, phase 0 +#define SSI_FRF_MOTO_MODE_3 0x00000003 // Moto fmt, polarity 1, phase 1 +#define SSI_FRF_TI 0x00000010 // TI frame format +#define SSI_FRF_NMW 0x00000020 // National MicroWire frame format + +#define SSI_MODE_MASTER 0x00000000 // SSI master +#define SSI_MODE_SLAVE 0x00000001 // SSI slave +#define SSI_MODE_SLAVE_OD 0x00000002 // SSI slave with output disabled + +//***************************************************************************** +// +// Values that can be passed to SSIDMAEnable() and SSIDMADisable(). +// +//***************************************************************************** +#define SSI_DMA_TX 0x00000002 // Enable DMA for transmit +#define SSI_DMA_RX 0x00000001 // Enable DMA for receive + +//***************************************************************************** +// +// Values that can be passed to SSIClockSourceSet() or returned from +// SSIClockSourceGet(). +// +//***************************************************************************** +#define SSI_CLOCK_SYSTEM 0x00000000 +#define SSI_CLOCK_PIOSC 0x00000001 + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void SSIConfigSetExpClk(uint32_t ui32Base, uint32_t ui32SSIClk, + uint32_t ui32Protocol, uint32_t ui32Mode, + uint32_t ui32BitRate, + uint32_t ui32DataWidth); +extern void SSIDataGet(uint32_t ui32Base, uint32_t *pui32Data); +extern int32_t SSIDataGetNonBlocking(uint32_t ui32Base, + uint32_t *pui32Data); +extern void SSIDataPut(uint32_t ui32Base, uint32_t ui32Data); +extern int32_t SSIDataPutNonBlocking(uint32_t ui32Base, uint32_t ui32Data); +extern void SSIDisable(uint32_t ui32Base); +extern void SSIEnable(uint32_t ui32Base); +extern void SSIIntClear(uint32_t ui32Base, uint32_t ui32IntFlags); +extern void SSIIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags); +extern void SSIIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags); +extern void SSIIntRegister(uint32_t ui32Base, void (*pfnHandler)(void)); +extern uint32_t SSIIntStatus(uint32_t ui32Base, bool bMasked); +extern void SSIIntUnregister(uint32_t ui32Base); +extern void SSIDMAEnable(uint32_t ui32Base, uint32_t ui32DMAFlags); +extern void SSIDMADisable(uint32_t ui32Base, uint32_t ui32DMAFlags); +extern bool SSIBusy(uint32_t ui32Base); +extern void SSIClockSourceSet(uint32_t ui32Base, uint32_t ui32Source); +extern uint32_t SSIClockSourceGet(uint32_t ui32Base); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __SSI_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/sys_ctrl.c b/bsp/boards/mimsy2-cc2538/source/sys_ctrl.c new file mode 100644 index 0000000000..68388af911 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/sys_ctrl.c @@ -0,0 +1,996 @@ +/****************************************************************************** +* Filename: sys_ctrl.c +* Revised: $Date: 2013-04-29 09:29:18 +0200 (Mon, 29 Apr 2013) $ +* Revision: $Revision: 9921 $ +* +* Description: Driver for the system controller. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup sysctl_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include +#include "cpu.h" +#include "debug.h" +#include "interrupt.h" +#include "sys_ctrl.h" + + +//***************************************************************************** +// +// Arrays that maps the "peripheral set" number (which is stored in the +// third nibble of the SYS_CTRL_PERIPH_* defines) to the SYSCTL register that +// contains the relevant bit for that peripheral. +// +//***************************************************************************** + +// Run mode registers +static const uint32_t g_pui32RCGCRegs[] = +{ + SYS_CTRL_RCGCGPT, + SYS_CTRL_RCGCSSI, + SYS_CTRL_RCGCUART, + SYS_CTRL_RCGCI2C, + SYS_CTRL_RCGCSEC, + SYS_CTRL_RCGCRFC +}; + +// Sleep mode registers +static const uint32_t g_pui32SCGCRegs[] = +{ + SYS_CTRL_SCGCGPT, + SYS_CTRL_SCGCSSI, + SYS_CTRL_SCGCUART, + SYS_CTRL_SCGCI2C, + SYS_CTRL_SCGCSEC, + SYS_CTRL_SCGCRFC +}; + +// Deep sleep mode registers +static const uint32_t g_pui32DCGCRegs[] = +{ + SYS_CTRL_DCGCGPT, + SYS_CTRL_DCGCSSI, + SYS_CTRL_DCGCUART, + SYS_CTRL_DCGCI2C, + SYS_CTRL_DCGCSEC, + SYS_CTRL_DCGCRFC +}; + +// Reset registers +static const uint32_t g_pui32SRRegs[] = +{ + SYS_CTRL_SRGPT, + SYS_CTRL_SRSSI, + SYS_CTRL_SRUART, + SYS_CTRL_SRI2C, + SYS_CTRL_SRSEC, +}; + +// Masks for determining if a peripheral is enabled +static const uint32_t g_pui32DieCfgMask[] = +{ + FLASH_CTRL_DIECFG1_GPTM0_EN, + FLASH_CTRL_DIECFG1_SSI0_EN, + FLASH_CTRL_DIECFG1_UART0_EN, + FLASH_CTRL_DIECFG1_I2C_EN, + FLASH_CTRL_DIECFG2_PKA_EN, + FLASH_CTRL_DIECFG2_RF_CORE_EN +}; + +//***************************************************************************** +// +// This macro extracts the array index out of the peripheral number. +// +//***************************************************************************** +#define SYS_CTRL_PERIPH_INDEX(a) (((a) >> 8) & 0xf) + + +//***************************************************************************** +// +// This macro extracts the peripheral instance number and generates bit mask +// +//***************************************************************************** +#define SYS_CTRL_PERIPH_MASKBIT(a) (0x00000001 << ((a) & 0xf)) + +//***************************************************************************** +// +// This macro extracts the instance number out of the peripheral number. +// +//***************************************************************************** +#define SYS_CTRL_PERIPH_INSTANCE(a) ((a) & 0xf) + +//***************************************************************************** +// +//! \internal +//! Checks a peripheral identifier +//! +//! \param ui32Peripheral is the peripheral identifier. +//! +//! This function determines if a peripheral identifier is valid. +//! +//! \return Returns \b true if the peripheral identifier is valid and \b false +//! otherwise. +// +//***************************************************************************** +#ifdef ENABLE_ASSERT +static bool +SysCtrlPeripheralValid(uint32_t ui32Peripheral) +{ + return((ui32Peripheral == SYS_CTRL_PERIPH_GPT0) || + (ui32Peripheral == SYS_CTRL_PERIPH_GPT1) || + (ui32Peripheral == SYS_CTRL_PERIPH_GPT2) || + (ui32Peripheral == SYS_CTRL_PERIPH_GPT3) || + (ui32Peripheral == SYS_CTRL_PERIPH_SSI0) || + (ui32Peripheral == SYS_CTRL_PERIPH_SSI1) || + (ui32Peripheral == SYS_CTRL_PERIPH_UART0) || + (ui32Peripheral == SYS_CTRL_PERIPH_UART1) || + (ui32Peripheral == SYS_CTRL_PERIPH_I2C) || + (ui32Peripheral == SYS_CTRL_PERIPH_PKA) || + (ui32Peripheral == SYS_CTRL_PERIPH_AES) || + (ui32Peripheral == SYS_CTRL_PERIPH_RFC)); +} +#endif + + +//***************************************************************************** +// +//! Sets the general clocking of the device +//! +//! \param bExternalOsc32k is set to true for applications with +//! external 32kHz crystal. +//! \param bInternalOsc selects internal 1-16MHz RC oscillator. If set to +//! false, the external 0-32MHz crystal is used. +//! \param ui32SysDiv System Clock Setting. +//! +//! This function configures the clocking of the device. +//! The oscillator used and the system clock divider settings are +//! configured with this function. +//! +//! The \e ui32SysDiv argument must be only one of the following values: +//! \b SYS_CTRL_SYSDIV_32MHZ, \b SYS_CTRL_SYSDIV_16MHZ, +//! \b SYS_CTRL_SYSDIV_8MHZ, \b SYS_CTRL_SYSDIV_4MHZ, +//! \b SYS_CTRL_SYSDIV_2MHZ, \b SYS_CTRL_SYSDIV_1MHZ, +//! \b SYS_CTRL_SYSDIV_500KHZ,\b SYS_CTRL_SYSDIV_250KHZ. +//! Note \b SYS_CTRL_SYSDIV_32MHZ can not be selected when Internal Oscillator +//! is selected. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlClockSet(bool bExternalOsc32k, bool bInternalOsc, + uint32_t ui32SysDiv) +{ + uint32_t ui32STA; + uint32_t ui32Reg; + uint32_t ui32TimeoutVal; + uint32_t ui32Osc; + + // check input parameters + ASSERT((ui32SysDiv == SYS_CTRL_SYSDIV_32MHZ || + ui32SysDiv == SYS_CTRL_SYSDIV_16MHZ || + ui32SysDiv == SYS_CTRL_SYSDIV_8MHZ || + ui32SysDiv == SYS_CTRL_SYSDIV_4MHZ || + ui32SysDiv == SYS_CTRL_SYSDIV_2MHZ || + ui32SysDiv == SYS_CTRL_SYSDIV_1MHZ || + ui32SysDiv == SYS_CTRL_SYSDIV_500KHZ || + ui32SysDiv == SYS_CTRL_SYSDIV_250KHZ) && + !((ui32SysDiv == SYS_CTRL_SYSDIV_32MHZ) && bInternalOsc)); + + // + // Enable AMP detect to make sure XOSC starts correctly + // + if(!bInternalOsc) + { + ui32Reg = HWREG(SYS_CTRL_CLOCK_CTRL) | SYS_CTRL_CLOCK_CTRL_AMP_DET; + HWREG(SYS_CTRL_CLOCK_CTRL) = ui32Reg; + } + + // + // Set 32kHz clock, Osc and SysDiv + // + ui32Reg = HWREG(SYS_CTRL_CLOCK_CTRL); + ui32Reg &= ~(SYS_CTRL_CLOCK_CTRL_OSC32K | SYS_CTRL_CLOCK_CTRL_OSC | + SYS_CTRL_CLOCK_CTRL_SYS_DIV_M); + if(!bExternalOsc32k) + { + ui32Reg |= SYS_CTRL_CLOCK_CTRL_OSC32K; + } + ui32Osc = bInternalOsc ? SYS_CTRL_CLOCK_CTRL_OSC : 0; + ui32Reg |= ui32Osc; + ui32Reg |= ui32SysDiv; + HWREG(SYS_CTRL_CLOCK_CTRL) = ui32Reg; + + // + // Note: This wait loop could potentially be removed, if caution + // is taken in code running after this call. + // + // If we have changed Osc settings, wait until change happens + // + ui32STA = HWREG(SYS_CTRL_CLOCK_STA); + ui32TimeoutVal = 0; + while((ui32Osc != (ui32STA & SYS_CTRL_CLOCK_CTRL_OSC)) && + (ui32TimeoutVal < SYS_CTRL_TIMEOUT)) + { + SysCtrlDelay(16); + ui32STA = HWREG(SYS_CTRL_CLOCK_STA); + ui32TimeoutVal++; + } + ASSERT(ui32TimeoutVal < SYS_CTRL_TIMEOUT); + +} // SysCtrlClockSet + + +//***************************************************************************** +// +//! Gets the processor clock rate +//! +//! This function determines the clock rate of the processor clock. +//! +//! \return The processor clock rate +// +//***************************************************************************** +uint32_t +SysCtrlClockGet(void) +{ + uint32_t ui32Clk; + uint32_t ui32STA; + uint32_t ui32SysDiv; + + ui32STA = HWREG(SYS_CTRL_CLOCK_STA); + ui32SysDiv = + (ui32STA & SYS_CTRL_CLOCK_STA_SYS_DIV_M) >> SYS_CTRL_CLOCK_STA_SYS_DIV_S; + ui32Clk = 0; + + switch(ui32SysDiv) + { + case SYS_CTRL_SYSDIV_32MHZ: + ui32Clk = SYS_CTRL_32MHZ; + break; + case SYS_CTRL_SYSDIV_16MHZ: + ui32Clk = SYS_CTRL_16MHZ; + break; + case SYS_CTRL_SYSDIV_8MHZ: + ui32Clk = SYS_CTRL_8MHZ; + break; + case SYS_CTRL_SYSDIV_4MHZ: + ui32Clk = SYS_CTRL_4MHZ; + break; + case SYS_CTRL_SYSDIV_2MHZ: + ui32Clk = SYS_CTRL_2MHZ; + break; + case SYS_CTRL_SYSDIV_1MHZ: + ui32Clk = SYS_CTRL_1MHZ; + break; + case SYS_CTRL_SYSDIV_500KHZ: + ui32Clk = SYS_CTRL_500KHZ; + break; + case SYS_CTRL_SYSDIV_250KHZ: + ui32Clk = SYS_CTRL_250KHZ; + break; + } + + // + // Return the computed clock rate. + // + return(ui32Clk); +} // SysCtrlClockGet + +//***************************************************************************** +// +//! Sets the IO clocking of the device +//! +//! \param ui32IODiv System Clock Setting. +//! +//! This function configures the IO clocking of the device (that is, the +//! Baud rate clock for SSI and UART). +//! +//! The \e ui32IODiv argument must be only one of the following values: +//! \b SYS_CTRL_SYSDIV_32MHZ, \b SYS_CTRL_SYSDIV_16MHZ, +//! \b SYS_CTRL_SYSDIV_8MHZ, \b SYS_CTRL_SYSDIV_4MHZ, +//! \b SYS_CTRL_SYSDIV_2MHZ, \b SYS_CTRL_SYSDIV_1MHZ, +//! \b SYS_CTRL_SYSDIV_500KHZ,\b SYS_CTRL_SYSDIV_250KHZ. +//! +//! Note \b SYS_CTRL_SYSDIV_32MHZ cannot be selected when Internal Oscillator +//! is selected. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlIOClockSet(uint32_t ui32IODiv) +{ + uint32_t ui32RegVal; + + // check input parameters + ASSERT(ui32IODiv == SYS_CTRL_SYSDIV_32MHZ || + ui32IODiv == SYS_CTRL_SYSDIV_16MHZ || + ui32IODiv == SYS_CTRL_SYSDIV_8MHZ || + ui32IODiv == SYS_CTRL_SYSDIV_4MHZ || + ui32IODiv == SYS_CTRL_SYSDIV_2MHZ || + ui32IODiv == SYS_CTRL_SYSDIV_1MHZ || + ui32IODiv == SYS_CTRL_SYSDIV_500KHZ || + ui32IODiv == SYS_CTRL_SYSDIV_250KHZ); + + ui32RegVal = HWREG(SYS_CTRL_CLOCK_CTRL); + ui32RegVal &= ~SYS_CTRL_CLOCK_CTRL_IO_DIV_M; + ui32RegVal |= (ui32IODiv << SYS_CTRL_CLOCK_CTRL_IO_DIV_S); + HWREG(SYS_CTRL_CLOCK_CTRL) = ui32RegVal; +} // SysCtrlIOClockSet + + +//***************************************************************************** +// +//! Gets the IO clock rate +//! +//! This function returns the IO clocking of the device, i.e. the Baud +//! rate clock for SSI and UART. +//! +//! \return The IO clock rate +// +//***************************************************************************** +uint32_t +SysCtrlIOClockGet(void) +{ + uint32_t ui32Clk; + uint32_t ui32STA; + uint32_t ui32IODiv; + + ui32STA = HWREG(SYS_CTRL_CLOCK_STA); + ui32IODiv = + (ui32STA & SYS_CTRL_CLOCK_STA_IO_DIV_M) >> SYS_CTRL_CLOCK_STA_IO_DIV_S; + + ui32Clk = 0; + + switch(ui32IODiv) + { + case SYS_CTRL_SYSDIV_32MHZ: + ui32Clk = SYS_CTRL_32MHZ; + break; + case SYS_CTRL_SYSDIV_16MHZ: + ui32Clk = SYS_CTRL_16MHZ; + break; + case SYS_CTRL_SYSDIV_8MHZ: + ui32Clk = SYS_CTRL_8MHZ; + break; + case SYS_CTRL_SYSDIV_4MHZ: + ui32Clk = SYS_CTRL_4MHZ; + break; + case SYS_CTRL_SYSDIV_2MHZ: + ui32Clk = SYS_CTRL_2MHZ; + break; + case SYS_CTRL_SYSDIV_1MHZ: + ui32Clk = SYS_CTRL_1MHZ; + break; + case SYS_CTRL_SYSDIV_500KHZ: + ui32Clk = SYS_CTRL_500KHZ; + break; + case SYS_CTRL_SYSDIV_250KHZ: + ui32Clk = SYS_CTRL_250KHZ; + break; + } + + // + // Return the computed clock rate. + // + return(ui32Clk); +} // SysCtrlIOClockGet + + +//***************************************************************************** +// +//! Provides a small delay +//! +//! \param ui32Count is the number of delay loop iterations to perform. +//! +//! This function provides a means of generating a constant length delay and +//! is written in assembly to keep the delay consistent across tool chains, +//! avoiding the need to tune the delay based on the tool chain in use. +//! +//! The loop takes 3 cycles/loop. +//! +//! \return None +// +//***************************************************************************** +#if defined(__ICCARM__) || defined(DOXYGEN) +void +SysCtrlDelay(uint32_t ui32Count) +{ + __asm(" subs r0, #1\n" + " bne.n SysCtrlDelay\n" + " bx lr"); +} +#endif +#if defined(__GNUC__) +void __attribute__((naked)) +SysCtrlDelay(uint32_t ui32Count) +{ + __asm(" subs r0, #1\n" + " bne SysCtrlDelay\n" + " bx lr"); +} +#endif +#if defined(__KEIL__) || defined(__ARMCC_VERSION) +__asm void +SysCtrlDelay(uint32_t ui32Count) +{ + subs r0, #1; + bne SysCtrlDelay; + bx lr; +} +#endif +// +// For CCS implement this function in pure assembly. This prevents the TI +// compiler from doing funny things with the optimizer. +// +#if defined(__TI_COMPILER_VERSION__) +__asm(" .sect \".text:SysCtrlDelay\"\n" + " .clink\n" + " .thumbfunc SysCtrlDelay\n" + " .thumb\n" + " .global SysCtrlDelay\n" + "SysCtrlDelay:\n" + " subs r0, #1\n" + " bne.n SysCtrlDelay\n" + " bx lr\n"); +#endif + + +//***************************************************************************** +// +//! Resets the device +//! +//! This function performs a software reset of the entire device. The +//! processor and all peripherals are reset and all device registers are +//! returned to their default values. +//! +//! \return This function does not return. +// +//***************************************************************************** +void +SysCtrlReset(void) +{ + // + // Perform a software reset request. This request causes the device to + // reset, no further code is executed. + // + HWREG(SYS_CTRL_PWRDBG) = SYS_CTRL_PWRDBG_FORCE_WARM_RESET; + + // + // The device should have reset, so this should never be reached. Just in + // case, loop forever. + // + while(1) + { + } +} + + +//***************************************************************************** +// +//! Puts the processor into sleep mode +//! +//! This function places the processor into sleep mode and does not return +//! until the processor returns to run mode. The peripherals that are enabled +//! by SysCtrlPeripheralSleepEnable() continue to operate and can wake up the +//! processor. +//! +//! \sa SysCtrlPeripheralSleepEnable() +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlSleep(void) +{ + // + // Wait for an interrupt. + // + CPUwfi(); +} + + +//***************************************************************************** +// +//! Puts the processor into deep-sleep mode +//! +//! This function places the processor into deep-sleep mode and does not return +//! until the processor returns to run mode. The peripherals that are enabled +//! by SysCtrlPeripheralDeepSleepEnable() continue to operate and can wake up +//! the processor (if not in power mode 1, 2, or 3). +//! Note the power mode should be set before going into deep sleep. +//! +//! \sa SysCtrlPowerModeSet(), SysCtrlPeripheralDeepSleepEnable() +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlDeepSleep(void) +{ +#ifndef NO_CLOCK_DIVIDER_RESTORE + bool bRestoreSys; + bool bRestoreIO; + uint32_t ui32Reg; + + ui32Reg = HWREG(SYS_CTRL_CLOCK_STA); + bRestoreSys = (ui32Reg & SYS_CTRL_CLOCK_STA_SYS_DIV_M)==0; + bRestoreIO = (ui32Reg & SYS_CTRL_CLOCK_STA_IO_DIV_M)==0; + if(bRestoreSys || bRestoreIO) + { + ui32Reg = HWREG(SYS_CTRL_CLOCK_CTRL); + ui32Reg |= bRestoreSys? 0x1:0x0; + ui32Reg |= bRestoreIO? 0x100:0x0; + HWREG(SYS_CTRL_CLOCK_CTRL) = ui32Reg; + } +#endif + + // + // Enable deep-sleep. + // + HWREG(NVIC_SYS_CTRL) |= NVIC_SYS_CTRL_SLEEPDEEP; + + // + // Wait for an interrupt. + // + CPUwfi(); + + // + // Disable deep-sleep so that a future sleep will work correctly. + // + HWREG(NVIC_SYS_CTRL) &= ~(NVIC_SYS_CTRL_SLEEPDEEP); + +#ifndef NO_CLOCK_DIVIDER_RESTORE + if(bRestoreSys || bRestoreIO) + { + ui32Reg = HWREG(SYS_CTRL_CLOCK_CTRL); + ui32Reg &= bRestoreSys ? ~SYS_CTRL_CLOCK_CTRL_SYS_DIV_M : 0xffffffff; + ui32Reg &= bRestoreIO ? ~SYS_CTRL_CLOCK_CTRL_IO_DIV_M : 0xffffffff; + HWREG(SYS_CTRL_CLOCK_CTRL) = ui32Reg; + } +#endif +} + + + +//***************************************************************************** +// +//! Determines if a peripheral is present +//! +//! \param ui32Peripheral is the peripheral in question. +//! +//! Determines if a particular peripheral is present in the device (that is, +//! is not permanently disabled). +//! +//! The \e ui32Peripheral parameter must be one of the values: +//! \b SYS_CTRL_PERIPH_GPT0 , \b SYS_CTRL_PERIPH_GPT1, +//! \b SYS_CTRL_PERIPH_GPT2, \b SYS_CTRL_PERIPH_GPT3, +//! \b SYS_CTRL_PERIPH_SSI0, \b SYS_CTRL_PERIPH_SSI1, +//! \b SYS_CTRL_PERIPH_UART0, \b SYS_CTRL_PERIPH_UART1, +//! \b SYS_CTRL_PERIPH_I2C, \b SYS_CTRL_PERIPH_PKA, +//! \b SYS_CTRL_PERIPH_AES, \b SYS_CTRL_PERIPH_RFC. +//! +//! \return Returns \b true if the specified peripheral is present and \b false +//! if it is permanently disabled. +// +//***************************************************************************** +bool +SysCtrlPeripheralPresent(uint32_t ui32Peripheral) +{ + uint32_t ui32DieCfg; + uint32_t ui32Mask; + + // Check the arguments. + ASSERT(SysCtrlPeripheralValid(ui32Peripheral)); + + if(SYS_CTRL_PERIPH_INDEX(ui32Peripheral) == + SYS_CTRL_PERIPH_INDEX(SYS_CTRL_PERIPH_PKA) || + SYS_CTRL_PERIPH_INDEX(ui32Peripheral) == + SYS_CTRL_PERIPH_INDEX(SYS_CTRL_PERIPH_AES) || + SYS_CTRL_PERIPH_INDEX(ui32Peripheral) == + SYS_CTRL_PERIPH_INDEX(SYS_CTRL_PERIPH_RFC)) + { + ui32DieCfg = HWREG(FLASH_CTRL_DIECFG2); + } + else + { + ui32DieCfg = HWREG(FLASH_CTRL_DIECFG1); + } + + ui32Mask = (g_pui32DieCfgMask[SYS_CTRL_PERIPH_INDEX(ui32Peripheral)] << + SYS_CTRL_PERIPH_INSTANCE(ui32Peripheral)); + + // Mask with correct mask and determine if this peripheral is + // permanently disabled. + if(ui32DieCfg & ui32Mask) + { + return(true); + } + else + { + return(false); + } +} + +//***************************************************************************** +// +//! Performs a software reset of a peripheral +//! +//! \param ui32Peripheral is the peripheral to reset. +//! +//! This function performs a software reset of the specified peripheral. An +//! individual peripheral reset signal is asserted for a brief period and then +//! deasserted, leaving the peripheral in a operating state but in its reset +//! condition. +//! +//! The \e ui32Peripheral parameter must be one of the values: +//! \b SYS_CTRL_PERIPH_GPT0 , \b SYS_CTRL_PERIPH_GPT1, +//! \b SYS_CTRL_PERIPH_GPT2, \b SYS_CTRL_PERIPH_GPT3, +//! \b SYS_CTRL_PERIPH_SSI0, \b SYS_CTRL_PERIPH_SSI1, +//! \b SYS_CTRL_PERIPH_UART0, \b SYS_CTRL_PERIPH_UART1, +//! \b SYS_CTRL_PERIPH_I2C, \b SYS_CTRL_PERIPH_PKA, +//! \b SYS_CTRL_PERIPH_AES. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlPeripheralReset(uint32_t ui32Peripheral) +{ + volatile uint32_t ui32Delay; + + // Check the arguments. + ASSERT(SysCtrlPeripheralValid(ui32Peripheral)); + ASSERT(!(ui32Peripheral == SYS_CTRL_PERIPH_RFC)); + + // Put the peripheral into the reset state. + HWREG(g_pui32SRRegs[SYS_CTRL_PERIPH_INDEX(ui32Peripheral)]) |= + SYS_CTRL_PERIPH_MASKBIT(ui32Peripheral); + + // Delay for a little bit. + for(ui32Delay = 0; ui32Delay < 16; ui32Delay++) { } + + // Take the peripheral out of the reset state. + HWREG(g_pui32SRRegs[SYS_CTRL_PERIPH_INDEX(ui32Peripheral)]) &= + ~SYS_CTRL_PERIPH_MASKBIT(ui32Peripheral); +} + + +//***************************************************************************** +// +//! Enables a peripheral (in Run mode) +//! +//! \param ui32Peripheral is the peripheral to enable. +//! +//! Peripherals are enabled with this function. At power-up, some peripherals +//! are disabled and must be enabled to operate or respond to +//! register reads/writes. +//! +//! The \e ui32Peripheral parameter must be one of the values: +//! \b SYS_CTRL_PERIPH_GPT0 , \b SYS_CTRL_PERIPH_GPT1, +//! \b SYS_CTRL_PERIPH_GPT2, \b SYS_CTRL_PERIPH_GPT3, +//! \b SYS_CTRL_PERIPH_SSI0, \b SYS_CTRL_PERIPH_SSI1, +//! \b SYS_CTRL_PERIPH_UART0, \b SYS_CTRL_PERIPH_UART1, +//! \b SYS_CTRL_PERIPH_I2C, \b SYS_CTRL_PERIPH_PKA, +//! \b SYS_CTRL_PERIPH_AES, \b SYS_CTRL_PERIPH_RFC. +//! +//! \note The actual enabling of the peripheral might be delayed until some +//! time after this function returns. Ensure that the peripheral is not +//! accessed until enabled. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlPeripheralEnable(uint32_t ui32Peripheral) +{ + // Check the arguments. + ASSERT(SysCtrlPeripheralValid(ui32Peripheral)); + + // Enable module in Run Mode + HWREG(g_pui32RCGCRegs[SYS_CTRL_PERIPH_INDEX(ui32Peripheral)]) |= + SYS_CTRL_PERIPH_MASKBIT(ui32Peripheral); +} + + +//***************************************************************************** +// +//! Disables a peripheral (in Run mode) +//! +//! \param ui32Peripheral is the peripheral to disable. +//! +//! Peripherals are disabled with this function. Once disabled, peripherals do +//! not operate or respond to register reads/writes. +//! +//! The \e ui32Peripheral parameter must be one of the values: +//! \b SYS_CTRL_PERIPH_GPT0 , \b SYS_CTRL_PERIPH_GPT1, +//! \b SYS_CTRL_PERIPH_GPT2, \b SYS_CTRL_PERIPH_GPT3, +//! \b SYS_CTRL_PERIPH_SSI0, \b SYS_CTRL_PERIPH_SSI1, +//! \b SYS_CTRL_PERIPH_UART0, \b SYS_CTRL_PERIPH_UART1, +//! \b SYS_CTRL_PERIPH_I2C, \b SYS_CTRL_PERIPH_PKA, +//! \b SYS_CTRL_PERIPH_AES, \b SYS_CTRL_PERIPH_RFC. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlPeripheralDisable(uint32_t ui32Peripheral) +{ + // Check the arguments. + ASSERT(SysCtrlPeripheralValid(ui32Peripheral)); + + // Disable module in Run Mode + HWREG(g_pui32RCGCRegs[SYS_CTRL_PERIPH_INDEX(ui32Peripheral)]) &= + ~SYS_CTRL_PERIPH_MASKBIT(ui32Peripheral); +} + + +//***************************************************************************** +// +//! Enables a peripheral in sleep mode +//! +//! \param ui32Peripheral is the peripheral to enable in sleep mode. +//! +//! This function allows a peripheral to continue operating when the processor +//! goes into sleep mode. Because the clocking configuration of the device does +//! not change, any peripheral can safely continue operating while the +//! processor is in sleep mode, and can therefore wake the processor from sleep +//! mode. +//! +//! The \e ui32Peripheral parameter must be one of the values: +//! \b SYS_CTRL_PERIPH_GPT0 , \b SYS_CTRL_PERIPH_GPT1, +//! \b SYS_CTRL_PERIPH_GPT2, \b SYS_CTRL_PERIPH_GPT3, +//! \b SYS_CTRL_PERIPH_SSI0, \b SYS_CTRL_PERIPH_SSI1, +//! \b SYS_CTRL_PERIPH_UART0, \b SYS_CTRL_PERIPH_UART1, +//! \b SYS_CTRL_PERIPH_I2C, \b SYS_CTRL_PERIPH_PKA, +//! \b SYS_CTRL_PERIPH_AES, \b SYS_CTRL_PERIPH_RFC. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlPeripheralSleepEnable(uint32_t ui32Peripheral) +{ + // Check the arguments. + ASSERT(SysCtrlPeripheralValid(ui32Peripheral)); + + // Enable this peripheral in sleep mode. + HWREG(g_pui32SCGCRegs[SYS_CTRL_PERIPH_INDEX(ui32Peripheral)]) |= + SYS_CTRL_PERIPH_MASKBIT(ui32Peripheral); +} + + +//***************************************************************************** +// +//! Disables a peripheral in sleep mode +//! +//! \param ui32Peripheral is the peripheral to disable in sleep mode. +//! +//! This function causes a peripheral to stop operating when the processor goes +//! into sleep mode. Disabling peripherals while in sleep mode helps lower +//! the current draw of the device. If enabled (by SysCtrlPeripheralEnable()), +//! the peripheral automatically resume operation when the processor +//! leaves sleep mode, maintaining the entire state before entry into sleep +//! mode. +//! +//! The \e ui32Peripheral parameter must be one of the values: +//! \b SYS_CTRL_PERIPH_GPT0 , \b SYS_CTRL_PERIPH_GPT1, +//! \b SYS_CTRL_PERIPH_GPT2, \b SYS_CTRL_PERIPH_GPT3, +//! \b SYS_CTRL_PERIPH_SSI0, \b SYS_CTRL_PERIPH_SSI1, +//! \b SYS_CTRL_PERIPH_UART0, \b SYS_CTRL_PERIPH_UART1, +//! \b SYS_CTRL_PERIPH_I2C, \b SYS_CTRL_PERIPH_PKA, +//! \b SYS_CTRL_PERIPH_AES, \b SYS_CTRL_PERIPH_RFC. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlPeripheralSleepDisable(uint32_t ui32Peripheral) +{ + // Check the arguments. + ASSERT(SysCtrlPeripheralValid(ui32Peripheral)); + + // Disable this peripheral in sleep mode. + HWREG(g_pui32SCGCRegs[SYS_CTRL_PERIPH_INDEX(ui32Peripheral)]) &= + ~SYS_CTRL_PERIPH_MASKBIT(ui32Peripheral); +} + + +//***************************************************************************** +// +//! Enables a peripheral in deep-sleep mode +//! +//! \param ui32Peripheral is the peripheral to enable in deep-sleep mode. +//! +//! This function allows a peripheral to continue operating when the processor +//! goes into deep-sleep mode. Because the clocking configuration of the device +//! can change, not all peripherals can safely continue operating while the +//! processor is in sleep mode. Safe operation depends on the chosen power mode. +//! The caller must make sensible choices. +//! +//! The \e ui32Peripheral parameter must be one of the values: +//! \b SYS_CTRL_PERIPH_GPT0 , \b SYS_CTRL_PERIPH_GPT1, +//! \b SYS_CTRL_PERIPH_GPT2, \b SYS_CTRL_PERIPH_GPT3, +//! \b SYS_CTRL_PERIPH_SSI0, \b SYS_CTRL_PERIPH_SSI1, +//! \b SYS_CTRL_PERIPH_UART0, \b SYS_CTRL_PERIPH_UART1, +//! \b SYS_CTRL_PERIPH_I2C, \b SYS_CTRL_PERIPH_PKA, +//! \b SYS_CTRL_PERIPH_AES, \b SYS_CTRL_PERIPH_RFC. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlPeripheralDeepSleepEnable(uint32_t ui32Peripheral) +{ + // Check the arguments. + ASSERT(SysCtrlPeripheralValid(ui32Peripheral)); + + // Enable this peripheral in deep-sleep mode. + HWREG(g_pui32DCGCRegs[SYS_CTRL_PERIPH_INDEX(ui32Peripheral)]) |= + SYS_CTRL_PERIPH_MASKBIT(ui32Peripheral); +} + + +//***************************************************************************** +// +//! Disables a peripheral in deep-sleep mode +//! +//! \param ui32Peripheral is the peripheral to disable in deep-sleep mode. +//! +//! This function causes a peripheral to stop operating when the processor goes +//! into deep-sleep mode. Disabling peripherals while in deep-sleep mode helps +//! to lower the current draw of the device, and can keep peripherals that +//! require a particular clock frequency from operating when the clock changes +//! as a result of entering deep-sleep mode. If enabled (by +//! SysCtrlPeripheralEnable()), the peripheral automatically resumes operation +//! when the processor leaves deep-sleep mode, maintaining its entire +//! state from before entry into deep-sleep mode. +//! +//! The \e ui32Peripheral parameter must be one of the values: +//! \b SYS_CTRL_PERIPH_GPT0 , \b SYS_CTRL_PERIPH_GPT1, +//! \b SYS_CTRL_PERIPH_GPT2, \b SYS_CTRL_PERIPH_GPT3, +//! \b SYS_CTRL_PERIPH_SSI0, \b SYS_CTRL_PERIPH_SSI1, +//! \b SYS_CTRL_PERIPH_UART0, \b SYS_CTRL_PERIPH_UART1, +//! \b SYS_CTRL_PERIPH_I2C, \b SYS_CTRL_PERIPH_PKA, +//! \b SYS_CTRL_PERIPH_AES, \b SYS_CTRL_PERIPH_RFC. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlPeripheralDeepSleepDisable(uint32_t ui32Peripheral) +{ + // Check the arguments. + ASSERT(SysCtrlPeripheralValid(ui32Peripheral)); + + // Disable this peripheral in deep-sleep mode. + HWREG(g_pui32DCGCRegs[SYS_CTRL_PERIPH_INDEX(ui32Peripheral)]) &= + ~SYS_CTRL_PERIPH_MASKBIT(ui32Peripheral); +} + + +//***************************************************************************** +// +//! Set Power Mode +//! +//! \param ui32PowerMode is the power mode to be entered. +//! +//! This function selects the power mode to enter when CM3 enters Deep Sleep +//! mode. +//! Power mode PM0 (\b SYS_CTRL_PM_NOACTION) is entered when the CPU +//! wakes up due to an interrupt. +//! Note only transitions to and from PM0 are legal (that is, PM1 to PM2 +//! cannot happen). +//! +//! The \e ui32PowerMode argument must be only one of the following values: +//! \b SYS_CTRL_PM_NOACTION, \b SYS_CTRL_PM_1, \b SYS_CTRL_PM_2 or +//! \b SYS_CTRL_PM_3. +//! +//! \sa SysCtrlDeepSleep(). +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlPowerModeSet(uint32_t ui32PowerMode) +{ + // Check the arguments. + ASSERT(ui32PowerMode == SYS_CTRL_PM_NOACTION || + ui32PowerMode == SYS_CTRL_PM_1 || + ui32PowerMode == SYS_CTRL_PM_2 || + ui32PowerMode == SYS_CTRL_PM_3); + + // Set power mode + HWREG(SYS_CTRL_PMCTL) = ui32PowerMode; +} + + +//***************************************************************************** +// +//! Get Power Mode +//! +//! This function returns the current Power Mode setting. +//! +//! \return Power mode, i.e. one of the following values: +//! \b SYS_CTRL_PM_NOACTION, \b SYS_CTRL_PM_1, \b SYS_CTRL_PM_2 or +//! \b SYS_CTRL_PM_3. +// +//***************************************************************************** +uint32_t +SysCtrlPowerModeGet(void) +{ + uint32_t ui32PowerMode; + + ui32PowerMode = HWREG(SYS_CTRL_PMCTL); + ui32PowerMode &= SYS_CTRL_PMCTL_PM_M; + + return(ui32PowerMode); +} + + + +//***************************************************************************** +// +//! Enable Clock Loss Detection +//! +//! This function enables clock loss detection. +//! +//! \return None +// +//***************************************************************************** +void +SysCtrlClockLossDetectEnable(void) +{ + uint32_t ui32CLD; + + ui32CLD = HWREG(SYS_CTRL_CLD); + ui32CLD |= SYS_CTRL_CLD_EN; + HWREG(SYS_CTRL_CLD) = ui32CLD; +} + + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/sys_ctrl.h b/bsp/boards/mimsy2-cc2538/source/sys_ctrl.h new file mode 100644 index 0000000000..3b1ed32ee0 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/sys_ctrl.h @@ -0,0 +1,162 @@ +/****************************************************************************** +* Filename: sys_ctrl.h +* Revised: $Date: 2013-03-20 14:59:13 +0100 (Wed, 20 Mar 2013) $ +* Revision: $Revision: 9491 $ +* +* Description: Prototypes for the system control driver. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __SYS_CTRL_H__ +#define __SYS_CTRL_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// General constants +// +//***************************************************************************** + +#define SYS_CTRL_TIMEOUT 0x0000ffff // Time out value for polling + +#define SYS_CTRL_32MHZ 32000000 +#define SYS_CTRL_16MHZ 16000000 +#define SYS_CTRL_8MHZ 8000000 +#define SYS_CTRL_4MHZ 4000000 +#define SYS_CTRL_2MHZ 2000000 +#define SYS_CTRL_1MHZ 1000000 +#define SYS_CTRL_500KHZ 500000 +#define SYS_CTRL_250KHZ 250000 +#define SYS_CTRL_62500HZ 62500 + + +//***************************************************************************** +// +// The following are values that can be passed to the +// SysCtrlPeripheralReset(), SysCtrlPeripheralEnable(), +// SysCtrlPeripheralDisable(), SysCtrlPeripheralSleepEnable(), +// SysCtrlPeripheralSleepDisable(), SysCtrlPeripheralDeepSleepEnable() and +// SysCtrlPeripheralDeepSleepDisable() APIs as the ui32Peripheral parameter. +// +//***************************************************************************** +#define SYS_CTRL_PERIPH_GPT0 0x00000000 // General Purpose Timer 0 +#define SYS_CTRL_PERIPH_GPT1 0x00000001 // General Purpose Timer 1 +#define SYS_CTRL_PERIPH_GPT2 0x00000002 // General Purpose Timer 2 +#define SYS_CTRL_PERIPH_GPT3 0x00000003 // General Purpose Timer 3 +#define SYS_CTRL_PERIPH_SSI0 0x00000100 // SSI 0 +#define SYS_CTRL_PERIPH_SSI1 0x00000101 // SSI 1 +#define SYS_CTRL_PERIPH_UART0 0x00000200 // UART 0 +#define SYS_CTRL_PERIPH_UART1 0x00000201 // UART 1 +#define SYS_CTRL_PERIPH_I2C 0x00000300 // I2C0 +#define SYS_CTRL_PERIPH_PKA 0x00000400 // PKA +#define SYS_CTRL_PERIPH_AES 0x00000401 // AES +#define SYS_CTRL_PERIPH_RFC 0x00000500 // RF Core + + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtrlClockSet() API as +// the ui32Config parameter. +// +//***************************************************************************** +#define SYS_CTRL_SYSDIV_32MHZ 0x00000000 // Sys_div for sysclk 32MHz +#define SYS_CTRL_SYSDIV_16MHZ 0x00000001 // Sys_div for sysclk 16MHz +#define SYS_CTRL_SYSDIV_8MHZ 0x00000002 // Sys_div for sysclk 8MHz +#define SYS_CTRL_SYSDIV_4MHZ 0x00000003 // Sys_div for sysclk 4MHz +#define SYS_CTRL_SYSDIV_2MHZ 0x00000004 // Sys_div for sysclk 2MHz +#define SYS_CTRL_SYSDIV_1MHZ 0x00000005 // Sys_div for sysclk 1MHz +#define SYS_CTRL_SYSDIV_500KHZ 0x00000006 // Sys_div for sysclk 0.50MHz +#define SYS_CTRL_SYSDIV_250KHZ 0x00000007 // Sys_div for sysclk 0.25MHz + + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtrlPowerModeSet() +// API as the ui32PowerMode parameter. +// +//***************************************************************************** +#define SYS_CTRL_PM_NOACTION 0x00000000 // No action +#define SYS_CTRL_PM_1 0x00000001 // Power Mode 1 +#define SYS_CTRL_PM_2 0x00000002 // Power Mode 2 +#define SYS_CTRL_PM_3 0x00000003 // Power Mode 3 + + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void SysCtrlClockSet(bool bOsc32k, bool bInternalOsc, + uint32_t ui32SysDiv); +extern uint32_t SysCtrlClockGet(void); +extern void SysCtrlIOClockSet(uint32_t ui32IODiv); +extern uint32_t SysCtrlIOClockGet(void); +extern void SysCtrlDelay(uint32_t ui32Count); +extern void SysCtrlReset(void); +extern void SysCtrlSleep(void); +extern void SysCtrlDeepSleep(void); +extern bool SysCtrlPeripheralPresent(uint32_t ui32Peripheral); +extern void SysCtrlPeripheralReset(uint32_t ui32Peripheral); +extern void SysCtrlPeripheralEnable(uint32_t ui32Peripheral); +extern void SysCtrlPeripheralDisable(uint32_t ui32Peripheral); +extern void SysCtrlPeripheralSleepEnable(uint32_t ui32Peripheral); +extern void SysCtrlPeripheralSleepDisable(uint32_t ui32Peripheral); +extern void SysCtrlPeripheralDeepSleepEnable(uint32_t ui32Peripheral); +extern void SysCtrlPeripheralDeepSleepDisable(uint32_t ui32Peripheral); +extern void SysCtrlPowerModeSet(uint32_t ui32PowerMode); +extern uint32_t SysCtrlPowerModeGet(void); +extern void SysCtrlClockLossDetectEnable(void); + + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __SYS_CTRL_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/systick.c b/bsp/boards/mimsy2-cc2538/source/systick.c new file mode 100644 index 0000000000..c133cd0712 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/systick.c @@ -0,0 +1,273 @@ +/****************************************************************************** +* Filename: systick.c +* Revised: $Date: 2013-01-21 15:25:21 +0100 (Mon, 21 Jan 2013) $ +* Revision: $Revision: 9178 $ +* +* Description: Driver for the SysTick timer in NVIC. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup systick_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include "debug.h" +#include "interrupt.h" +#include "systick.h" + +//***************************************************************************** +// +//! Enables the SysTick counter +//! +//! This function starts the SysTick counter. If an interrupt handler has been +//! registered, it is called when the SysTick counter rolls over. +//! +//! \note Calling this function causes the SysTick counter to (re)commence +//! counting from its current value. The counter is not automatically reloaded +//! with the period as specified in a previous call to SysTickPeriodSet(). If +//! an immediate reload is required, the \b NVIC_ST_CURRENT register must be +//! written to force the reload. Any write to this register clears the SysTick +//! counter to 0 and causes a reload with the supplied period on the next +//! clock. +//! +//! \return None +// +//***************************************************************************** +void +SysTickEnable(void) +{ + // + // Enable SysTick. + // + HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_ENABLE; +} + +//***************************************************************************** +// +//! Disables the SysTick counter +//! +//! This will stop the SysTick counter. If an interrupt handler has been +//! registered, it will no longer be called until SysTick is restarted. +//! +//! \return None +// +//***************************************************************************** +void +SysTickDisable(void) +{ + // + // Disable SysTick. + // + HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_ENABLE); +} + +//***************************************************************************** +// +//! Registers an interrupt handler for the SysTick interrupt +//! +//! \param pfnHandler is a pointer to the function to be called when the +//! SysTick interrupt occurs. +//! +//! This sets the handler to be called when a SysTick interrupt occurs. +//! +//! \sa See IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +SysTickIntRegister(void (*pfnHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(FAULT_SYSTICK, pfnHandler); + + // + // Enable the SysTick interrupt. + // + HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN; +} + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the SysTick interrupt +//! +//! This function will clear the handler to be called when a SysTick interrupt +//! occurs. +//! +//! \sa See IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +SysTickIntUnregister(void) +{ + // + // Disable the SysTick interrupt. + // + HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN); + + // + // Unregister the interrupt handler. + // + IntUnregister(FAULT_SYSTICK); +} + +//***************************************************************************** +// +//! Enables the SysTick interrupt +//! +//! This function will enable the SysTick interrupt, allowing it to be +//! reflected to the processor. +//! +//! \note The SysTick interrupt handler does not need to clear the SysTick +//! interrupt source as this is done automatically by NVIC when the interrupt +//! handler is called. +//! +//! \return None +// +//***************************************************************************** +void +SysTickIntEnable(void) +{ + // + // Enable the SysTick interrupt. + // + HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN; +} + +//***************************************************************************** +// +//! Disables the SysTick interrupt +//! +//! This function will disable the SysTick interrupt, preventing it from being +//! reflected to the processor. +//! +//! \return None +// +//***************************************************************************** +void +SysTickIntDisable(void) +{ + // + // Disable the SysTick interrupt. + // + HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN); +} + +//***************************************************************************** +// +//! Sets the period of the SysTick counter +//! +//! \param ui32Period is the number of clock ticks in each period of the SysTick +//! counter; must be between 1 and 16,777,216, inclusive. +//! +//! This function sets the rate at which the SysTick counter wraps; this +//! equates to the number of processor clocks between interrupts. +//! +//! \note Calling this function does not cause the SysTick counter to reload +//! immediately. If an immediate reload is required, the \b NVIC_ST_CURRENT +//! register must be written. Any write to this register clears the SysTick +//! counter to 0 and will cause a reload with the \e ui32Period supplied here on +//! the next clock after the SysTick is enabled. +//! +//! \return None +// +//***************************************************************************** +void +SysTickPeriodSet(uint32_t ui32Period) +{ + // + // Check the arguments. + // + ASSERT((ui32Period > 0) && (ui32Period <= 16777216)); + + // + // Set the period of the SysTick counter. + // + HWREG(NVIC_ST_RELOAD) = ui32Period - 1; +} + +//***************************************************************************** +// +//! Gets the period of the SysTick counter +//! +//! This function returns the rate at which the SysTick counter wraps; this +//! equates to the number of processor clocks between interrupts. +//! +//! \return Returns the period of the SysTick counter. +// +//***************************************************************************** +uint32_t +SysTickPeriodGet(void) +{ + // + // Return the period of the SysTick counter. + // + return(HWREG(NVIC_ST_RELOAD) + 1); +} + +//***************************************************************************** +// +//! Gets the current value of the SysTick counter +//! +//! This function returns the current value of the SysTick counter; this will +//! be a value between the period - 1 and zero, inclusive. +//! +//! \return Returns the current value of the SysTick counter. +// +//***************************************************************************** +uint32_t +SysTickValueGet(void) +{ + // + // Return the current value of the SysTick counter. + // + return(HWREG(NVIC_ST_CURRENT)); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/systick.h b/bsp/boards/mimsy2-cc2538/source/systick.h new file mode 100644 index 0000000000..a628898e6d --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/systick.h @@ -0,0 +1,82 @@ +/****************************************************************************** +* Filename: systick.h +* Revised: $Date: 2013-01-21 15:25:21 +0100 (Mon, 21 Jan 2013) $ +* Revision: $Revision: 9178 $ +* +* Description: Prototypes for the SysTick driver. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __SYSTICK_H__ +#define __SYSTICK_H__ + +#include + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void SysTickEnable(void); +extern void SysTickDisable(void); +extern void SysTickIntRegister(void (*pfnHandler)(void)); +extern void SysTickIntUnregister(void); +extern void SysTickIntEnable(void); +extern void SysTickIntDisable(void); +extern void SysTickPeriodSet(uint32_t ui32Period); +extern uint32_t SysTickPeriodGet(void); +extern uint32_t SysTickValueGet(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __SYSTICK_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/uarthal.c b/bsp/boards/mimsy2-cc2538/source/uarthal.c new file mode 100644 index 0000000000..0c4b548bf8 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/uarthal.c @@ -0,0 +1,1515 @@ +/****************************************************************************** +* Filename: uart.c +* Revised: $Date: 2013-04-16 12:01:40 +0200 (Tue, 16 Apr 2013) $ +* Revision: $Revision: 9777 $ +* +* Description: Driver for the UART. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup uart_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include +#include "debug.h" +#include "interrupt.h" +#include "uarthal.h" + +//***************************************************************************** +// +//! \internal +//! Checks a UART base address +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function determines if a UART port base address is valid. +//! +//! \return Returns \b true if the base address is valid and \b false +//! otherwise. +// +//***************************************************************************** +#ifdef ENABLE_ASSERT +static bool +UARTBaseValid(uint32_t ui32Base) +{ + return((ui32Base == UART0_BASE) || (ui32Base == UART1_BASE)); +} +#endif + +//***************************************************************************** +// +//! Sets the type of parity +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32Parity specifies the type of parity to use. +//! +//! This function sets the type of parity to use for transmitting and expect +//! when receiving. The \e ui32Parity parameter must be one of +//! \b UART_CONFIG_PAR_NONE, \b UART_CONFIG_PAR_EVEN, \b UART_CONFIG_PAR_ODD, +//! \b UART_CONFIG_PAR_ONE, or \b UART_CONFIG_PAR_ZERO. The last two allow +//! direct control of the parity bit; it is always either one or zero based on +//! the mode. +//! +//! \return None +// +//***************************************************************************** +void +UARTParityModeSet(uint32_t ui32Base, uint32_t ui32Parity) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + ASSERT((ui32Parity == UART_CONFIG_PAR_NONE) || + (ui32Parity == UART_CONFIG_PAR_EVEN) || + (ui32Parity == UART_CONFIG_PAR_ODD) || + (ui32Parity == UART_CONFIG_PAR_ONE) || + (ui32Parity == UART_CONFIG_PAR_ZERO)); + + // + // Set the parity mode. + // + HWREG(ui32Base + UART_O_LCRH) = ((HWREG(ui32Base + UART_O_LCRH) & + ~(UART_LCRH_SPS | UART_LCRH_EPS | + UART_LCRH_PEN)) | ui32Parity); +} + +//***************************************************************************** +// +//! Gets the type of parity currently being used +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function gets the type of parity used for transmitting data and +//! expected when receiving data. +//! +//! \return Returns the current parity settings, specified as one of +//! \b UART_CONFIG_PAR_NONE, \b UART_CONFIG_PAR_EVEN, \b UART_CONFIG_PAR_ODD, +//! \b UART_CONFIG_PAR_ONE, or \b UART_CONFIG_PAR_ZERO. +// +//***************************************************************************** +uint32_t +UARTParityModeGet(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Return the current parity setting. + // + return(HWREG(ui32Base + UART_O_LCRH) & + (UART_LCRH_SPS | UART_LCRH_EPS | UART_LCRH_PEN)); +} + +//***************************************************************************** +// +//! Sets the FIFO level at which interrupts are generated +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32TxLevel is the transmit FIFO interrupt level, specified as one of +//! \b UART_FIFO_TX1_8, \b UART_FIFO_TX2_8, \b UART_FIFO_TX4_8, +//! \b UART_FIFO_TX6_8, or \b UART_FIFO_TX7_8. +//! \param ui32RxLevel is the receive FIFO interrupt level, specified as one of +//! \b UART_FIFO_RX1_8, \b UART_FIFO_RX2_8, \b UART_FIFO_RX4_8, +//! \b UART_FIFO_RX6_8, or \b UART_FIFO_RX7_8. +//! +//! This function sets the FIFO level at which transmit and receive interrupts +//! are generated. +//! +//! \return None +// +//***************************************************************************** +void +UARTFIFOLevelSet(uint32_t ui32Base, uint32_t ui32TxLevel, + uint32_t ui32RxLevel) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + ASSERT((ui32TxLevel == UART_FIFO_TX1_8) || + (ui32TxLevel == UART_FIFO_TX2_8) || + (ui32TxLevel == UART_FIFO_TX4_8) || + (ui32TxLevel == UART_FIFO_TX6_8) || + (ui32TxLevel == UART_FIFO_TX7_8)); + ASSERT((ui32RxLevel == UART_FIFO_RX1_8) || + (ui32RxLevel == UART_FIFO_RX2_8) || + (ui32RxLevel == UART_FIFO_RX4_8) || + (ui32RxLevel == UART_FIFO_RX6_8) || + (ui32RxLevel == UART_FIFO_RX7_8)); + + // + // Set the FIFO interrupt levels. + // + HWREG(ui32Base + UART_O_IFLS) = ui32TxLevel | ui32RxLevel; +} + +//***************************************************************************** +// +//! Gets the FIFO level at which interrupts are generated +//! +//! \param ui32Base is the base address of the UART port. +//! \param pui32TxLevel is a pointer to storage for the transmit FIFO level, +//! returned as one of \b UART_FIFO_TX1_8, \b UART_FIFO_TX2_8, +//! \b UART_FIFO_TX4_8, \b UART_FIFO_TX6_8, or \b UART_FIFO_TX7_8. +//! \param pui32RxLevel is a pointer to storage for the receive FIFO level, +//! returned as one of \b UART_FIFO_RX1_8, \b UART_FIFO_RX2_8, +//! \b UART_FIFO_RX4_8, \b UART_FIFO_RX6_8, or \b UART_FIFO_RX7_8. +//! +//! This function gets the FIFO level at which transmit and receive interrupts +//! are generated. +//! +//! \return None +// +//***************************************************************************** +void +UARTFIFOLevelGet(uint32_t ui32Base, uint32_t *pui32TxLevel, + uint32_t *pui32RxLevel) +{ + uint32_t ui32Temp; + + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Read the FIFO level register. + // + ui32Temp = HWREG(ui32Base + UART_O_IFLS); + + // + // Extract the transmit and receive FIFO levels. + // + *pui32TxLevel = ui32Temp & UART_IFLS_TXIFLSEL_M; + *pui32RxLevel = ui32Temp & UART_IFLS_RXIFLSEL_M; +} + +//***************************************************************************** +// +//! Sets the configuration of a UART +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32UARTClk is the rate of the clock supplied to the UART module. +//! \param ui32Baud is the desired baud rate. +//! \param ui32Config is the data format for the port (number of data bits, +//! number of stop bits, and parity). +//! +//! This function configures the UART for operation in the specified data +//! format. The baud rate is provided in the \e ui32Baud parameter and the data +//! format in the \e ui32Config parameter. +//! +//! The \e ui32Config parameter is the logical OR of three values: the number of +//! data bits, the number of stop bits, and the parity. \b UART_CONFIG_WLEN_8, +//! \b UART_CONFIG_WLEN_7, \b UART_CONFIG_WLEN_6, and \b UART_CONFIG_WLEN_5 +//! select from eight to five data bits per byte (respectively). +//! \b UART_CONFIG_STOP_ONE and \b UART_CONFIG_STOP_TWO select one or two stop +//! bits (respectively). \b UART_CONFIG_PAR_NONE, \b UART_CONFIG_PAR_EVEN, +//! \b UART_CONFIG_PAR_ODD, \b UART_CONFIG_PAR_ONE, and \b UART_CONFIG_PAR_ZERO +//! select the parity mode (no parity bit, even parity bit, odd parity bit, +//! parity bit always one, and parity bit always zero, respectively). +//! +//! The peripheral clock is set in the System Control module. The frequency of +//! the system clock is the value returned by SysCtrlClockGet() or +//! SysCtrlIOClockGet() depending on the chosen clock source as set by +//! UARTClockSourceSet(), or it can be explicitly hard coded if it is constant +//! and known (to save the code/execution overhead of a call to +//! SysCtrlClockGet() or SysCtrlIOClockGet()). +//! +//! The CC2538 part has the ability to specify the UART baud clock +//! source (via UARTClockSourceSet()), the peripheral clock can be changed to +//! PIOSC. In this case, the peripheral clock should be specified as +//! 16,000,000 (the nominal rate of PIOSC). +//! +//! \sa See UARTClockSourceSet() +//! +//! \return None +// +//***************************************************************************** +void +UARTConfigSetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk, + uint32_t ui32Baud, uint32_t ui32Config) +{ + uint32_t ui32Div; + + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + ASSERT(ui32Baud != 0); + + // + // Stop the UART. + // + UARTDisable(ui32Base); + + // + // Is the required baud rate greater than the maximum rate supported + // without the use of high speed mode? + // + if((ui32Baud * 16) > ui32UARTClk) + { + // + // Enable high speed mode. + // + HWREG(ui32Base + UART_O_CTL) |= UART_CTL_HSE; + + // + // Half the supplied baud rate to compensate for enabling high speed + // mode. This allows the following code to be common to both cases. + // + ui32Baud /= 2; + } + else + { + // + // Disable high speed mode. + // + HWREG(ui32Base + UART_O_CTL) &= ~(UART_CTL_HSE); + } + + // + // Compute the fractional baud rate divider. + // + ui32Div = (((ui32UARTClk * 8) / ui32Baud) + 1) / 2; + + // + // Set the baud rate. + // + HWREG(ui32Base + UART_O_IBRD) = ui32Div / 64; + HWREG(ui32Base + UART_O_FBRD) = ui32Div % 64; + + // + // Set parity, data length, and number of stop bits. + // + HWREG(ui32Base + UART_O_LCRH) = ui32Config; + + // + // Clear the flags register. + // + HWREG(ui32Base + UART_O_FR) = 0; +} + +//***************************************************************************** +// +//! Gets the current configuration of a UART +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32UARTClk is the rate of the clock supplied to the UART module. +//! \param pui32Baud is a pointer to storage for the baud rate. +//! \param pui32Config is a pointer to storage for the data format. +//! +//! The baud rate and data format for the UART is determined, given an +//! explicitly provided peripheral clock (hence the ExpClk suffix). The +//! returned baud rate is the actual baud rate; it may not be the exact baud +//! rate requested or an ``official'' baud rate. The data format returned in +//! \e pui32Config is enumerated the same as the \e ui32Config parameter of +//! UARTConfigSetExpClk(). +//! +//! The peripheral clock is set in the System Control module. The frequency of +//! the system clock is the value returned by SysCtrlClockGet() or +//! SysCtrlIOClockGet() depending on the chosen clock source as set by +//! UARTClockSourceSet(), or it can be explicitly hard coded if it is constant +//! and known (to save the code/execution overhead of a call to +//! SysCtrlClockGet() or SysCtrlIOClockGet()). +//! +//! The CC2538 part has the ability to specify the UART baud clock +//! source (via UARTClockSourceSet()), the peripheral clock can be changed to +//! PIOSC. In this case, the peripheral clock should be specified as +//! 16,000,000 (the nominal rate of PIOSC). +//! +//! \return None +// +//***************************************************************************** +void +UARTConfigGetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk, + uint32_t *pui32Baud, uint32_t *pui32Config) +{ + uint32_t ui32Int, ui32Frac; + + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Compute the baud rate. + // + ui32Int = HWREG(ui32Base + UART_O_IBRD); + ui32Frac = HWREG(ui32Base + UART_O_FBRD); + *pui32Baud = (ui32UARTClk * 4) / ((64 * ui32Int) + ui32Frac); + + // + // See if high speed mode enabled. + // + if(HWREG(ui32Base + UART_O_CTL) & UART_CTL_HSE) + { + // + // High speed mode is enabled so the actual baud rate is actually + // double what was just calculated. + // + *pui32Baud *= 2; + } + + // + // Get the parity, data length, and number of stop bits. + // + *pui32Config = (HWREG(ui32Base + UART_O_LCRH) & + (UART_LCRH_SPS | UART_LCRH_WLEN_M | UART_LCRH_STP2 | + UART_LCRH_EPS | UART_LCRH_PEN)); +} + +//***************************************************************************** +// +//! Enables transmitting and receiving +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function sets the UARTEN, TXE, and RXE bits, and enables the transmit +//! and receive FIFOs. +//! +//! \return None +// +//***************************************************************************** +void +UARTEnable(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Enable the FIFO. + // + HWREG(ui32Base + UART_O_LCRH) |= UART_LCRH_FEN; + + // + // Enable RX, TX, and the UART. + // + HWREG(ui32Base + UART_O_CTL) |= (UART_CTL_UARTEN | UART_CTL_TXE | + UART_CTL_RXE); +} + +//***************************************************************************** +// +//! Disables transmitting and receiving +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function clears the UARTEN, TXE, and RXE bits, waits for the end of +//! transmission of the current character, and flushes the transmit FIFO. +//! +//! \return None +// +//***************************************************************************** +void +UARTDisable(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Wait for end of TX. + // + while(HWREG(ui32Base + UART_O_FR) & UART_FR_BUSY) + { + } + + // + // Disable the FIFO. + // + HWREG(ui32Base + UART_O_LCRH) &= ~(UART_LCRH_FEN); + + // + // Disable the UART. + // + HWREG(ui32Base + UART_O_CTL) &= ~(UART_CTL_UARTEN | UART_CTL_TXE | + UART_CTL_RXE); +} + +//***************************************************************************** +// +//! Enables the transmit and receive FIFOs +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This functions enables the transmit and receive FIFOs in the UART. +//! +//! \return None +// +//***************************************************************************** +void +UARTFIFOEnable(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Enable the FIFO. + // + HWREG(ui32Base + UART_O_LCRH) |= UART_LCRH_FEN; +} + +//***************************************************************************** +// +//! Disables the transmit and receive FIFOs +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This functions disables the transmit and receive FIFOs in the UART. +//! +//! \return None +// +//***************************************************************************** +void +UARTFIFODisable(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Disable the FIFO. + // + HWREG(ui32Base + UART_O_LCRH) &= ~(UART_LCRH_FEN); +} + +//***************************************************************************** +// +//! Enables SIR (IrDA) mode on the specified UART +//! +//! \param ui32Base is the base address of the UART port. +//! \param bLowPower indicates if SIR Low Power Mode is to be used. +//! +//! This function enables the SIREN control bit for IrDA mode on the UART. If +//! the \e bLowPower flag is set, then SIRLP bit will also be set. +//! +//! \return None +// +//***************************************************************************** +void +UARTEnableSIR(uint32_t ui32Base, bool bLowPower) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Enable SIR and SIRLP (if appropriate). + // + if(bLowPower) + { + HWREG(ui32Base + UART_O_CTL) |= (UART_CTL_SIREN | UART_CTL_SIRLP); + } + else + { + HWREG(ui32Base + UART_O_CTL) |= (UART_CTL_SIREN); + } +} + +//***************************************************************************** +// +//! Disables SIR (IrDA) mode on the specified UART +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function clears the SIREN (IrDA) and SIRLP (Low Power) bits. +//! +//! \return None +// +//***************************************************************************** +void +UARTDisableSIR(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Disable SIR and SIRLP (if appropriate). + // + HWREG(ui32Base + UART_O_CTL) &= ~(UART_CTL_SIREN | UART_CTL_SIRLP); +} + +//***************************************************************************** +// +//! Sets the operating mode for the UART transmit interrupt +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32Mode is the operating mode for the transmit interrupt. It may be +//! \b UART_TXINT_MODE_EOT to trigger interrupts when the transmitter is idle +//! or \b UART_TXINT_MODE_FIFO to trigger based on the current transmit FIFO +//! level. +//! +//! This function allows the mode of the UART transmit interrupt to be set. By +//! default, the transmit interrupt is asserted when the FIFO level falls past +//! a threshold set via a call to UARTFIFOLevelSet(). Alternatively, if this +//! function is called with \e ui32Mode set to \b UART_TXINT_MODE_EOT, the +//! transmit interrupt is asserted once the transmitter is completely idle - +//! the transmit FIFO is empty and all bits, including any stop bits, have +//! cleared the transmitter. +//! +//! \return None +// +//***************************************************************************** +void +UARTTxIntModeSet(uint32_t ui32Base, uint32_t ui32Mode) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + ASSERT((ui32Mode == UART_TXINT_MODE_EOT) || + (ui32Mode == UART_TXINT_MODE_FIFO)); + + // + // Set or clear the EOT bit of the UART control register as appropriate. + // + HWREG(ui32Base + UART_O_CTL) = ((HWREG(ui32Base + UART_O_CTL) & + ~(UART_TXINT_MODE_EOT | + UART_TXINT_MODE_FIFO)) | ui32Mode); +} + +//***************************************************************************** +// +//! Returns the current operating mode for the UART transmit interrupt +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function returns the current operating mode for the UART transmit +//! interrupt. The return value is \b UART_TXINT_MODE_EOT if the transmit +//! interrupt is currently set to be asserted once the transmitter is +//! completely idle - the transmit FIFO is empty and all bits, including any +//! stop bits, have cleared the transmitter. The return value is +//! \b UART_TXINT_MODE_FIFO if the interrupt is set to be asserted based upon +//! the level of the transmit FIFO. +//! +//! \return Returns \b UART_TXINT_MODE_FIFO or \b UART_TXINT_MODE_EOT. +// +//***************************************************************************** +uint32_t +UARTTxIntModeGet(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Return the current transmit interrupt mode. + // + return(HWREG(ui32Base + UART_O_CTL) & (UART_TXINT_MODE_EOT | + UART_TXINT_MODE_FIFO)); +} + +//***************************************************************************** +// +//! Determines if there are any characters in the receive FIFO +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function returns a flag indicating whether or not there is data +//! available in the receive FIFO. +//! +//! \return Returns \b true if there is data in the receive FIFO or \b false +//! if there is no data in the receive FIFO. +// +//***************************************************************************** +bool +UARTCharsAvail(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Return the availability of characters. + // + return((HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE) ? false : true); +} + +//***************************************************************************** +// +//! Determines if there is any space in the transmit FIFO +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function returns a flag indicating whether or not there is space +//! available in the transmit FIFO. +//! +//! \return Returns \b true if there is space available in the transmit FIFO +//! or \b false if there is no space available in the transmit FIFO. +// +//***************************************************************************** +bool +UARTSpaceAvail(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Return the availability of space. + // + return((HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF) ? false : true); +} + +//***************************************************************************** +// +//! Receives a character from the specified port +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function gets a character from the receive FIFO for the specified +//! port. +//! +//! \return Returns the character read from the specified port, cast as a +//! \e int32_t. A \b -1 is returned if there are no characters present in the +//! receive FIFO. The UARTCharsAvail() function should be called before +//! attempting to call this function. +// +//***************************************************************************** +int32_t +UARTCharGetNonBlocking(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // See if there are any characters in the receive FIFO. + // + if(!(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE)) + { + // + // Read and return the next character. + // + return(HWREG(ui32Base + UART_O_DR)); + } + else + { + // + // There are no characters, so return a failure. + // + return(-1); + } +} + +//***************************************************************************** +// +//! Waits for a character from the specified port +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function gets a character from the receive FIFO for the specified +//! port. If there are no characters available, this function waits until a +//! character is received before returning. +//! +//! \return Returns the character read from the specified port, cast as a +//! \e int32_t. +// +//***************************************************************************** +int32_t +UARTCharGet(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Wait until a char is available. + // + while(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE) + { + } + + // + // Now get the char. + // + return(HWREG(ui32Base + UART_O_DR)); +} + +//***************************************************************************** +// +//! Sends a character to the specified port +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui8Data is the character to be transmitted. +//! +//! This function writes the character \e ui8Data to the transmit FIFO for the +//! specified port. This function does not block, so if there is no space +//! available, then a \b false is returned, and the application must retry the +//! function later. +//! +//! \return Returns \b true if the character was successfully placed in the +//! transmit FIFO or \b false if there was no space available in the transmit +//! FIFO. +// +//***************************************************************************** +bool +UARTCharPutNonBlocking(uint32_t ui32Base, uint8_t ui8Data) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // See if there is space in the transmit FIFO. + // + if(!(HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF)) + { + // + // Write this character to the transmit FIFO. + // + HWREG(ui32Base + UART_O_DR) = ui8Data; + + // + // Success. + // + return(true); + } + else + { + // + // There is no space in the transmit FIFO, so return a failure. + // + return(false); + } +} + +//***************************************************************************** +// +//! Waits to send a character from the specified port +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui8Data is the character to be transmitted. +//! +//! This function sends the character \e ui8Data to the transmit FIFO for the +//! specified port. If there is no space available in the transmit FIFO, this +//! function waits until there is space available before returning. +//! +//! \return None +// +//***************************************************************************** +void +UARTCharPut(uint32_t ui32Base, uint8_t ui8Data) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Wait until space is available. + // + while(HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF) + { + } + + // + // Send the char. + // + HWREG(ui32Base + UART_O_DR) = ui8Data; +} + +//***************************************************************************** +// +//! Causes a BREAK to be sent +//! +//! \param ui32Base is the base address of the UART port. +//! \param bBreakState controls the output level. +//! +//! Calling this function with \e bBreakState set to \b true asserts a break +//! condition on the UART. Calling this function with \e bBreakState set to +//! \b false removes the break condition. For proper transmission of a break +//! command, the break must be asserted for at least two complete frames. +//! +//! \return None +// +//***************************************************************************** +void +UARTBreakCtl(uint32_t ui32Base, bool bBreakState) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Set the break condition as requested. + // + HWREG(ui32Base + UART_O_LCRH) = + (bBreakState ? + (HWREG(ui32Base + UART_O_LCRH) | UART_LCRH_BRK) : + (HWREG(ui32Base + UART_O_LCRH) & ~(UART_LCRH_BRK))); +} + +//***************************************************************************** +// +//! Determines whether the UART transmitter is busy or not +//! +//! \param ui32Base is the base address of the UART port. +//! +//! Allows the caller to determine whether all transmitted bytes have cleared +//! the transmitter hardware. If \b false is returned, the transmit FIFO is +//! empty and all bits of the last transmitted character, including all stop +//! bits, have left the hardware shift register. +//! +//! \return Returns \b true if the UART is transmitting or \b false if all +//! transmissions are complete. +// +//***************************************************************************** +bool +UARTBusy(uint32_t ui32Base) +{ + // + // Check the argument. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Determine if the UART is busy. + // + return((HWREG(ui32Base + UART_O_FR) & UART_FR_BUSY) ? true : false); +} + +//***************************************************************************** +// +//! Registers an interrupt handler for a UART interrupt +//! +//! \param ui32Base is the base address of the UART port. +//! \param pfnHandler is a pointer to the function to be called when the +//! UART interrupt occurs. +//! +//! This function does the actual registering of the interrupt handler. This +//! function enables the global interrupt in the interrupt controller; specific +//! UART interrupts must be enabled via UARTIntEnable(). It is the interrupt +//! handler's responsibility to clear the interrupt source. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +UARTIntRegister(uint32_t ui32Base, void (*pfnHandler)(void)) +{ + uint32_t ui32Int; + + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Determine the interrupt number based on the UART port. + // + ui32Int = ((ui32Base == UART0_BASE) ? INT_UART0 : INT_UART1); + + // + // Register the interrupt handler. + // + IntRegister(ui32Int, pfnHandler); + + // + // Enable the UART interrupt. + // + IntEnable(ui32Int); +} + +//***************************************************************************** +// +//! Unregisters an interrupt handler for a UART interrupt +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function does the actual unregistering of the interrupt handler. It +//! clears the handler to be called when a UART interrupt occurs. This +//! function also masks off the interrupt in the interrupt controller so that +//! the interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +UARTIntUnregister(uint32_t ui32Base) +{ + uint32_t ui32Int; + + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Determine the interrupt number based on the UART port. + // + ui32Int = ((ui32Base == UART0_BASE) ? INT_UART0 : INT_UART1); + + // + // Disable the interrupt. + // + IntDisable(ui32Int); + + // + // Unregister the interrupt handler. + // + IntUnregister(ui32Int); +} + +//***************************************************************************** +// +//! Enables individual UART interrupt sources +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32IntFlags is the bit mask of the interrupt sources to be enabled. +//! +//! This function enables the indicated UART interrupt sources. Only the +//! sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! The \e ui32IntFlags parameter is the logical OR of any of the following: +//! +//! - \b UART_INT_9BIT - 9-bit address match interrupt +//! - \b UART_INT_OE - Overrun Error interrupt +//! - \b UART_INT_BE - Break Error interrupt +//! - \b UART_INT_PE - Parity Error interrupt +//! - \b UART_INT_FE - Framing Error interrupt +//! - \b UART_INT_RT - Receive Timeout interrupt +//! - \b UART_INT_TX - Transmit interrupt +//! - \b UART_INT_RX - Receive interrupt +//! - \b UART_INT_CTS - CTS interrupt (UART1 only) +//! +//! \return None +// +//***************************************************************************** +void +UARTIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Enable the specified interrupts. + // + HWREG(ui32Base + UART_O_IM) |= ui32IntFlags; +} + +//***************************************************************************** +// +//! Disables individual UART interrupt sources +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32IntFlags is the bit mask of the interrupt sources to be disabled. +//! +//! This function disables the indicated UART interrupt sources. Only the +//! sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! The \e ui32IntFlags parameter has the same definition as the \e ui32IntFlags +//! parameter to UARTIntEnable(). +//! +//! \return None +// +//***************************************************************************** +void +UARTIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Disable the specified interrupts. + // + HWREG(ui32Base + UART_O_IM) &= ~(ui32IntFlags); +} + +//***************************************************************************** +// +//! Gets the current interrupt status +//! +//! \param ui32Base is the base address of the UART port. +//! \param bMasked is \b false if the raw interrupt status is required and +//! \b true if the masked interrupt status is required. +//! +//! This function returns the interrupt status for the specified UART. Either +//! the raw interrupt status or the status of interrupts that are allowed to +//! reflect to the processor can be returned. +//! +//! \return Returns the current interrupt status, enumerated as a bit field of +//! values described in UARTIntEnable(). +// +//***************************************************************************** +uint32_t +UARTIntStatus(uint32_t ui32Base, bool bMasked) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(ui32Base + UART_O_MIS)); + } + else + { + return(HWREG(ui32Base + UART_O_RIS)); + } +} + +//***************************************************************************** +// +//! Clears UART interrupt sources +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32IntFlags is a bit mask of the interrupt sources to be cleared. +//! +//! The specified UART interrupt sources are cleared, so that they no longer +//! assert. This function must be called in the interrupt handler to keep the +//! interrupt from being recognized again immediately upon exit. +//! +//! The \e ui32IntFlags parameter has the same definition as the \e ui32IntFlags +//! parameter to UARTIntEnable(). +//! +//! \note Because there is a write buffer in the Cortex-M3 processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \return None +// +//***************************************************************************** +void +UARTIntClear(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Clear the requested interrupt sources. + // + HWREG(ui32Base + UART_O_ICR) = ui32IntFlags; +} + +//***************************************************************************** +// +//! Enable UART DMA operation +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32DMAFlags is a bit mask of the DMA features to enable. +//! +//! The specified UART DMA features are enabled. The UART can be +//! configured to use DMA for transmit or receive, and to disable +//! receive if an error occurs. The \e ui32DMAFlags parameter is the +//! logical OR of any of the following values: +//! +//! - UART_DMA_RX - enable DMA for receive +//! - UART_DMA_TX - enable DMA for transmit +//! - UART_DMA_ERR_RXSTOP - disable DMA receive on UART error +//! +//! \note The uDMA controller must also be set up before DMA can be used +//! with the UART. +//! +//! \return None +// +//***************************************************************************** +void +UARTDMAEnable(uint32_t ui32Base, uint32_t ui32DMAFlags) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Set the requested bits in the UART DMA control register. + // + HWREG(ui32Base + UART_O_DMACTL) |= ui32DMAFlags; +} + +//***************************************************************************** +// +//! Disable UART DMA operation +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32DMAFlags is a bit mask of the DMA features to disable. +//! +//! This function is used to disable UART DMA features that were enabled +//! by UARTDMAEnable(). The specified UART DMA features are disabled. The +//! \e ui32DMAFlags parameter is the logical OR of any of the following values: +//! +//! - UART_DMA_RX - disable DMA for receive +//! - UART_DMA_TX - disable DMA for transmit +//! - UART_DMA_ERR_RXSTOP - do not disable DMA receive on UART error +//! +//! \return None +// +//***************************************************************************** +void +UARTDMADisable(uint32_t ui32Base, uint32_t ui32DMAFlags) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Clear the requested bits in the UART DMA control register. + // + HWREG(ui32Base + UART_O_DMACTL) &= ~ui32DMAFlags; +} + +//***************************************************************************** +// +//! Gets current receiver errors +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function returns the current state of each of the 4 receiver error +//! sources. The returned errors are equivalent to the four error bits +//! returned via the previous call to UARTCharGet() or UARTCharGetNonBlocking() +//! with the exception that the overrun error is set immediately the overrun +//! occurs rather than when a character is next read. +//! +//! \return Returns a logical OR combination of the receiver error flags, +//! \b UART_RXERROR_FRAMING, \b UART_RXERROR_PARITY, \b UART_RXERROR_BREAK +//! and \b UART_RXERROR_OVERRUN. +// +//***************************************************************************** +uint32_t +UARTRxErrorGet(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Return the current value of the receive status register. + // + return(HWREG(ui32Base + UART_O_RSR) & 0x0000000F); +} + +//***************************************************************************** +// +//! Clears all reported receiver errors +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function is used to clear all receiver error conditions reported via +//! UARTRxErrorGet(). If using the overrun, framing error, parity error or +//! break interrupts, this function must be called after clearing the interrupt +//! to ensure that later errors of the same type trigger another interrupt. +//! +//! \return None +// +//***************************************************************************** +void +UARTRxErrorClear(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Any write to the Error Clear Register will clear all bits which are + // currently set. + // + HWREG(ui32Base + UART_O_ECR) = 0; +} + +//***************************************************************************** +// +//! Sets the baud clock source for the specified UART +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui32Source is the baud clock source for the UART. +//! +//! This function allows the baud clock source for the UART to be selected. +//! The possible clock source are the system clock (\b UART_CLOCK_SYSTEM) or +//! the precision internal oscillator (\b UART_CLOCK_PIOSC). +//! +//! If \b UART_CLOCK_SYSTEM is chosen, the IO clock frequency must thus be +//! queried by SysCtrlClcokSet(). +//! If \b UART_CLOCK_PIOSC the SysCtrlIOClcokSet() function must be used. +//! +//! Changing the baud clock source will change the baud rate generated by the +//! UART. Therefore, the baud rate should be reconfigured after any change to +//! the baud clock source. +//! +//! \note If the precision internal oscillator (\b UART_CLOCK_PIOSC) is used +//! for the UART baud clock, the system clock frequency must be at least +//! 9 MHz in Run mode. +//! +//! \sa UARTConfigSetExpClk() +//! +//! \return None +// +//***************************************************************************** +void +UARTClockSourceSet(uint32_t ui32Base, uint32_t ui32Source) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + ASSERT((ui32Source == UART_CLOCK_SYSTEM) || (ui32Source == UART_CLOCK_PIOSC)); + + // + // Set the UART clock source. + // + HWREG(ui32Base + UART_O_CC) = ui32Source; +} + +//***************************************************************************** +// +//! Gets the baud clock source for the specified UART +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function returns the baud clock source for the specified UART. The +//! possible baud clock source are the system clock (\b UART_CLOCK_SYSTEM) or +//! the precision internal oscillator (\b UART_CLOCK_PIOSC). +//! +//! \return None +// +//***************************************************************************** +uint32_t +UARTClockSourceGet(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Return the UART clock source. + // + return(HWREG(ui32Base + UART_O_CC)); +} + +//***************************************************************************** +// +//! Enables 9-bit mode on the specified UART +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function enables the 9-bit operational mode of the UART. +//! +//! \return None +// +//***************************************************************************** +void +UART9BitEnable(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Enable 9-bit mode. + // + HWREG(ui32Base + UART_O_NINEBITADDR) |= UART_NINEBITADDR_NINEBITEN; +} + +//***************************************************************************** +// +//! Disables 9-bit mode on the specified UART +//! +//! \param ui32Base is the base address of the UART port. +//! +//! This function disables the 9-bit operational mode of the UART. +//! +//! \return None +// +//***************************************************************************** +void +UART9BitDisable(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Disable 9-bit mode. + // + HWREG(ui32Base + UART_O_NINEBITADDR) &= ~UART_NINEBITADDR_NINEBITEN; +} + +//***************************************************************************** +// +//! Sets the device address(es) for 9-bit mode +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui8Addr is the device address. +//! \param ui8Mask is the device address mask. +//! +//! This function sets the device address, or range of device addresses, that +//! respond to requests on the 9-bit UART port. The received address is masked +//! with the mask and then compared against the given address, allowing either +//! a single address (if \b ui8Mask is 0xff) or a set of addresses to be +//! matched. +//! +//! \return None +// +//***************************************************************************** +void +UART9BitAddrSet(uint32_t ui32Base, uint8_t ui8Addr, + uint8_t ui8Mask) +{ + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Set the address and mask. + // + HWREG(ui32Base + UART_O_NINEBITADDR) = ui8Addr << UART_NINEBITADDR_ADDR_S; + HWREG(ui32Base + UART_O_NINEBITAMASK) = ui8Mask << UART_NINEBITAMASK_MASK_S; +} + +//***************************************************************************** +// +//! Sends an address character from the specified port when operating in 9-bit +//! mode +//! +//! \param ui32Base is the base address of the UART port. +//! \param ui8Addr is the address to be transmitted. +//! +//! This function waits until all data has been sent from the specified port +//! and then sends the given address as an address byte. It then waits until +//! the address byte has been transmitted before returning. +//! +//! The normal data functions (UARTCharPut(), UARTCharPutNonBlocking(), +//! UARTCharGet(), and UARTCharGetNonBlocking()) are used to send and receive +//! data characters in 9-bit mode. +//! +//! \return None +// +//***************************************************************************** +void +UART9BitAddrSend(uint32_t ui32Base, uint8_t ui8Addr) +{ + uint32_t ui32LCRH; + + // + // Check the arguments. + // + ASSERT(UARTBaseValid(ui32Base)); + + // + // Wait until the FIFO is empty and the UART is not busy. + // + while((HWREG(ui32Base + UART_O_FR) & (UART_FR_TXFE | UART_FR_BUSY)) != + UART_FR_TXFE) + { + } + + + // + // Force the address/data bit to 1 to indicate this is an address byte. + // + ui32LCRH = HWREG(ui32Base + UART_O_LCRH); + HWREG(ui32Base + UART_O_LCRH) = ((ui32LCRH & ~UART_LCRH_EPS) | UART_LCRH_SPS | + UART_LCRH_PEN); + + // + // Send the address. + // + HWREG(ui32Base + UART_O_DR) = ui8Addr; + + // + // Wait until the address has been sent. + // + while((HWREG(ui32Base + UART_O_FR) & (UART_FR_TXFE | UART_FR_BUSY)) != + UART_FR_TXFE) + { + } + + // + // Restore the address/data setting. + // + HWREG(ui32Base + UART_O_LCRH) = ui32LCRH; +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/uarthal.h b/bsp/boards/mimsy2-cc2538/source/uarthal.h new file mode 100644 index 0000000000..a84953bfc7 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/uarthal.h @@ -0,0 +1,219 @@ +/****************************************************************************** +* Filename: uarthal.h +* Revised: $Date: 2013-04-16 12:01:40 +0200 (Tue, 16 Apr 2013) $ +* Revision: $Revision: 9777 $ +* +* Description: Defines and Macros for the UART. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __UARTHAL_H__ +#define __UARTHAL_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// Values that can be passed to UARTIntEnable, UARTIntDisable, and UARTIntClear +// as the ui32IntFlags parameter, and returned from UARTIntStatus. +// +//***************************************************************************** +#define UART_INT_9BIT 0x1000 // 9-bit address match interrupt +#define UART_INT_OE 0x400 // Overrun Error Interrupt Mask +#define UART_INT_BE 0x200 // Break Error Interrupt Mask +#define UART_INT_PE 0x100 // Parity Error Interrupt Mask +#define UART_INT_FE 0x080 // Framing Error Interrupt Mask +#define UART_INT_RT 0x040 // Receive Timeout Interrupt Mask +#define UART_INT_TX 0x020 // Transmit Interrupt Mask +#define UART_INT_RX 0x010 // Receive Interrupt Mask +#define UART_INT_CTS 0x002 // CTS Modem Interrupt Mask (only + // UART1) + +//***************************************************************************** +// +// Values that can be passed to UARTConfigSetExpClk as the ui32Config parameter +// and returned by UARTConfigGetExpClk in the pui32Config parameter. +// Additionally, the UART_CONFIG_PAR_* subset can be passed to +// UARTParityModeSet as the ui32Parity parameter, and are returned by +// UARTParityModeGet. +// +//***************************************************************************** +#define UART_CONFIG_WLEN_MASK 0x00000060 // Mask for extracting word length +#define UART_CONFIG_WLEN_8 0x00000060 // 8 bit data +#define UART_CONFIG_WLEN_7 0x00000040 // 7 bit data +#define UART_CONFIG_WLEN_6 0x00000020 // 6 bit data +#define UART_CONFIG_WLEN_5 0x00000000 // 5 bit data +#define UART_CONFIG_STOP_MASK 0x00000008 // Mask for extracting stop bits +#define UART_CONFIG_STOP_ONE 0x00000000 // One stop bit +#define UART_CONFIG_STOP_TWO 0x00000008 // Two stop bits +#define UART_CONFIG_PAR_MASK 0x00000086 // Mask for extracting parity +#define UART_CONFIG_PAR_NONE 0x00000000 // No parity +#define UART_CONFIG_PAR_EVEN 0x00000006 // Even parity +#define UART_CONFIG_PAR_ODD 0x00000002 // Odd parity +#define UART_CONFIG_PAR_ONE 0x00000082 // Parity bit is one +#define UART_CONFIG_PAR_ZERO 0x00000086 // Parity bit is zero + +//***************************************************************************** +// +// Values that can be passed to UARTFIFOLevelSet as the ui32TxLevel parameter and +// returned by UARTFIFOLevelGet in the pui32TxLevel. +// +//***************************************************************************** +#define UART_FIFO_TX1_8 0x00000000 // Transmit interrupt at 1/8 Full +#define UART_FIFO_TX2_8 0x00000001 // Transmit interrupt at 1/4 Full +#define UART_FIFO_TX4_8 0x00000002 // Transmit interrupt at 1/2 Full +#define UART_FIFO_TX6_8 0x00000003 // Transmit interrupt at 3/4 Full +#define UART_FIFO_TX7_8 0x00000004 // Transmit interrupt at 7/8 Full + +//***************************************************************************** +// +// Values that can be passed to UARTFIFOLevelSet as the ui32RxLevel parameter and +// returned by UARTFIFOLevelGet in the pui32RxLevel. +// +//***************************************************************************** +#define UART_FIFO_RX1_8 0x00000000 // Receive interrupt at 1/8 Full +#define UART_FIFO_RX2_8 0x00000008 // Receive interrupt at 1/4 Full +#define UART_FIFO_RX4_8 0x00000010 // Receive interrupt at 1/2 Full +#define UART_FIFO_RX6_8 0x00000018 // Receive interrupt at 3/4 Full +#define UART_FIFO_RX7_8 0x00000020 // Receive interrupt at 7/8 Full + +//***************************************************************************** +// +// Values that can be passed to UARTDMAEnable() and UARTDMADisable(). +// +//***************************************************************************** +#define UART_DMA_ERR_RXSTOP 0x00000004 // Stop DMA receive if UART error +#define UART_DMA_TX 0x00000002 // Enable DMA for transmit +#define UART_DMA_RX 0x00000001 // Enable DMA for receive + +//***************************************************************************** +// +// Values returned from UARTRxErrorGet(). +// +//***************************************************************************** +#define UART_RXERROR_OVERRUN 0x00000008 +#define UART_RXERROR_BREAK 0x00000004 +#define UART_RXERROR_PARITY 0x00000002 +#define UART_RXERROR_FRAMING 0x00000001 + +//***************************************************************************** +// +// Values that can be passed to UARTTxIntModeSet() or returned from +// UARTTxIntModeGet(). +// +//***************************************************************************** +#define UART_TXINT_MODE_FIFO 0x00000000 +#define UART_TXINT_MODE_EOT 0x00000010 + +//***************************************************************************** +// +// Values that can be passed to UARTClockSourceSet() or returned from +// UARTClockSourceGet(). +// +//***************************************************************************** +#define UART_CLOCK_SYSTEM 0x00000000 +#define UART_CLOCK_PIOSC 0x00000001 + +//***************************************************************************** +// +// API Function prototypes +// +//***************************************************************************** +extern void UARTParityModeSet(uint32_t ui32Base, uint32_t ui32Parity); +extern uint32_t UARTParityModeGet(uint32_t ui32Base); +extern void UARTFIFOLevelSet(uint32_t ui32Base, uint32_t ui32TxLevel, + uint32_t ui32RxLevel); +extern void UARTFIFOLevelGet(uint32_t ui32Base, uint32_t *pui32TxLevel, + uint32_t *pui32RxLevel); +extern void UARTConfigSetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk, + uint32_t ui32Baud, uint32_t ui32Config); +extern void UARTConfigGetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk, + uint32_t *pui32Baud, + uint32_t *pui32Config); +extern void UARTEnable(uint32_t ui32Base); +extern void UARTDisable(uint32_t ui32Base); +extern void UARTFIFOEnable(uint32_t ui32Base); +extern void UARTFIFODisable(uint32_t ui32Base); +extern void UARTEnableSIR(uint32_t ui32Base, bool bLowPower); +extern void UARTDisableSIR(uint32_t ui32Base); +extern bool UARTCharsAvail(uint32_t ui32Base); +extern bool UARTSpaceAvail(uint32_t ui32Base); +extern int32_t UARTCharGetNonBlocking(uint32_t ui32Base); +extern int32_t UARTCharGet(uint32_t ui32Base); +extern bool UARTCharPutNonBlocking(uint32_t ui32Base, + uint8_t ui8Data); +extern void UARTCharPut(uint32_t ui32Base, uint8_t ui8Data); +extern void UARTBreakCtl(uint32_t ui32Base, bool bBreakState); +extern bool UARTBusy(uint32_t ui32Base); +extern void UARTIntRegister(uint32_t ui32Base, void (*pfnHandler)(void)); +extern void UARTIntUnregister(uint32_t ui32Base); +extern void UARTIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags); +extern void UARTIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags); +extern uint32_t UARTIntStatus(uint32_t ui32Base, bool bMasked); +extern void UARTIntClear(uint32_t ui32Base, uint32_t ui32IntFlags); +extern void UARTDMAEnable(uint32_t ui32Base, uint32_t ui32DMAFlags); +extern void UARTDMADisable(uint32_t ui32Base, uint32_t ui32DMAFlags); +extern uint32_t UARTRxErrorGet(uint32_t ui32Base); +extern void UARTRxErrorClear(uint32_t ui32Base); +extern void UARTTxIntModeSet(uint32_t ui32Base, uint32_t ui32Mode); +extern uint32_t UARTTxIntModeGet(uint32_t ui32Base); +extern void UARTClockSourceSet(uint32_t ui32Base, uint32_t ui32Source); +extern uint32_t UARTClockSourceGet(uint32_t ui32Base); +extern void UART9BitEnable(uint32_t ui32Base); +extern void UART9BitDisable(uint32_t ui32Base); +extern void UART9BitAddrSet(uint32_t ui32Base, uint8_t ui8Addr, + uint8_t ui8Mask); +extern void UART9BitAddrSend(uint32_t ui32Base, uint8_t ui8Addr); + + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __UARTHAL_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/udma.c b/bsp/boards/mimsy2-cc2538/source/udma.c new file mode 100644 index 0000000000..b8ac79cb62 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/udma.c @@ -0,0 +1,1250 @@ +/****************************************************************************** +* Filename: udma.c +* Revised: $Date: 2013-03-20 14:47:53 +0100 (Wed, 20 Mar 2013) $ +* Revision: $Revision: 9489 $ +* +* Description: Driver for the micro-DMA controller. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup udma_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include "debug.h" +#include "interrupt.h" +#include "udma.h" + +//***************************************************************************** +// +//! Enables the uDMA controller for use +//! +//! This function enables the uDMA controller. The uDMA controller must be +//! enabled before it can be configured and used. +//! +//! \return None +// +//***************************************************************************** +void +uDMAEnable(void) +{ + // + // Set the master enable bit in the config register. + // + HWREG(UDMA_CFG) = UDMA_CFG_MASTEN; +} + +//***************************************************************************** +// +//! Disables the uDMA controller for use +//! +//! This function disables the uDMA controller. Once disabled, the uDMA +//! controller will not operate until re-enabled with uDMAEnable(). +//! +//! \return None +// +//***************************************************************************** +void +uDMADisable(void) +{ + // + // Clear the master enable bit in the config register. + // + HWREG(UDMA_CFG) = 0; +} + +//***************************************************************************** +// +//! Gets the uDMA error status +//! +//! This function returns the uDMA error status. It should be called from +//! within the uDMA error interrupt handler to determine if a uDMA error +//! occurred. +//! +//! \return Returns non-zero if a uDMA error is pending. +// +//***************************************************************************** +uint32_t +uDMAErrorStatusGet(void) +{ + // + // Return the uDMA error status. + // + return(HWREG(UDMA_ERRCLR)); +} + +//***************************************************************************** +// +//! Clears the uDMA error interrupt +//! +//! This function clears a pending uDMA error interrupt. It should be called +//! from within the uDMA error interrupt handler to clear the interrupt. +//! +//! \return None +// +//***************************************************************************** +void +uDMAErrorStatusClear(void) +{ + // + // Clear the uDMA error interrupt. + // + HWREG(UDMA_ERRCLR) = 1; +} + +//***************************************************************************** +// +//! Enables a uDMA channel for operation +//! +//! \param ui32ChannelNum is the channel number to enable. +//! +//! This function enables a specific uDMA channel for use. This function must +//! be used to enable a channel before it can be used to perform a uDMA +//! transfer. +//! +//! When a uDMA transfer is completed, the channel will be automatically +//! disabled by the uDMA controller. Therefore, this function should be called +//! prior to starting up any new transfer. +//! +//! \return None +// +//***************************************************************************** +void +uDMAChannelEnable(uint32_t ui32ChannelNum) +{ + // + // Check the arguments. + // + ASSERT((ui32ChannelNum & 0xffff) < 32); + + // + // Set the bit for this channel in the enable set register. + // + HWREG(UDMA_ENASET) = 1 << (ui32ChannelNum & 0x1f); +} + +//***************************************************************************** +// +//! Disables a uDMA channel for operation +//! +//! \param ui32ChannelNum is the channel number to disable. +//! +//! This function disables a specific uDMA channel. Once disabled, a channel +//! will not respond to uDMA transfer requests until re-enabled via +//! uDMAChannelEnable(). +//! +//! \return None +// +//***************************************************************************** +void +uDMAChannelDisable(uint32_t ui32ChannelNum) +{ + // + // Check the arguments. + // + ASSERT((ui32ChannelNum & 0xffff) < 32); + + // + // Set the bit for this channel in the enable clear register. + // + HWREG(UDMA_ENACLR) = 1 << (ui32ChannelNum & 0x1f); +} + +//***************************************************************************** +// +//! Checks if a uDMA channel is enabled for operation +//! +//! \param ui32ChannelNum is the channel number to check. +//! +//! This function checks to see if a specific uDMA channel is enabled. This +//! can be used to check the status of a transfer, since the channel will +//! be automatically disabled at the end of a transfer. +//! +//! \return Returns \b true if the channel is enabled, \b false if disabled. +// +//***************************************************************************** +bool +uDMAChannelIsEnabled(uint32_t ui32ChannelNum) +{ + // + // Check the arguments. + // + ASSERT((ui32ChannelNum & 0xffff) < 32); + + // + // AND the specified channel bit with the enable register, and return the + // result. + // + + return((HWREG(UDMA_ENASET) & (1 << (ui32ChannelNum & 0x1f))) ? true : false); +} + +//***************************************************************************** +// +//! Sets the base address for the channel control table +//! +//! \param pControlTable is a pointer to the 1024 byte aligned base address +//! of the uDMA channel control table. +//! +//! This function sets the base address of the channel control table. This +//! table resides in system memory and holds control information for each uDMA +//! channel. The table must be aligned on a 1024 byte boundary. The base +//! address must be set before any of the channel functions can be used. +//! +//! The size of the channel control table depends on the number of uDMA +//! channels, and which transfer modes are used. Refer to the introductory +//! text and the microcontroller datasheet for more information about the +//! channel control table. +//! +//! \return None +// +//***************************************************************************** +void +uDMAControlBaseSet(void *pControlTable) +{ + // + // Check the arguments. + // + ASSERT(((uint32_t)pControlTable & ~0x3FF) == + (uint32_t)pControlTable); + ASSERT((uint32_t)pControlTable >= 0x20000000); + + // + // Program the base address into the register. + // + HWREG(UDMA_CTLBASE) = (uint32_t)pControlTable; +} + +//***************************************************************************** +// +//! Gets the base address for the channel control table +//! +//! This function gets the base address of the channel control table. This +//! table resides in system memory and holds control information for each uDMA +//! channel. +//! +//! \return Returns a pointer to the base address of the channel control table. +// +//***************************************************************************** +void * +uDMAControlBaseGet(void) +{ + // + // Read the current value of the control base register, and return it to + // the caller. + // + return((void *)HWREG(UDMA_CTLBASE)); +} + +//***************************************************************************** +// +//! Gets the base address for the channel control table alternate structures +//! +//! This function gets the base address of the second half of the channel +//! control table that holds the alternate control structures for each channel. +//! +//! \return Returns a pointer to the base address of the second half of the +//! channel control table. +// +//***************************************************************************** +void * +uDMAControlAlternateBaseGet(void) +{ + // + // Read the current value of the control base register, and return it to + // the caller. + // + return((void *)HWREG(UDMA_ALTBASE)); +} + +//***************************************************************************** +// +//! Requests a uDMA channel to start a transfer +//! +//! \param ui32ChannelNum is the channel number on which to request a uDMA +//! transfer. +//! +//! This function allows software to request a uDMA channel to begin a +//! transfer. This could be used for performing a memory to memory transfer, +//! or if for some reason a transfer needs to be initiated by software instead +//! of the peripheral associated with that channel. +//! +//! \note If the channel is \b UDMA_CH30_SW and interrupts +//! are used, then the completion will be signaled on the uDMA dedicated +//! interrupt. +//! If a peripheral channel is used, then the completion will be signaled on the +//! peripheral's interrupt. +//! +//! \return None +// +//***************************************************************************** +void +uDMAChannelRequest(uint32_t ui32ChannelNum) +{ + // + // Check the arguments. + // + ASSERT((ui32ChannelNum & 0xffff) < 32); + + // + // Set the bit for this channel in the software uDMA request register. + // + HWREG(UDMA_SWREQ) = 1 << (ui32ChannelNum & 0x1f); +} + +//***************************************************************************** +// +//! Enables attributes of a uDMA channel +//! +//! \param ui32ChannelNum is the channel to configure. +//! \param ui32Attr is a combination of attributes for the channel. +//! +//! This function is used to enable attributes of a uDMA channel. +//! +//! The \e ui32Attr parameter is the logical OR of any of the following: +//! +//! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only a burst +//! mode. +//! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure +//! for this channel (it is very unlikely that this flag should be used). +//! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority. +//! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the +//! peripheral for this channel. +//! +//! \return None +// +//***************************************************************************** +void +uDMAChannelAttributeEnable(uint32_t ui32ChannelNum, uint32_t ui32Attr) +{ + // + // Check the arguments. + // + ASSERT((ui32ChannelNum & 0xffff) < 32); + ASSERT((ui32Attr & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | + UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) == 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the ui32ChannelNum parameter, extract just the channel number + // from this parameter. + // + ui32ChannelNum &= 0x1f; + + // + // Set the useburst bit for this channel if set in ui32Config. + // + if(ui32Attr & UDMA_ATTR_USEBURST) + { + HWREG(UDMA_USEBURSTSET) = 1 << ui32ChannelNum; + } + + // + // Set the alternate control select bit for this channel, + // if set in ui32Config. + // + if(ui32Attr & UDMA_ATTR_ALTSELECT) + { + HWREG(UDMA_ALTSET) = 1 << ui32ChannelNum; + } + + // + // Set the high priority bit for this channel, if set in ui32Config. + // + if(ui32Attr & UDMA_ATTR_HIGH_PRIORITY) + { + HWREG(UDMA_PRIOSET) = 1 << ui32ChannelNum; + } + + // + // Set the request mask bit for this channel, if set in ui32Config. + // + if(ui32Attr & UDMA_ATTR_REQMASK) + { + HWREG(UDMA_REQMASKSET) = 1 << ui32ChannelNum; + } +} + +//***************************************************************************** +// +//! Disables attributes of a uDMA channel +//! +//! \param ui32ChannelNum is the channel to configure. +//! \param ui32Attr is a combination of attributes for the channel. +//! +//! This function is used to disable attributes of a uDMA channel. +//! +//! The \e ui32Attr parameter is the logical OR of any of the following: +//! +//! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only a burst +//! mode. +//! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure +//! for this channel. +//! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority. +//! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the +//! peripheral for this channel. +//! +//! \return None +// +//***************************************************************************** +void +uDMAChannelAttributeDisable(uint32_t ui32ChannelNum, uint32_t ui32Attr) +{ + // + // Check the arguments. + // + ASSERT((ui32ChannelNum & 0xffff) < 32); + ASSERT((ui32Attr & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | + UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) == 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the ui32ChannelNum parameter, extract just the channel number + // from this parameter. + // + ui32ChannelNum &= 0x1f; + + // + // Clear the useburst bit for this channel if set in ui32Config. + // + if(ui32Attr & UDMA_ATTR_USEBURST) + { + HWREG(UDMA_USEBURSTCLR) = 1 << ui32ChannelNum; + } + + // + // Clear the alternate control select bit for this channel, if set in + // ui32Config. + // + if(ui32Attr & UDMA_ATTR_ALTSELECT) + { + HWREG(UDMA_ALTCLR) = 1 << ui32ChannelNum; + } + + // + // Clear the high priority bit for this channel, if set in ui32Config. + // + if(ui32Attr & UDMA_ATTR_HIGH_PRIORITY) + { + HWREG(UDMA_PRIOCLR) = 1 << ui32ChannelNum; + } + + // + // Clear the request mask bit for this channel, if set in ui32Config. + // + if(ui32Attr & UDMA_ATTR_REQMASK) + { + HWREG(UDMA_REQMASKCLR) = 1 << ui32ChannelNum; + } +} + +//***************************************************************************** +// +//! Gets the enabled attributes of a uDMA channel +//! +//! \param ui32ChannelNum is the channel to configure. +//! +//! This function returns a combination of flags representing the attributes of +//! the uDMA channel. +//! +//! \return Returns the logical OR of the attributes of the uDMA channel, which +//! can be any of the following: +//! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only a burst +//! mode. +//! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure +//! for this channel. +//! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority. +//! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the +//! peripheral for this channel. +// +//***************************************************************************** +uint32_t +uDMAChannelAttributeGet(uint32_t ui32ChannelNum) +{ + uint32_t ui32Attr = 0; + + // + // Check the arguments. + // + ASSERT((ui32ChannelNum & 0xffff) < 32); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the ui32ChannelNum parameter, extract just the channel number + // from this parameter. + // + ui32ChannelNum &= 0x1f; + + // + // Check to see if useburst bit is set for this channel. + // + if(HWREG(UDMA_USEBURSTSET) & (1 << ui32ChannelNum)) + { + ui32Attr |= UDMA_ATTR_USEBURST; + } + + // + // Check to see if the alternate control bit is set for this channel. + // + if(HWREG(UDMA_ALTSET) & (1 << ui32ChannelNum)) + { + ui32Attr |= UDMA_ATTR_ALTSELECT; + } + + // + // Check to see if the high priority bit is set for this channel. + // + if(HWREG(UDMA_PRIOSET) & (1 << ui32ChannelNum)) + { + ui32Attr |= UDMA_ATTR_HIGH_PRIORITY; + } + + // + // Check to see if the request mask bit is set for this channel. + // + if(HWREG(UDMA_REQMASKSET) & (1 << ui32ChannelNum)) + { + ui32Attr |= UDMA_ATTR_REQMASK; + } + + // + // Return the configuration flags. + // + return(ui32Attr); +} + +//***************************************************************************** +// +//! Sets the control parameters for a uDMA channel control structure +//! +//! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number +//! with \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT. +//! \param ui32Control is logical OR of several control values to set the control +//! parameters for the channel. +//! +//! This function is used to set control parameters for a uDMA transfer. These +//! are typically parameters that are not changed often. +//! +//! The \e ui32ChannelStructIndex parameter should be the logical OR of the +//! channel number with one of \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to +//! choose whether the primary or alternate data structure is used. +//! +//! The \e ui32Control parameter is the logical OR of five values: the data size, +//! the source address increment, the destination address increment, the +//! arbitration size, and the use burst flag. The choices available for each +//! of these values is described below. +//! +//! Choose the data size from one of \b UDMA_SIZE_8, \b UDMA_SIZE_16, or +//! \b UDMA_SIZE_32 to select a data size of 8, 16, or 32 bits. +//! +//! Choose the source address increment from one of \b UDMA_SRC_INC_8, +//! \b UDMA_SRC_INC_16, \b UDMA_SRC_INC_32, or \b UDMA_SRC_INC_NONE to select +//! an address increment of 8-bit bytes, 16-bit halfwords, 32-bit words, or +//! to select non-incrementing. +//! +//! Choose the destination address increment from one of \b UDMA_DST_INC_8, +//! \b UDMA_DST_INC_16, \b UDMA_DST_INC_32, or \b UDMA_DST_INC_NONE to select +//! an address increment of 8-bit bytes, 16-bit halfwords, 32-bit words, or +//! to select non-incrementing. +//! +//! The arbitration size determines how many items are transferred before +//! the uDMA controller re-arbitrates for the bus. Choose the arbitration size +//! from one of \b UDMA_ARB_1, \b UDMA_ARB_2, \b UDMA_ARB_4, \b UDMA_ARB_8, +//! through \b UDMA_ARB_1024 to select the arbitration size from 1 to 1024 +//! items, in powers of 2. +//! +//! The value \b UDMA_NEXT_USEBURST is used to force the channel to only +//! respond to burst requests at the tail end of a scatter-gather transfer. +//! +//! \note The address increment cannot be smaller than the data size. +//! +//! \return None +// +//***************************************************************************** +void +uDMAChannelControlSet(uint32_t ui32ChannelStructIndex, + uint32_t ui32Control) +{ + tDMAControlTable *pCtl; + + // + // Check the arguments. + // + ASSERT((ui32ChannelStructIndex & 0xffff) < 64); + ASSERT(HWREG(UDMA_CTLBASE) != 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the ui32ChannelStructIndex parameter, extract just the channel + // index from this parameter. + // + ui32ChannelStructIndex &= 0x3f; + + // + // Get the base address of the control table. + // + pCtl = (tDMAControlTable *)HWREG(UDMA_CTLBASE); + + // + // Get the current control word value and mask off the fields to be + // changed, then OR in the new settings. + // + pCtl[ui32ChannelStructIndex].ui32Control = + ((pCtl[ui32ChannelStructIndex].ui32Control & + ~(UDMACHCTL_CHCTL_DSTINC_M | + UDMACHCTL_CHCTL_DSTSIZE_M | + UDMACHCTL_CHCTL_SRCINC_M | + UDMACHCTL_CHCTL_SRCSIZE_M | + UDMACHCTL_CHCTL_ARBSIZE_M | + UDMACHCTL_CHCTL_NXTUSEBURST)) | + ui32Control); +} + +//***************************************************************************** +// +//! Sets the transfer parameters for a uDMA channel control structure +//! +//! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number +//! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT. +//! \param ui32Mode is the type of uDMA transfer. +//! \param pvSrcAddr is the source address for the transfer. +//! \param pvDstAddr is the destination address for the transfer. +//! \param ui32TransferSize is the number of data items to transfer. +//! +//! This function is used to set the parameters for a uDMA transfer. These are +//! typically parameters that are changed often. The function +//! uDMAChannelControlSet() MUST be called at least once for this channel prior +//! to calling this function. +//! +//! The \e ui32ChannelStructIndex parameter should be the logical OR of the +//! channel number with one of \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to +//! choose whether the primary or alternate data structure is used. +//! +//! The \e ui32Mode parameter should be one of the following values: +//! +//! - \b UDMA_MODE_STOP stops the uDMA transfer. The controller sets the mode +//! to this value at the end of a transfer. +//! - \b UDMA_MODE_BASIC to perform a basic transfer based on request. +//! - \b UDMA_MODE_AUTO to perform a transfer that will always complete once +//! started even if request is removed. +//! - \b UDMA_MODE_PINGPONG to set up a transfer that switches between the +//! primary and alternate control structures for the channel. This allows +//! use of ping-pong buffering for uDMA transfers. +//! - \b UDMA_MODE_MEM_SCATTER_GATHER to set up a memory scatter-gather +//! transfer. +//! - \b UDMA_MODE_PER_SCATTER_GATHER to set up a peripheral scatter-gather +//! transfer. +//! +//! The \e pvSrcAddr and \e pvDstAddr parameters are pointers to the first +//! location of the data to be transferred. These addresses should be aligned +//! according to the item size. The compiler will take care of this if the +//! pointers are pointing to storage of the appropriate data type. +//! +//! The \e ui32TransferSize parameter is the number of data items, not the number +//! of bytes. +//! +//! The two scatter/gather modes, memory and peripheral, are actually different +//! depending on whether the primary or alternate control structure is +//! selected. This function will look for the \b UDMA_PRI_SELECT and +//! \b UDMA_ALT_SELECT flag along with the channel number and will set the +//! scatter/gather mode as appropriate for the primary or alternate control +//! structure. +//! +//! The channel must also be enabled using uDMAChannelEnable() after calling +//! this function. The transfer will not begin until the channel has been set +//! up and enabled. Note that the channel is automatically disabled after the +//! transfer is completed, meaning that uDMAChannelEnable() must be called +//! again after setting up the next transfer. +//! +//! \note Great care must be taken to not modify a channel control structure +//! that is in use or else the results will be unpredictable, including the +//! possibility of undesired data transfers to or from memory or peripherals. +//! For BASIC and AUTO modes, it is safe to make changes when the channel is +//! disabled, or the uDMAChannelModeGet() returns \b UDMA_MODE_STOP. For +//! PINGPONG or one of the SCATTER_GATHER modes, it is safe to modify the +//! primary or alternate control structure only when the other is being used. +//! The uDMAChannelModeGet() function will return \b UDMA_MODE_STOP when a +//! channel control structure is inactive and safe to modify. +//! +//! \return None +// +//***************************************************************************** +void +uDMAChannelTransferSet(uint32_t ui32ChannelStructIndex, + uint32_t ui32Mode, void *pvSrcAddr, void *pvDstAddr, + uint32_t ui32TransferSize) +{ + tDMAControlTable *pControlTable; + uint32_t ui32Control; + uint32_t ui32Inc; + uint32_t ui32BufferBytes; + + // + // Check the arguments. + // + ASSERT((ui32ChannelStructIndex & 0xffff) < 64); + ASSERT(HWREG(UDMA_CTLBASE) != 0); + ASSERT(ui32Mode <= UDMA_MODE_PER_SCATTER_GATHER); + ASSERT((uint32_t)pvSrcAddr >= 0x20000000); + ASSERT((uint32_t)pvDstAddr >= 0x20000000); + ASSERT((ui32TransferSize != 0) && (ui32TransferSize <= 1024)); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the ui32ChannelStructIndex parameter, extract just the channel + // index from this parameter. + // + ui32ChannelStructIndex &= 0x3f; + + // + // Get the base address of the control table. + // + pControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE); + + // + // Get the current control word value and mask off the mode and size + // fields. + // + ui32Control = (pControlTable[ui32ChannelStructIndex].ui32Control & + ~(UDMACHCTL_CHCTL_XFERSIZE_M | UDMACHCTL_CHCTL_XFERMODE_M)); + + // + // Adjust the mode if the alt control structure is selected. + // + if(ui32ChannelStructIndex & UDMA_ALT_SELECT) + { + if((ui32Mode == UDMA_MODE_MEM_SCATTER_GATHER) || + (ui32Mode == UDMA_MODE_PER_SCATTER_GATHER)) + { + ui32Mode |= UDMA_MODE_ALT_SELECT; + } + } + + // + // Set the transfer size and mode in the control word (but don't write the + // control word yet as it could kick off a transfer). + // + ui32Control |= ui32Mode | ((ui32TransferSize - 1) << 4); + + // + // Get the address increment value for the source, from the control word. + // + ui32Inc = (ui32Control & UDMACHCTL_CHCTL_SRCINC_M); + + // + // Compute the ending source address of the transfer. If the source + // increment is set to none, then the ending address is the same as the + // beginning. + // + if(ui32Inc != UDMA_SRC_INC_NONE) + { + ui32Inc = ui32Inc >> 26; + ui32BufferBytes = ui32TransferSize << ui32Inc; + pvSrcAddr = (void *)((uint32_t)pvSrcAddr + ui32BufferBytes - 1); + } + + // + // Load the source ending address into the control block. + // + pControlTable[ui32ChannelStructIndex].pvSrcEndAddr = pvSrcAddr; + + // + // Get the address increment value for the destination, from the control + // word. + // + ui32Inc = ui32Control & UDMACHCTL_CHCTL_DSTINC_M; + + // + // Compute the ending destination address of the transfer. If the + // destination increment is set to none, then the ending address is the + // same as the beginning. + // + if(ui32Inc != UDMA_DST_INC_NONE) + { + // + // There is a special case if this is setting up a scatter-gather + // transfer. The destination pointer needs to point to the end of + // the alternate structure for this channel instead of calculating + // the end of the buffer in the normal way. + // + if((ui32Mode == UDMA_MODE_MEM_SCATTER_GATHER) || + (ui32Mode == UDMA_MODE_PER_SCATTER_GATHER)) + { + pvDstAddr = + (void *)&pControlTable[ui32ChannelStructIndex | + UDMA_ALT_SELECT].ui32Spare; + } + // + // Not a scatter-gather transfer, calculate end pointer normally. + // + else + { + ui32Inc = ui32Inc >> 30; + ui32BufferBytes = ui32TransferSize << ui32Inc; + pvDstAddr = (void *)((uint32_t)pvDstAddr + ui32BufferBytes - 1); + } + } + + // + // Load the destination ending address into the control block. + // + pControlTable[ui32ChannelStructIndex].pvDstEndAddr = pvDstAddr; + + // + // Write the new control word value. + // + pControlTable[ui32ChannelStructIndex].ui32Control = ui32Control; +} + +//***************************************************************************** +// +//! Configures a uDMA channel for scatter-gather mode +//! +//! \param ui32ChannelNum is the uDMA channel number. +//! \param ui32TaskCount is the number of scatter-gather tasks to execute. +//! \param pvTaskList is a pointer to the beginning of the scatter-gather +//! task list. +//! \param ui32IsPeriphSG is a flag to indicate it is a peripheral scatter-gather +//! transfer (else it will be memory scatter-gather transfer) +//! +//! This function is used to configure a channel for scatter-gather mode. +//! The caller must have already set up a task list, and pass a pointer to +//! the start of the task list as the \e pvTaskList parameter. The +//! \e ui32TaskCount parameter is the count of tasks in the task list, not the +//! size of the task list. The flag \e bIsPeriphSG should be used to indicate +//! if the scatter-gather should be configured for a peripheral or memory +//! scatter-gather operation. +//! +//! \sa uDMATaskStructEntry +//! +//! \return None +// +//***************************************************************************** +void +uDMAChannelScatterGatherSet(uint32_t ui32ChannelNum, + uint32_t ui32TaskCount, void *pvTaskList, + uint32_t ui32IsPeriphSG) +{ + tDMAControlTable *pControlTable; + tDMAControlTable *pTaskTable; + + // + // Check the parameters + // + ASSERT((ui32ChannelNum & 0xffff) < 32); + ASSERT(HWREG(UDMA_CTLBASE) != 0); + ASSERT(pvTaskList != 0); + ASSERT(ui32TaskCount <= 1024); + ASSERT(ui32TaskCount != 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the ui32ChannelNum parameter, extract just the channel number + // from this parameter. + // + ui32ChannelNum &= 0x1f; + + // + // Get the base address of the control table. + // + pControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE); + + // + // Get a handy pointer to the task list + // + pTaskTable = (tDMAControlTable *)pvTaskList; + + // + // Compute the ending address for the source pointer. This will be the + // last element of the last task in the task table + // + pControlTable[ui32ChannelNum].pvSrcEndAddr = + &pTaskTable[ui32TaskCount - 1].ui32Spare; + + // + // Compute the ending address for the destination pointer. This will be + // the end of the alternate structure for this channel. + // + pControlTable[ui32ChannelNum].pvDstEndAddr = + &pControlTable[ui32ChannelNum | UDMA_ALT_SELECT].ui32Spare; + + // + // Compute the control word. Most configurable items are fixed for + // scatter-gather. Item and increment sizes are all 32-bit and arb + // size must be 4. The count is the number of items in the task list + // times 4 (4 words per task). + // + pControlTable[ui32ChannelNum].ui32Control = + (UDMA_CHCTL_DSTINC_32 | UDMA_CHCTL_DSTSIZE_32 | + UDMA_CHCTL_SRCINC_32 | UDMA_CHCTL_SRCSIZE_32 | + UDMA_CHCTL_ARBSIZE_4 | + (((ui32TaskCount * 4) - 1) << UDMACHCTL_CHCTL_XFERSIZE_S) | + (ui32IsPeriphSG ? UDMA_CHCTL_XFERMODE_PER_SG : + UDMA_CHCTL_XFERMODE_MEM_SG)); +} + +//***************************************************************************** +// +//! Gets the current transfer size for a uDMA channel control structure +//! +//! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number +//! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT. +//! +//! This function is used to get the uDMA transfer size for a channel. The +//! transfer size is the number of items to transfer, where the size of an item +//! might be 8, 16, or 32 bits. If a partial transfer has already occurred, +//! then the number of remaining items will be returned. If the transfer is +//! complete, then 0 will be returned. +//! +//! \return Returns the number of items remaining to transfer. +// +//***************************************************************************** +uint32_t +uDMAChannelSizeGet(uint32_t ui32ChannelStructIndex) +{ + tDMAControlTable *pControlTable; + uint32_t ui32Control; + + // + // Check the arguments. + // + ASSERT((ui32ChannelStructIndex & 0xffff) < 64); + ASSERT(HWREG(UDMA_CTLBASE) != 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the ui32ChannelStructIndex parameter, extract just the channel + // index from this parameter. + // + ui32ChannelStructIndex &= 0x3f; + + // + // Get the base address of the control table. + // + pControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE); + + // + // Get the current control word value and mask off all but the size field + // and the mode field. + // + ui32Control = (pControlTable[ui32ChannelStructIndex].ui32Control & + (UDMACHCTL_CHCTL_XFERSIZE_M | UDMACHCTL_CHCTL_XFERMODE_M)); + + // + // If the size field and mode field are 0 then the transfer is finished + // and there are no more items to transfer + // + if(ui32Control == 0) + { + return(0); + } + + // + // Otherwise, if either the size field or more field is non-zero, then + // not all the items have been transferred. + // + else + { + // + // Shift the size field and add one, then return to user. + // + return((ui32Control >> 4) + 1); + } +} + +//***************************************************************************** +// +//! Gets the transfer mode for a uDMA channel control structure +//! +//! \param ui32ChannelStructIndex is the logical OR of the uDMA channel number +//! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT. +//! +//! This function is used to get the transfer mode for the uDMA channel. It +//! can be used to query the status of a transfer on a channel. When the +//! transfer is complete the mode will be \b UDMA_MODE_STOP. +//! +//! \return Returns the transfer mode of the specified channel and control +//! structure, which will be one of the following values: \b UDMA_MODE_STOP, +//! \b UDMA_MODE_BASIC, \b UDMA_MODE_AUTO, \b UDMA_MODE_PINGPONG, +//! \b UDMA_MODE_MEM_SCATTER_GATHER, or \b UDMA_MODE_PER_SCATTER_GATHER. +// +//***************************************************************************** +uint32_t +uDMAChannelModeGet(uint32_t ui32ChannelStructIndex) +{ + tDMAControlTable *pControlTable; + uint32_t ui32Control; + + // + // Check the arguments. + // + ASSERT((ui32ChannelStructIndex & 0xffff) < 64); + ASSERT(HWREG(UDMA_CTLBASE) != 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the ui32ChannelStructIndex parameter, extract just the channel + // index from this parameter. + // + ui32ChannelStructIndex &= 0x3f; + + // + // Get the base address of the control table. + // + pControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE); + + // + // Get the current control word value and mask off all but the mode field. + // + ui32Control = (pControlTable[ui32ChannelStructIndex].ui32Control & + UDMACHCTL_CHCTL_XFERMODE_M); + + // + // Check if scatter/gather mode, and if so, mask off the alt bit. + // + if(((ui32Control & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_MEM_SCATTER_GATHER) || + ((ui32Control & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_PER_SCATTER_GATHER)) + { + ui32Control &= ~UDMA_MODE_ALT_SELECT; + } + + // + // Return the mode to the caller. + // + return(ui32Control); +} + + +//***************************************************************************** +// +//! Registers an interrupt handler for the uDMA controller +//! +//! \param ui32IntChannel identifies which uDMA interrupt is to be registered. +//! \param pfnHandler is a pointer to the function to be called when the +//! interrupt is activated. +//! +//! This sets and enables the handler to be called when the uDMA controller +//! generates an interrupt. The \e ui32IntChannel parameter should be one of the +//! following: +//! +//! - \b UDMA_INT_SW to register an interrupt handler to process interrupts +//! from the uDMA software channel (UDMA_CH30_SW) +//! - \b UDMA_INT_ERR to register an interrupt handler to process uDMA error +//! interrupts +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \note The interrupt handler for uDMA is for transfer completion when the +//! channel UDMA_CH30W is used, and for error interrupts. The +//! interrupts for each peripheral channel are handled through the individual +//! peripheral interrupt handlers. +//! +//! \return None +// +//***************************************************************************** +void +uDMAIntRegister(uint32_t ui32IntChannel, void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(pfnHandler); + ASSERT((ui32IntChannel == UDMA_INT_SW) || (ui32IntChannel == UDMA_INT_ERR)); + + // + // Register the interrupt handler. + // + IntRegister(ui32IntChannel, pfnHandler); + + // + // Enable the memory management fault. + // + IntEnable(ui32IntChannel); +} + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the uDMA controller +//! +//! \param ui32IntChannel identifies which uDMA interrupt to unregister. +//! +//! This function will disable and clear the handler to be called for the +//! specified uDMA interrupt. The \e ui32IntChannel parameter should be one of +//! \b UDMA_INT_SW or \b UDMA_INT_ERR as documented for the function +//! uDMAIntRegister(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None +// +//***************************************************************************** +void +uDMAIntUnregister(uint32_t ui32IntChannel) +{ + // + // Disable the interrupt. + // + IntDisable(ui32IntChannel); + + // + // Unregister the interrupt handler. + // + IntUnregister(ui32IntChannel); +} + +//***************************************************************************** +// +//! Gets the uDMA controller channel interrupt status +//! +//! This function is used to get the interrupt status of the uDMA controller. +//! The returned value is a 32-bit bit mask that indicates which channels are +//! requesting an interrupt. This function can be used from within an +//! interrupt handler to determine or confirm which uDMA channel has requested +//! an interrupt. +//! +//! \note This function is only available on devices that have the DMA Channel +//! Interrupt Status Register (DMACHIS). Please consult the data sheet for +//! your part. +//! +//! \return Returns a 32-bit mask which indicates requesting uDMA channels. +//! There is a bit for each channel, and a 1 in a bit indicates that channel +//! is requesting an interrupt. Multiple bits can be set. +// +//***************************************************************************** +uint32_t +uDMAIntStatus(void) +{ + // + // Return the value of the uDMA interrupt status register + // + return(HWREG(UDMA_CHIS)); +} + +//***************************************************************************** +// +//! Clears uDMA interrupt status +//! +//! \param ui32ChanMask is a 32-bit mask with one bit for each uDMA channel. +//! +//! Clears bits in the uDMA interrupt status register according to which bits +//! are set in \e ui32ChanMask. There is one bit for each channel. If a a bit +//! is set in \e ui32ChanMask, then that corresponding channel's interrupt +//! status will be cleared (if it was set). +//! +//! \note This function is only available on devices that have the DMA Channel +//! Interrupt Status Register (DMACHIS). Please consult the data sheet for +//! your part. +//! +//! \return None +// +//***************************************************************************** +void +uDMAIntClear(uint32_t ui32ChanMask) +{ + // + // Clear the requested bits in the uDMA interrupt status register + // + HWREG(UDMA_CHIS) = ui32ChanMask; +} + +//***************************************************************************** +// +//! Assigns a peripheral mapping for a uDMA channel +//! +//! \param ui32Mapping is a macro specifying the peripheral assignment for +//! a channel +//! +//! This function assigns a peripheral mapping to a uDMA channel. It is +//! used to select which peripheral is used for a uDMA channel. The parameter +//! \e ui32Mapping should be one of the macros named \b UDMA_CHn_tttt from the +//! header file \e udma.h. For example, to assign uDMA channel 8 to the +//! UART0RX channel, the parameter should be the macro \b UDMA_CH8_UART0RX. +//! +//! Please consult the cc2538 data sheet for a table showing all the +//! possible peripheral assignments for the uDMA channels for a particular +//! device. +//! +//! \note This function is only available on devices that have the DMA Channel +//! Map Select registers (DMACHMAP0-3). Please consult the data sheet for +//! your part. +//! +//! \return None +// +//***************************************************************************** +void +uDMAChannelAssign(uint32_t ui32Mapping) +{ + uint32_t ui32MapReg; + uint32_t ui32MapShift; + uint32_t ui32ChannelNum; + uint32_t ui32Encoding; + + // + // Check the parameters + // + ASSERT((ui32Mapping & 0xffffff00) < 0x00050000); + + // + // Extract the channel number and map encoding value from the parameter. + // + ui32ChannelNum = ui32Mapping & 0xff; + ui32Encoding = ui32Mapping >> 16; + + // + // Find the uDMA channel mapping register and shift value to use for this + // channel + // + ui32MapReg = UDMA_CHMAP0 + ((ui32ChannelNum / 8) * 4); + ui32MapShift = (ui32ChannelNum % 8) * 4; + + // + // Set the channel map encoding for this channel + // + HWREG(ui32MapReg) = (HWREG(ui32MapReg) & ~(0xf << ui32MapShift)) | + ui32Encoding << ui32MapShift; +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/udma.h b/bsp/boards/mimsy2-cc2538/source/udma.h new file mode 100644 index 0000000000..5e3e207406 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/udma.h @@ -0,0 +1,658 @@ +/****************************************************************************** +* Filename: udma.h +* Revised: $Date: 2013-02-19 10:35:37 +0100 (Tue, 19 Feb 2013) $ +* Revision: $Revision: 9322 $ +* +* Description: Prototypes and macros for the uDMA controller. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __UDMA_H__ +#define __UDMA_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +//! \addtogroup udma_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// A structure that defines an entry in the channel control table. These +// fields are used by the uDMA controller and normally it is not necessary for +// software to directly read or write fields in the table. +// +//***************************************************************************** +typedef struct +{ + // + // The ending source address of the data transfer. + // + volatile void *pvSrcEndAddr; + + // + // The ending destination address of the data transfer. + // + volatile void *pvDstEndAddr; + + // + // The channel control mode. + // + volatile uint32_t ui32Control; + + // + // An unused location. + // + volatile uint32_t ui32Spare; +} +tDMAControlTable; + +//***************************************************************************** +// +//! A helper macro for building scatter-gather task table entries. +//! +//! \param ui32TransferCount is the count of items to transfer for this task. +//! \param ui32ItemSize is the bit size of the items to transfer for this task. +//! \param ui32SrcIncrement is the bit size increment for source data. +//! \param pvSrcAddr is the starting address of the data to transfer. +//! \param ui32DstIncrement is the bit size increment for destination data. +//! \param pvDstAddr is the starting address of the destination data. +//! \param ui32ArbSize is the arbitration size to use for the transfer task. +//! \param ui32Mode is the transfer mode for this task. +//! +//! This macro is intended to be used to help populate a table of uDMA tasks +//! for a scatter-gather transfer. This macro will calculate the values for +//! the fields of a task structure entry based on the input parameters. +//! +//! There are specific requirements for the values of each parameter. No +//! checking is done so it is up to the caller to ensure that correct values +//! are used for the parameters. +//! +//! The \e ui32TransferCount parameter is the number of items that will be +//! transferred by this task. It must be in the range 1-1024. +//! +//! The \e ui32ItemSize parameter is the bit size of the transfer data. It must +//! be one of \b UDMA_SIZE_8, \b UDMA_SIZE_16, or \b UDMA_SIZE_32. +//! +//! The \e ui32SrcIncrement parameter is the increment size for the source data. +//! It must be one of \b UDMA_SRC_INC_8, \b UDMA_SRC_INC_16, +//! \b UDMA_SRC_INC_32, or \b UDMA_SRC_INC_NONE. +//! +//! The \e pvSrcAddr parameter is a void pointer to the beginning of the source +//! data. +//! +//! The \e ui32DstIncrement parameter is the increment size for the destination +//! data. It must be one of \b UDMA_DST_INC_8, \b UDMA_DST_INC_16, +//! \b UDMA_DST_INC_32, or \b UDMA_DST_INC_NONE. +//! +//! The \e pvDstAddr parameter is a void pointer to the beginning of the +//! location where the data will be transferred. +//! +//! The \e ui32ArbSize parameter is the arbitration size for the transfer, and +//! must be one of \b UDMA_ARB_1, \b UDMA_ARB_2, \b UDMA_ARB_4, and so on +//! up to \b UDMA_ARB_1024. This is used to select the arbitration size in +//! powers of 2, from 1 to 1024. +//! +//! The \e ui32Mode parameter is the mode to use for this transfer task. It +//! must be one of \b UDMA_MODE_BASIC, \b UDMA_MODE_AUTO, +//! \b UDMA_MODE_MEM_SCATTER_GATHER, or \b UDMA_MODE_PER_SCATTER_GATHER. Note +//! that normally all tasks will be one of the scatter-gather modes while the +//! last task is a task list will be AUTO or BASIC. +//! +//! This macro is intended to be used to initialize individual entries of +//! a structure of tDMAControlTable type, like this: +//! +//! \verbatim +//! tDMAControlTable MyTaskList[] = +//! { +//! uDMATaskStructEntry(Task1Count, UDMA_SIZE_8, +//! UDMA_SRC_INC_8, MySourceBuf, +//! UDMA_DST_INC_8, MyDestBuf, +//! UDMA_ARB_8, UDMA_MODE_MEM_SCATTER_GATHER), +//! uDMATaskStructEntry(Task2Count, ... ), +//! } +//! \endverbatim +//! +//! \return Nothing; this is not a function. +// +//***************************************************************************** +#define uDMATaskStructEntry(ui32TransferCount, \ + ui32ItemSize, \ + ui32SrcIncrement, \ + pvSrcAddr, \ + ui32DstIncrement, \ + pvDstAddr, \ + ui32ArbSize, \ + ui32Mode) \ + { \ + (((ui32SrcIncrement) == UDMA_SRC_INC_NONE) ? (pvSrcAddr) : \ + ((void *)(&((uint8_t *)(pvSrcAddr))[((ui32TransferCount) << \ + ((ui32SrcIncrement) >> 26)) - 1]))), \ + (((ui32DstIncrement) == UDMA_DST_INC_NONE) ? (pvDstAddr) : \ + ((void *)(&((uint8_t *)(pvDstAddr))[((ui32TransferCount) << \ + ((ui32DstIncrement) >> 30)) - 1]))), \ + (ui32SrcIncrement) | (ui32DstIncrement) | (ui32ItemSize) | (ui32ArbSize) | \ + (((ui32TransferCount) - 1) << 4) | \ + ((((ui32Mode) == UDMA_MODE_MEM_SCATTER_GATHER) || \ + ((ui32Mode) == UDMA_MODE_PER_SCATTER_GATHER)) ? \ + (ui32Mode) | UDMA_MODE_ALT_SELECT : (ui32Mode)), 0 \ + } + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +//***************************************************************************** +// +// Flags that can be passed to uDMAChannelAttributeEnable(), +// uDMAChannelAttributeDisable(), and returned from uDMAChannelAttributeGet(). +// +//***************************************************************************** +#define UDMA_ATTR_USEBURST 0x00000001 +#define UDMA_ATTR_ALTSELECT 0x00000002 +#define UDMA_ATTR_HIGH_PRIORITY 0x00000004 +#define UDMA_ATTR_REQMASK 0x00000008 +#define UDMA_ATTR_ALL 0x0000000F + +//***************************************************************************** +// +// DMA control modes that can be passed to uDMAModeSet() and returned +// uDMAModeGet(). +// +//***************************************************************************** +#define UDMA_MODE_STOP 0x00000000 +#define UDMA_MODE_BASIC 0x00000001 +#define UDMA_MODE_AUTO 0x00000002 +#define UDMA_MODE_PINGPONG 0x00000003 +#define UDMA_MODE_MEM_SCATTER_GATHER \ + 0x00000004 +#define UDMA_MODE_PER_SCATTER_GATHER \ + 0x00000006 +#define UDMA_MODE_ALT_SELECT 0x00000001 + +//***************************************************************************** +// +// Channel configuration values that can be passed to uDMAControlSet(). +// +//***************************************************************************** +#define UDMA_DST_INC_8 0x00000000 +#define UDMA_DST_INC_16 0x40000000 +#define UDMA_DST_INC_32 0x80000000 +#define UDMA_DST_INC_NONE 0xc0000000 +#define UDMA_SRC_INC_8 0x00000000 +#define UDMA_SRC_INC_16 0x04000000 +#define UDMA_SRC_INC_32 0x08000000 +#define UDMA_SRC_INC_NONE 0x0c000000 +#define UDMA_SIZE_8 0x00000000 +#define UDMA_SIZE_16 0x11000000 +#define UDMA_SIZE_32 0x22000000 +#define UDMA_ARB_1 0x00000000 +#define UDMA_ARB_2 0x00004000 +#define UDMA_ARB_4 0x00008000 +#define UDMA_ARB_8 0x0000c000 +#define UDMA_ARB_16 0x00010000 +#define UDMA_ARB_32 0x00014000 +#define UDMA_ARB_64 0x00018000 +#define UDMA_ARB_128 0x0001c000 +#define UDMA_ARB_256 0x00020000 +#define UDMA_ARB_512 0x00024000 +#define UDMA_ARB_1024 0x00028000 +#define UDMA_NEXT_USEBURST 0x00000008 + +//***************************************************************************** +// +// Flags to be OR'd with the channel ID to indicate if the primary or alternate +// control structure should be used. +// +//***************************************************************************** +#define UDMA_PRI_SELECT 0x00000000 +#define UDMA_ALT_SELECT 0x00000020 + +//***************************************************************************** +// +// uDMA interrupt sources, to be passed to uDMAIntRegister() and +// uDMAIntUnregister(). +// +//***************************************************************************** +#define UDMA_INT_SW 62 +#define UDMA_INT_ERR 63 + +//***************************************************************************** +// +// Values that can be passed to uDMAChannelMapConfigure() to select peripheral +// mapping for each channel. The channels named RESERVED may be assigned +// to a peripheral in future parts. +// +//***************************************************************************** +// +// Channel 0 +// +#define UDMA_CH0_RESERVED0 0x00000000 +#define UDMA_CH0_RESERVED1 0x00010000 +#define UDMA_CH0_RESERVED2 0x00020000 +#define UDMA_CH0_RESERVED3 0x00030000 +#define UDMA_CH0_USB 0x00040000 + +// +// Channel 1 +// +#define UDMA_CH1_RESERVED0 0x00000001 +#define UDMA_CH1_RESERVED1 0x00010001 +#define UDMA_CH1_RESERVED2 0x00020001 +#define UDMA_CH1_RESERVED3 0x00030001 +#define UDMA_CH1_ADC 0x00040001 + +// +// Channel 2 +// +#define UDMA_CH2_RESERVED0 0x00000002 +#define UDMA_CH2_TIMER3A 0x00010002 +#define UDMA_CH2_RESERVED2 0x00020002 +#define UDMA_CH2_RESERVED3 0x00030002 +#define UDMA_CH2_FLASH 0x00040002 + +// +// Channel 3 +// +#define UDMA_CH3_RESERVED0 0x00000003 +#define UDMA_CH3_TIMER3B 0x00010003 +#define UDMA_CH3_RESERVED2 0x00020003 +#define UDMA_CH3_RESERVED3 0x00030003 +#define UDMA_CH3_RFCORETRG1 0x00040003 + +// +// Channel 4 +// +#define UDMA_CH4_RESERVED0 0x00000004 +#define UDMA_CH4_TIMER2A 0x00010004 +#define UDMA_CH4_RESERVED2 0x00020004 +#define UDMA_CH4_RESERVED3 0x00030004 +#define UDMA_CH4_RFCORETRG2 0x00040004 + +// +// Channel 5 +// +#define UDMA_CH5_RESERVED0 0x00000005 +#define UDMA_CH5_TIMER2B 0x00010005 +#define UDMA_CH5_RESERVED2 0x00020005 +#define UDMA_CH5_RESERVED3 0x00030005 +#define UDMA_CH5_RESERVED4 0x00040005 + +// +// Channel 6 +// +#define UDMA_CH6_RESERVED0 0x00000006 +#define UDMA_CH6_TIMER2A 0x00010006 +#define UDMA_CH6_RESERVED2 0x00020006 +#define UDMA_CH6_RESERVED3 0x00030006 +#define UDMA_CH6_RESERVED4 0x00040006 + +// +// Channel 7 +// +#define UDMA_CH7_RESERVED0 0x00000007 +#define UDMA_CH7_TIMER2B 0x00010007 +#define UDMA_CH7_RESERVED2 0x00020007 +#define UDMA_CH7_RESERVED3 0x00030007 +#define UDMA_CH7_RESERVED4 0x00040007 + +// +// Channel 8 +// +#define UDMA_CH8_UART0RX 0x00000008 +#define UDMA_CH8_UART1RX 0x00010008 +#define UDMA_CH8_RESERVED2 0x00020008 +#define UDMA_CH8_RESERVED3 0x00030008 +#define UDMA_CH8_RESERVED4 0x00040008 + +// +// Channel 9 +// +#define UDMA_CH9_UART0TX 0x00000009 +#define UDMA_CH9_UART1TX 0x00010009 +#define UDMA_CH9_RESERVED2 0x00020009 +#define UDMA_CH9_RESERVED3 0x00030009 +#define UDMA_CH9_RESERVED4 0x00040009 + +// +// Channel 10 +// +#define UDMA_CH10_SSI0RX 0x0000000A +#define UDMA_CH10_SSI1RX 0x0001000A +#define UDMA_CH10_RESERVED2 0x0002000A +#define UDMA_CH10_RESERVED3 0x0003000A +#define UDMA_CH10_RESERVED4 0x0004000A + +// +// Channel 11 +// +#define UDMA_CH11_SSI0TX 0x0000000B +#define UDMA_CH11_SSI1TX 0x0001000B +#define UDMA_CH11_RESERVED2 0x0002000B +#define UDMA_CH11_RESERVED3 0x0003000B +#define UDMA_CH11_RESERVED4 0x0004000B + +// +// Channel 12 +// +#define UDMA_CH12_RESERVED0 0x0000000C +#define UDMA_CH12_RESERVED1 0x0001000C +#define UDMA_CH12_RESERVED2 0x0002000C +#define UDMA_CH12_RESERVED3 0x0003000C +#define UDMA_CH12_RESERVED4 0x0004000C + +// +// Channel 13 +// +#define UDMA_CH13_RESERVED0 0x0000000D +#define UDMA_CH13_RESERVED1 0x0001000D +#define UDMA_CH13_RESERVED2 0x0002000D +#define UDMA_CH13_RESERVED3 0x0003000D +#define UDMA_CH13_RESERVED4 0x0004000D + +// +// Channel 14 +// +#define UDMA_CH14_ADC0 0x0000000E +#define UDMA_CH14_TIMER2A 0x0001000E +#define UDMA_CH14_RESERVED2 0x0002000E +#define UDMA_CH14_RESERVED3 0x0003000E +#define UDMA_CH14_RESERVED4 0x0004000E + +// +// Channel 15 +// +#define UDMA_CH15_ADC1 0x0000000F +#define UDMA_CH15_TIMER2B 0x0001000F +#define UDMA_CH15_RESERVED2 0x0002000F +#define UDMA_CH15_RESERVED3 0x0003000F +#define UDMA_CH15_RESERVED4 0x0004000F + +// +// Channel 16 +// +#define UDMA_CH16_ADC2 0x00000010 +#define UDMA_CH16_RESERVED1 0x00010010 +#define UDMA_CH16_RESERVED2 0x00020010 +#define UDMA_CH16_RESERVED3 0x00030010 +#define UDMA_CH16_RESERVED4 0x00040010 + +// +// Channel 17 +// +#define UDMA_CH17_ADC3 0x00000011 +#define UDMA_CH17_RESERVED1 0x00010011 +#define UDMA_CH17_RESERVED2 0x00020011 +#define UDMA_CH17_RESERVED3 0x00030011 +#define UDMA_CH17_RESERVED4 0x00040011 + +// +// Channel 18 +// +#define UDMA_CH18_TIMER0A 0x00000012 +#define UDMA_CH18_TIMER1A 0x00010012 +#define UDMA_CH18_RESERVED2 0x00020012 +#define UDMA_CH18_RESERVED3 0x00030012 +#define UDMA_CH18_RESERVED4 0x00040012 + +// +// Channel 19 +// +#define UDMA_CH19_TIMER0B 0x00000013 +#define UDMA_CH19_TIMER1B 0x00010013 +#define UDMA_CH19_RESERVED2 0x00020013 +#define UDMA_CH19_RESERVED3 0x00030013 +#define UDMA_CH19_RESERVED4 0x00040013 + +// +// Channel 20 +// +#define UDMA_CH20_TIMER1A 0x00000014 +#define UDMA_CH20_RESERVED1 0x00010014 +#define UDMA_CH20_RESERVED2 0x00020014 +#define UDMA_CH20_RESERVED3 0x00030014 +#define UDMA_CH20_RESERVED4 0x00040014 + +// +// Channel 21 +// +#define UDMA_CH21_TIMER1B 0x00000015 +#define UDMA_CH21_RESERVED1 0x00010015 +#define UDMA_CH21_RESERVED2 0x00020015 +#define UDMA_CH21_RESERVED3 0x00030015 +#define UDMA_CH21_RESERVED4 0x00040015 + +// +// Channel 22 +// +#define UDMA_CH22_UART1RX 0x00000016 +#define UDMA_CH22_RESERVED1 0x00010016 +#define UDMA_CH22_RESERVED2 0x00020016 +#define UDMA_CH22_RESERVED3 0x00030016 +#define UDMA_CH22_RESERVED4 0x00040016 + +// +// Channel 23 +// +#define UDMA_CH23_UART1TX 0x00000017 +#define UDMA_CH23_RESERVED1 0x00010017 +#define UDMA_CH23_RESERVED2 0x00020017 +#define UDMA_CH23_RESERVED3 0x00030017 +#define UDMA_CH23_RESERVED4 0x00040017 + +// +// Channel 24 +// +#define UDMA_CH24_SSI1RX 0x00000018 +#define UDMA_CH24_ADC4 0x00010018 +#define UDMA_CH24_RESERVED2 0x00020018 +#define UDMA_CH24_RESERVED3 0x00030018 +#define UDMA_CH24_RESERVED4 0x00040018 + +// +// Channel 25 +// +#define UDMA_CH25_SSI1TX 0x00000019 +#define UDMA_CH25_ADC5 0x00010019 +#define UDMA_CH25_RESERVED2 0x00020019 +#define UDMA_CH25_RESERVED3 0x00030019 +#define UDMA_CH25_RESERVED4 0x00040019 + +// +// Channel 26 +// +#define UDMA_CH26_RESERVED0 0x0000001A +#define UDMA_CH26_ADC6 0x0001001A +#define UDMA_CH26_RESERVED2 0x0002001A +#define UDMA_CH26_RESERVED3 0x0003001A +#define UDMA_CH26_RESERVED4 0x0004001A + +// +// Channel 27 +// +#define UDMA_CH27_RESERVED0 0x0000001B +#define UDMA_CH27_ADC7 0x0001001B +#define UDMA_CH27_RESERVED2 0x0002001B +#define UDMA_CH27_RESERVED3 0x0003001B +#define UDMA_CH27_RESERVED4 0x0004001B + +// +// Channel 28 +// +#define UDMA_CH28_RESERVED0 0x0000001C +#define UDMA_CH28_RESERVED1 0x0001001C +#define UDMA_CH28_RESERVED2 0x0002001C +#define UDMA_CH28_RESERVED3 0x0003001C +#define UDMA_CH28_RESERVED4 0x0004001C + +// +// Channel 29 +// +#define UDMA_CH29_RESERVED0 0x0000001D +#define UDMA_CH29_RESERVED1 0x0001001D +#define UDMA_CH29_RESERVED2 0x0002001D +#define UDMA_CH29_RESERVED3 0x0003001D +#define UDMA_CH29_RFCORET2TRG1 0x0004001D + +// +// Channel 30 +// +#define UDMA_CH30_SW 0x0000001E +#define UDMA_CH30_RESERVED1 0x0001001E +#define UDMA_CH30_RESERVED2 0x0002001E +#define UDMA_CH30_RESERVED3 0x0003001E +#define UDMA_CH30_RFCORET2TRG2 0x0004001E + +// +// Channel 31 +// +#define UDMA_CH31_RESERVED0 0x0000001F +#define UDMA_CH31_RESERVED1 0x0001001F +#define UDMA_CH31_RESERVED2 0x0002001F +#define UDMA_CH31_RESERVED3 0x0003001F +#define UDMA_CH31_RESERVED4 0x0004001F + +// Enumerations used for channel ctrl +#define UDMA_CHCTL_DSTINC_8 0x00000000 // Byte +#define UDMA_CHCTL_DSTINC_16 0x40000000 // Half-word +#define UDMA_CHCTL_DSTINC_32 0x80000000 // Word + +#define UDMA_CHCTL_DSTSIZE_8 0x00000000 // Byte +#define UDMA_CHCTL_DSTSIZE_16 0x10000000 // Half-word +#define UDMA_CHCTL_DSTSIZE_32 0x20000000 // Word + +#define UDMA_CHCTL_SRCINC_8 0x00000000 // Byte +#define UDMA_CHCTL_SRCINC_16 0x04000000 // Half-word +#define UDMA_CHCTL_SRCINC_32 0x08000000 // Word + +#define UDMA_CHCTL_SRCSIZE_8 0x00000000 // Byte +#define UDMA_CHCTL_SRCSIZE_16 0x01000000 // Half-word +#define UDMA_CHCTL_SRCSIZE_32 0x02000000 // Word + +#define UDMA_CHCTL_ARBSIZE_1 0x00000000 // 1 Transfer +#define UDMA_CHCTL_ARBSIZE_2 0x00004000 // 2 Transfers +#define UDMA_CHCTL_ARBSIZE_4 0x00008000 // 4 Transfers +#define UDMA_CHCTL_ARBSIZE_8 0x0000C000 // 8 Transfers +#define UDMA_CHCTL_ARBSIZE_16 0x00010000 // 16 Transfers +#define UDMA_CHCTL_ARBSIZE_32 0x00014000 // 32 Transfers +#define UDMA_CHCTL_ARBSIZE_64 0x00018000 // 64 Transfers +#define UDMA_CHCTL_ARBSIZE_128 0x0001C000 // 128 Transfers +#define UDMA_CHCTL_ARBSIZE_256 0x00020000 // 256 Transfers +#define UDMA_CHCTL_ARBSIZE_512 0x00024000 // 512 Transfers +#define UDMA_CHCTL_ARBSIZE_1024 0x00028000 // 1024 Transfers + +#define UDMA_CHCTL_XFERMODE_STOP \ + 0x00000000 // Stop +#define UDMA_CHCTL_XFERMODE_BASIC \ + 0x00000001 // Basic +#define UDMA_CHCTL_XFERMODE_AUTO \ + 0x00000002 // Auto-Request +#define UDMA_CHCTL_XFERMODE_PINGPONG \ + 0x00000003 // Ping-Pong +#define UDMA_CHCTL_XFERMODE_MEM_SG \ + 0x00000004 // Memory Scatter-Gather +#define UDMA_CHCTL_XFERMODE_MEM_SGA \ + 0x00000005 // Alternate Memory Scatter-Gather +#define UDMA_CHCTL_XFERMODE_PER_SG \ + 0x00000006 // Peripheral Scatter-Gather +#define UDMA_CHCTL_XFERMODE_PER_SGA \ + 0x00000007 // Alternate Peripheral + // Scatter-Gather + +//***************************************************************************** +// +// API Function prototypes +// +//***************************************************************************** +extern void uDMAEnable(void); +extern void uDMADisable(void); +extern uint32_t uDMAErrorStatusGet(void); +extern void uDMAErrorStatusClear(void); +extern void uDMAChannelEnable(uint32_t ui32ChannelNum); +extern void uDMAChannelDisable(uint32_t ui32ChannelNum); +extern bool uDMAChannelIsEnabled(uint32_t ui32ChannelNum); +extern void uDMAControlBaseSet(void *pControlTable); +extern void *uDMAControlBaseGet(void); +extern void *uDMAControlAlternateBaseGet(void); +extern void uDMAChannelRequest(uint32_t ui32ChannelNum); +extern void uDMAChannelAttributeEnable(uint32_t ui32ChannelNum, + uint32_t ui32Attr); +extern void uDMAChannelAttributeDisable(uint32_t ui32ChannelNum, + uint32_t ui32Attr); +extern uint32_t uDMAChannelAttributeGet(uint32_t ui32ChannelNum); +extern void uDMAChannelControlSet(uint32_t ui32ChannelStructIndex, + uint32_t ui32Control); +extern void uDMAChannelTransferSet(uint32_t ui32ChannelStructIndex, + uint32_t ui32Mode, void *pvSrcAddr, + void *pvDstAddr, + uint32_t ui32TransferSize); +extern void uDMAChannelScatterGatherSet(uint32_t ui32ChannelNum, + uint32_t ui32TaskCount, +void *pvTaskList, + uint32_t ui32IsPeriphSG); +extern uint32_t uDMAChannelSizeGet(uint32_t ui32ChannelStructIndex); +extern uint32_t uDMAChannelModeGet(uint32_t ui32ChannelStructIndex); +extern void uDMAIntRegister(uint32_t ui32IntChannel, + void (*pfnHandler)(void)); +extern void uDMAIntUnregister(uint32_t ui32IntChannel); +extern uint32_t uDMAIntStatus(void); +extern void uDMAIntClear(uint32_t ui32ChanMask); +extern void uDMAChannelAssign(uint32_t ui32Mapping); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __UDMA_H__ diff --git a/bsp/boards/mimsy2-cc2538/source/watchdog.c b/bsp/boards/mimsy2-cc2538/source/watchdog.c new file mode 100644 index 0000000000..e349b6abaa --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/watchdog.c @@ -0,0 +1,139 @@ +/****************************************************************************** +* Filename: watchdog.c +* Revised: $Date: 2013-04-04 15:31:10 +0200 (Thu, 04 Apr 2013) $ +* Revision: $Revision: 9634 $ +* +* Description: Driver for the Watchdog Timer Module. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup watchdog_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include "debug.h" +#include "interrupt.h" +#include "watchdog.h" + +//***************************************************************************** +// +//! Enables the watchdog timer +//! +//! \param ui32Interval is the timer interval setting. +//! +//! This function sets the timer interval and enables the watchdog timer. +//! A timeout causes a chip reset. +//! +//! The \e ui32Interval argument must be only one of the following values: +//! \b WATCHDOG_INTERVAL_32768, \b WATCHDOG_INTERVAL_8192, +//! \b WATCHDOG_INTERVAL_512, \b WATCHDOG_INTERVAL_64. +//! +//! \sa WatchdogDisable() +//! +//! \return None +// +//***************************************************************************** +void +WatchdogEnable(uint32_t ui32Interval) +{ + uint32_t ui32Regval; + // + // Check the arguments. + // + ASSERT(ui32Interval == WATCHDOG_INTERVAL_32768 || + ui32Interval == WATCHDOG_INTERVAL_8192 || + ui32Interval == WATCHDOG_INTERVAL_512 || + ui32Interval == WATCHDOG_INTERVAL_64); + + // Disable Timer to set interval + HWREG(SMWDTHROSC_WDCTL) &= ~SMWDTHROSC_WDCTL_EN; + ui32Regval = HWREG(SMWDTHROSC_WDCTL); + ui32Regval &= ~SMWDTHROSC_WDCTL_INT_M; + ui32Regval |= ui32Interval; + HWREG(SMWDTHROSC_WDCTL) = ui32Regval; + + // + // Enable the watchdog timer module. + // + ui32Regval = HWREG(SMWDTHROSC_WDCTL); + ui32Regval &= ~0x4; + ui32Regval |= SMWDTHROSC_WDCTL_EN; + HWREG(SMWDTHROSC_WDCTL) = ui32Regval; +} + +//***************************************************************************** +// +//! Clear watch dog timer +//! +//! This function clears the watch dog timer. +//! Timer must be enabled for the clear operation to take effect. +//! +//! \return None +// +//***************************************************************************** +void +WatchdogClear(void) +{ + uint32_t ui32Reg1; + uint32_t ui32Reg2; + + // + // Write 0xA followed by 0x5 to CLR field + // (0x5 also clears in timer mode) + // + ui32Reg1 = HWREG(SMWDTHROSC_WDCTL); + ui32Reg1 &= ~SMWDTHROSC_WDCTL_CLR_M; + ui32Reg2 = ui32Reg1 | (0x5 << SMWDTHROSC_WDCTL_CLR_S); + ui32Reg1 |= 0xa << SMWDTHROSC_WDCTL_CLR_S; + + // + // The following two writes must happen within 0.5 cycle of WDT clock! + // for clear to actually happen. + // Note: might need to "safe guard" this zone by disabling interrupts. + // + HWREG(SMWDTHROSC_WDCTL) = ui32Reg1; + HWREG(SMWDTHROSC_WDCTL) = ui32Reg2; +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/source/watchdog.h b/bsp/boards/mimsy2-cc2538/source/watchdog.h new file mode 100644 index 0000000000..dea77a614f --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/source/watchdog.h @@ -0,0 +1,84 @@ +/****************************************************************************** +* Filename: watchdog.h +* Revised: $Date: 2013-04-04 15:31:10 +0200 (Thu, 04 Apr 2013) $ +* Revision: $Revision: 9634 $ +* +* Description: Prototypes for the Watchdog Timer API. +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __WATCHDOG_H__ +#define __WATCHDOG_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +//***************************************************************************** +// +// The following are values that can be passed to the WatchdogEnable() +// +//***************************************************************************** +#define WATCHDOG_INTERVAL_32768 0x00000000 // Timer select: Twdt x 32768 +#define WATCHDOG_INTERVAL_8192 0x00000001 // Timer select: Twdt x 8192 +#define WATCHDOG_INTERVAL_512 0x00000002 // Timer select: Twdt x 512 +#define WATCHDOG_INTERVAL_64 0x00000003 // Timer select: Twdt x 64 + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void WatchdogEnable(uint32_t ui32Interval); +extern void WatchdogClear(void); + + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __WATCHDOG_H__ diff --git a/bsp/boards/mimsy2-cc2538/start_manager.c b/bsp/boards/mimsy2-cc2538/start_manager.c new file mode 100644 index 0000000000..67a8a95f24 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/start_manager.c @@ -0,0 +1,105 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/******************************************************************************* + * + * $Id:$ + * + ******************************************************************************/ +/** + * @defgroup Start_Manager start_manager + * @brief Motion Library - Start Manager + * Start Manager + * + * @{ + * @file start_manager.c + * @brief This handles all the callbacks when inv_start_mpl() is called. + */ + + +#include +#include "log.h" +#include "start_manager.h" + +typedef inv_error_t (*inv_start_cb_func)(); +struct inv_start_cb_t { + int num_cb; + inv_start_cb_func start_cb[INV_MAX_START_CB]; +}; + +static struct inv_start_cb_t inv_start_cb; + +/** Initilize the start manager. Typically called by inv_start_mpl(); +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_init_start_manager(void) +{ + memset(&inv_start_cb, 0, sizeof(inv_start_cb)); + return INV_SUCCESS; +} + +/** Removes a callback from start notification +* @param[in] start_cb function to remove from start notification +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_unregister_mpl_start_notification(inv_error_t (*start_cb)(void)) +{ + int kk; + + for (kk=0; kk= INV_MAX_START_CB) + return INV_ERROR_INVALID_PARAMETER; + + inv_start_cb.start_cb[inv_start_cb.num_cb] = start_cb; + inv_start_cb.num_cb++; + return INV_SUCCESS; +} + +/** Callback all the functions that want to be notified when inv_start_mpl() was +* called. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_execute_mpl_start_notification(void) +{ + inv_error_t result,first_error; + int kk; + + first_error = INV_SUCCESS; + + for (kk = 0; kk < inv_start_cb.num_cb; ++kk) { + result = inv_start_cb.start_cb[kk](); + if (result && (first_error == INV_SUCCESS)) { + first_error = result; + } + } + return first_error; +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/start_manager.h b/bsp/boards/mimsy2-cc2538/start_manager.h new file mode 100644 index 0000000000..ecb1ab9574 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/start_manager.h @@ -0,0 +1,27 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#ifndef INV_START_MANAGER_H__ +#define INV_START_MANAGER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mltypes.h" + +/** Max number of start callbacks we can handle. */ +#define INV_MAX_START_CB 20 + +inv_error_t inv_init_start_manager(void); +inv_error_t inv_register_mpl_start_notification(inv_error_t (*start_cb)(void)); +inv_error_t inv_execute_mpl_start_notification(void); +inv_error_t inv_unregister_mpl_start_notification(inv_error_t (*start_cb)(void)); + +#ifdef __cplusplus +} +#endif +#endif // INV_START_MANAGER_H__ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/startup_gcc.c b/bsp/boards/mimsy2-cc2538/startup_gcc.c new file mode 100644 index 0000000000..1fe185f942 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/startup_gcc.c @@ -0,0 +1,365 @@ +//***************************************************************************** +//! @file startup_gcc.c +//! @brief Startup code for CC2538 for use with GCC. +//! +//! Revised $Date: 2013-04-11 20:13:13 +0200 (Thu, 11 Apr 2013) $ +//! Revision $Revision: 9714 $ +// +// Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//****************************************************************************/ + +#include + +#include + +#define FLASH_START_ADDR 0x00200000 +#define BOOTLOADER_BACKDOOR_ENABLE 0xF6FFFFFF // ENABLED: PORT A, PIN 6, LOW +#define BOOTLOADER_BACKDOOR_DISABLE 0xEFFFFFFF // DISABLED +#define SYS_CTRL_EMUOVR 0x400D20B4 +#define SYS_CTRL_I_MAP 0x400D2098 + +//***************************************************************************** +// +// Macro for hardware access, both direct and via the bit-band region. +// +//***************************************************************************** +#ifndef HWREG +#define HWREG(x) \ + (*((volatile unsigned long *)(x))) +#endif + +extern int main (void); + +void ResetISR(void); +void NmiSR(void); +void FaultISR(void); +void IntDefaultHandler(void); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +static uint32_t pui32Stack[512]; + +//***************************************************************************** +// +// Customer Configuration Area in Lock Page +// Holds Application entry point (bytes 2012 - 2015) and +// Image Valid (bytes 2008 - 2011) and +// Bootloader backdoor (byte 2007) and +// Reserved (byte 2006 - 2004) +// +//***************************************************************************** +typedef struct +{ + uint32_t ui32BootldrCfg; + uint32_t ui32ImageValid; + uint32_t ui32ImageVectorAddr; +} +lockPageCCA_t; + +__attribute__ ((section(".flashcca"), used)) +const lockPageCCA_t __cca = +{ + BOOTLOADER_BACKDOOR_ENABLE, // Bootloader backdoor enabled + 0, // Image valid bytes + FLASH_START_ADDR // Vector table located at flash start address +}; + +__attribute__ ((section(".vectors"), used)) +void (* const gVectors[])(void) = +{ + (void (*)(void))((uint32_t)pui32Stack + sizeof(pui32Stack)), // Stack pointer + ResetISR, // Reset handler + NmiSR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // 4 The MPU fault handler + IntDefaultHandler, // 5 The bus fault handler + IntDefaultHandler, // 6 The usage fault handler + 0, // 7 Reserved + 0, // 8 Reserved + 0, // 9 Reserved + 0, // 10 Reserved + IntDefaultHandler, // 11 SVCall handler + IntDefaultHandler, // 12 Debug monitor handler + 0, // 13 Reserved + IntDefaultHandler, // 14 The PendSV handler + IntDefaultHandler, // 15 The SysTick handler + IntDefaultHandler, // 16 GPIO Port A + IntDefaultHandler, // 17 GPIO Port B + IntDefaultHandler, // 18 GPIO Port C + IntDefaultHandler, // 19 GPIO Port D + 0, // 20 none + IntDefaultHandler, // 21 UART0 Rx and Tx + IntDefaultHandler, // 22 UART1 Rx and Tx + IntDefaultHandler, // 23 SSI0 Rx and Tx + IntDefaultHandler, // 24 I2C Master and Slave + 0, // 25 Reserved + 0, // 26 Reserved + 0, // 27 Reserved + 0, // 28 Reserved + 0, // 29 Reserved + IntDefaultHandler, // 30 ADC Sequence 0 + 0, // 31 Reserved + 0, // 32 Reserved + 0, // 33 Reserved + IntDefaultHandler, // 34 Watchdog timer, timer 0 + IntDefaultHandler, // 35 Timer 0 subtimer A + IntDefaultHandler, // 36 Timer 0 subtimer B + IntDefaultHandler, // 37 Timer 1 subtimer A + IntDefaultHandler, // 38 Timer 1 subtimer B + IntDefaultHandler, // 39 Timer 2 subtimer A + IntDefaultHandler, // 40 Timer 2 subtimer B + IntDefaultHandler, // 41 Analog Comparator 0 + IntDefaultHandler, // 42 RFCore Rx/Tx + IntDefaultHandler, // 43 RFCore Error + IntDefaultHandler, // 44 IcePick + IntDefaultHandler, // 45 FLASH Control + IntDefaultHandler, // 46 AES + IntDefaultHandler, // 47 PKA + IntDefaultHandler, // 48 Sleep Timer + IntDefaultHandler, // 49 MacTimer + IntDefaultHandler, // 50 SSI1 Rx and Tx + IntDefaultHandler, // 51 Timer 3 subtimer A + IntDefaultHandler, // 52 Timer 3 subtimer B + 0, // 53 Reserved + 0, // 54 Reserved + 0, // 55 Reserved + 0, // 56 Reserved + 0, // 57 Reserved + 0, // 58 Reserved + 0, // 59 Reserved + IntDefaultHandler, // 60 USB 2538 + 0, // 61 Reserved + IntDefaultHandler, // 62 uDMA + IntDefaultHandler, // 63 uDMA Error +#ifndef CC2538_USE_ALTERNATE_INTERRUPT_MAP + 0, // 64 64-155 are not in use + 0, // 65 + 0, // 66 + 0, // 67 + 0, // 68 + 0, // 69 + 0, // 70 + 0, // 71 + 0, // 72 + 0, // 73 + 0, // 74 + 0, // 75 + 0, // 76 + 0, // 77 + 0, // 78 + 0, // 79 + 0, // 80 + 0, // 81 + 0, // 82 + 0, // 83 + 0, // 84 + 0, // 85 + 0, // 86 + 0, // 87 + 0, // 88 + 0, // 89 + 0, // 90 + 0, // 91 + 0, // 92 + 0, // 93 + 0, // 94 + 0, // 95 + 0, // 96 + 0, // 97 + 0, // 98 + 0, // 99 + 0, // 100 + 0, // 101 + 0, // 102 + 0, // 103 + 0, // 104 + 0, // 105 + 0, // 106 + 0, // 107 + 0, // 108 + 0, // 109 + 0, // 110 + 0, // 111 + 0, // 112 + 0, // 113 + 0, // 114 + 0, // 115 + 0, // 116 + 0, // 117 + 0, // 118 + 0, // 119 + 0, // 120 + 0, // 121 + 0, // 122 + 0, // 123 + 0, // 124 + 0, // 125 + 0, // 126 + 0, // 127 + 0, // 128 + 0, // 129 + 0, // 130 + 0, // 131 + 0, // 132 + 0, // 133 + 0, // 134 + 0, // 135 + 0, // 136 + 0, // 137 + 0, // 138 + 0, // 139 + 0, // 140 + 0, // 141 + 0, // 142 + 0, // 143 + 0, // 144 + 0, // 145 + 0, // 146 + 0, // 147 + 0, // 148 + 0, // 149 + 0, // 150 + 0, // 151 + 0, // 152 + 0, // 153 + 0, // 154 + 0, // 155 + IntDefaultHandler, // 156 USB + IntDefaultHandler, // 157 RFCORE RX/TX + IntDefaultHandler, // 158 RFCORE Error + IntDefaultHandler, // 159 AES + IntDefaultHandler, // 160 PKA + IntDefaultHandler, // 161 SMTimer + IntDefaultHandler, // 162 MACTimer +#endif +}; + +//***************************************************************************** +// +// The following are constructs created by the linker, indicating where the +// the "data" and "bss" segments reside in memory. The initializers for the +// for the "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern uint32_t _etext; +extern uint32_t _data; +extern uint32_t _edata; +extern uint32_t _bss; +extern uint32_t _ebss; + +// +// And here are the weak interrupt handlers. +// +void +NmiSR (void) +{ + ResetISR(); + while(1) + { + } +} + + +void +FaultISR (void) +{ + while(1) + { + } +} + + +void +IntDefaultHandler (void) +{ + while(1) + { + } +} + +void +ResetISR (void) +{ + uint32_t *pui32Src, *pui32Dest; + + // + // Workaround for PM debug issue + // + HWREG(SYS_CTRL_EMUOVR) = 0xFF; + + + /* Workaround for J-Link debug issue */ + HWREG(NVIC_VTABLE) = (uint32_t)gVectors; + + // + // Copy the data segment initializers from flash to SRAM. + // + pui32Src = &_etext; + for(pui32Dest = &_data; pui32Dest < &_edata; ) + { + *pui32Dest++ = *pui32Src++; + } + + // + // Zero fill the bss segment. + // + __asm(" ldr r0, =_bss\n" + " ldr r1, =_ebss\n" + " mov r2, #0\n" + " .thumb_func\n" + "zero_loop:\n" + " cmp r0, r1\n" + " it lt\n" + " strlt r2, [r0], #4\n" + " blt zero_loop"); + +#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP + // + // Enable alternate interrupt mapping + // + HWREG(SYS_CTRL_I_MAP) |= 1; +#endif + // + // Call the application's entry point. + // + main(); + + // + // End here if return from main() + // + while(1) + { + } +} + diff --git a/bsp/boards/mimsy2-cc2538/startup_iar.c b/bsp/boards/mimsy2-cc2538/startup_iar.c new file mode 100644 index 0000000000..cb85e55621 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/startup_iar.c @@ -0,0 +1,459 @@ +//***************************************************************************** +//! @file startup_iar.c +//! @brief Startup code for CC2538 for use with IAR EWARM. +//! +//! Revised $Date: 2013-04-29 14:48:18 +0200 (Mon, 29 Apr 2013) $ +//! Revision $Revision: 9929 $ +// +// Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//****************************************************************************/ + +#include + +#define FLASH_START_ADDR 0x00200000 +#define BOOTLOADER_BACKDOOR_DISABLE 0xEFFFFFFF +#define SYS_CTRL_EMUOVR 0x400D20B4 +#define SYS_CTRL_I_MAP 0x400D2098 + + +//***************************************************************************** +// +// Check if compiler is IAR +// +//***************************************************************************** +#if !(defined(__IAR_SYSTEMS_ICC__)) +#error "startup_iar.c: Unsupported compiler!" +#endif + + +//***************************************************************************** +// +// Macro for hardware access, both direct and via the bit-band region. +// +//***************************************************************************** +#ifndef HWREG +#define HWREG(x) \ + (*((volatile uint32_t *)(x))) +#endif + + +//***************************************************************************** +// +// IAR: Enable the IAR extensions for this source file. +// +//***************************************************************************** +#pragma language=extended + + +//***************************************************************************** +// +// IAR: The entry point for the application startup code. +// +//***************************************************************************** +extern void __iar_program_start(void); + + +//***************************************************************************** +// +// IAR: Get stack start (highest address) symbol from linker file. +// +//***************************************************************************** +extern const void* STACK_TOP; + +// It is required to place something in the CSTACK segment to get the stack +// check feature in IAR to work as expected +__root static void* dummy_stack @ ".stack"; + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +static void ResetISR(void); +static void NmiISR(void); +static void FaultISR(void); +static void IntDefaultHandler(void); + +// Handlers that can potentially be registered directly by application +extern void PendSVIntHandler(void); +extern void SysTickIntHandler(void); +extern void GPIOAIntHandler(void); +extern void GPIOBIntHandler(void); +extern void GPIOCIntHandler(void); +extern void GPIODIntHandler(void); +extern void UART0IntHandler(void); +extern void UART1IntHandler(void); +extern void SSI0IntHandler(void); +extern void SSI1IntHandler(void); +extern void I2CIntHandler(void); +extern void ADCIntHandler(void); +extern void WatchdogIntHandler(void); +extern void Timer0AIntHandler(void); +extern void Timer0BIntHandler(void); +extern void Timer1AIntHandler(void); +extern void Timer1BIntHandler(void); +extern void Timer2AIntHandler(void); +extern void Timer2BIntHandler(void); +extern void Timer3AIntHandler(void); +extern void Timer3BIntHandler(void); +extern void CompIntHandler(void); +extern void RFCoreTxIntHandler(void); +extern void RFCoreErrIntHandler(void); +extern void IcePickIntHandler(void); +extern void FlashIntHandler(void); +extern void AESIntHandler(void); +extern void PKAIntHandler(void); +extern void SleepModeIntHandler(void); +extern void MacTimerIntHandler(void); +extern void USBIntHandler(void); +extern void uDMAIntHandler(void); +extern void uDMAErrIntHandler(void); + +// Default interrupt handlers, these can be overwritten if defined elsewhere +#pragma weak PendSVIntHandler = IntDefaultHandler +#pragma weak SysTickIntHandler = IntDefaultHandler +#pragma weak GPIOAIntHandler = IntDefaultHandler +#pragma weak GPIOBIntHandler = IntDefaultHandler +#pragma weak GPIOCIntHandler = IntDefaultHandler +#pragma weak GPIODIntHandler = IntDefaultHandler +#pragma weak UART0IntHandler = IntDefaultHandler +#pragma weak UART1IntHandler = IntDefaultHandler +#pragma weak SSI0IntHandler = IntDefaultHandler +#pragma weak SSI1IntHandler = IntDefaultHandler +#pragma weak I2CIntHandler = IntDefaultHandler +#pragma weak ADCIntHandler = IntDefaultHandler +#pragma weak WatchdogIntHandler = IntDefaultHandler +#pragma weak Timer0AIntHandler = IntDefaultHandler +#pragma weak Timer0BIntHandler = IntDefaultHandler +#pragma weak Timer1AIntHandler = IntDefaultHandler +#pragma weak Timer1BIntHandler = IntDefaultHandler +#pragma weak Timer2AIntHandler = IntDefaultHandler +#pragma weak Timer2BIntHandler = IntDefaultHandler +#pragma weak Timer3AIntHandler = IntDefaultHandler +#pragma weak Timer3BIntHandler = IntDefaultHandler +#pragma weak CompIntHandler = IntDefaultHandler +#pragma weak RFCoreTxIntHandler = IntDefaultHandler +#pragma weak RFCoreErrIntHandler = IntDefaultHandler +#pragma weak IcePickIntHandler = IntDefaultHandler +#pragma weak FlashIntHandler = IntDefaultHandler +#pragma weak AESIntHandler = IntDefaultHandler +#pragma weak PKAIntHandler = IntDefaultHandler +#pragma weak SleepModeIntHandler = IntDefaultHandler +#pragma weak MacTimerIntHandler = IntDefaultHandler +#pragma weak USBIntHandler = IntDefaultHandler +#pragma weak uDMAIntHandler = IntDefaultHandler +#pragma weak uDMAErrIntHandler = IntDefaultHandler + + +//***************************************************************************** +// +// Customer Configuration Area in Lock Page +// Holds Image Vector table address (bytes 2013 - 2015) and +// Image Valid bytes (bytes 2008 -2011) +// +//***************************************************************************** +typedef struct +{ + uint32_t ui32BootldrCfg; + uint32_t ui32ImageValid; + uint32_t ui32ImageVectorAddr; +} +lockPageCCA_t; + +__root const lockPageCCA_t __cca @ ".flashcca" = +{ + BOOTLOADER_BACKDOOR_DISABLE, // Bootloader backdoor disabled + 0, // Image valid bytes + FLASH_START_ADDR // Vector table located at flash start address +}; + + +//***************************************************************************** +// +// The vector table. Note that the proper constructs must be placed on this to +// ensure that it ends up at physical address 0x200000 (start of the flash). +// +//***************************************************************************** +__root void (* const __vector_table[])(void) @ ".intvec" = +{ + (void (*)(void))&STACK_TOP, // 0 The initial stack pointer + ResetISR, // 1 The reset handler + NmiISR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // 4 The MPU fault handler + IntDefaultHandler, // 5 The bus fault handler + IntDefaultHandler, // 6 The usage fault handler + 0, // 7 Reserved + 0, // 8 Reserved + 0, // 9 Reserved + 0, // 10 Reserved + IntDefaultHandler, // 11 SVCall handler + IntDefaultHandler, // 12 Debug monitor handler + 0, // 13 Reserved + PendSVIntHandler, // 14 The PendSV handler + SysTickIntHandler, // 15 The SysTick handler + GPIOAIntHandler, // 16 GPIO Port A + GPIOBIntHandler, // 17 GPIO Port B + GPIOCIntHandler, // 18 GPIO Port C + GPIODIntHandler, // 19 GPIO Port D + 0, // 20 none + UART0IntHandler, // 21 UART0 Rx and Tx + UART1IntHandler, // 22 UART1 Rx and Tx + SSI0IntHandler, // 23 SSI0 Rx and Tx + I2CIntHandler, // 24 I2C Master and Slave + 0, // 25 Reserved + 0, // 26 Reserved + 0, // 27 Reserved + 0, // 28 Reserved + 0, // 29 Reserved + ADCIntHandler, // 30 ADC Sequence 0 + 0, // 31 Reserved + 0, // 32 Reserved + 0, // 33 Reserved + WatchdogIntHandler, // 34 Watchdog timer, timer 0 + Timer0AIntHandler, // 35 Timer 0 subtimer A + Timer0BIntHandler, // 36 Timer 0 subtimer B + Timer1AIntHandler, // 37 Timer 1 subtimer A + Timer1BIntHandler, // 38 Timer 1 subtimer B + Timer2AIntHandler, // 39 Timer 2 subtimer A + Timer2BIntHandler, // 40 Timer 2 subtimer B + CompIntHandler, // 41 Analog Comparator 0 + RFCoreTxIntHandler, // 42 RFCore Rx/Tx + RFCoreErrIntHandler, // 43 RFCore Error + IcePickIntHandler, // 44 IcePick + FlashIntHandler, // 45 FLASH Control + AESIntHandler, // 46 AES + PKAIntHandler, // 47 PKA + SleepModeIntHandler, // 48 Sleep Timer + MacTimerIntHandler, // 49 MacTimer + SSI1IntHandler, // 50 SSI1 Rx and Tx + Timer3AIntHandler, // 51 Timer 3 subtimer A + Timer3BIntHandler, // 52 Timer 3 subtimer B + 0, // 53 Reserved + 0, // 54 Reserved + 0, // 55 Reserved + 0, // 56 Reserved + 0, // 57 Reserved + 0, // 58 Reserved + 0, // 59 Reserved + USBIntHandler, // 60 USB 2538 + 0, // 61 Reserved + uDMAIntHandler, // 62 uDMA + uDMAErrIntHandler, // 63 uDMA Error +#ifndef CC2538_USE_ALTERNATE_INTERRUPT_MAP + 0, // 64 64-155 are not in use + 0, // 65 + 0, // 66 + 0, // 67 + 0, // 68 + 0, // 69 + 0, // 70 + 0, // 71 + 0, // 72 + 0, // 73 + 0, // 74 + 0, // 75 + 0, // 76 + 0, // 77 + 0, // 78 + 0, // 79 + 0, // 80 + 0, // 81 + 0, // 82 + 0, // 83 + 0, // 84 + 0, // 85 + 0, // 86 + 0, // 87 + 0, // 88 + 0, // 89 + 0, // 90 + 0, // 91 + 0, // 92 + 0, // 93 + 0, // 94 + 0, // 95 + 0, // 96 + 0, // 97 + 0, // 98 + 0, // 99 + 0, // 100 + 0, // 101 + 0, // 102 + 0, // 103 + 0, // 104 + 0, // 105 + 0, // 106 + 0, // 107 + 0, // 108 + 0, // 109 + 0, // 110 + 0, // 111 + 0, // 112 + 0, // 113 + 0, // 114 + 0, // 115 + 0, // 116 + 0, // 117 + 0, // 118 + 0, // 119 + 0, // 120 + 0, // 121 + 0, // 122 + 0, // 123 + 0, // 124 + 0, // 125 + 0, // 126 + 0, // 127 + 0, // 128 + 0, // 129 + 0, // 130 + 0, // 131 + 0, // 132 + 0, // 133 + 0, // 134 + 0, // 135 + 0, // 136 + 0, // 137 + 0, // 138 + 0, // 139 + 0, // 140 + 0, // 141 + 0, // 142 + 0, // 143 + 0, // 144 + 0, // 145 + 0, // 146 + 0, // 147 + 0, // 148 + 0, // 149 + 0, // 150 + 0, // 151 + 0, // 152 + 0, // 153 + 0, // 154 + 0, // 155 + USBIntHandler, // 156 USB + RFCoreTxIntHandler, // 157 RFCORE RX/TX + RFCoreErrIntHandler, // 158 RFCORE Error + AESIntHandler, // 159 AES + PKAIntHandler, // 160 PKA + SleepModeIntHandler, // 161 SMTimer + MacTimerIntHandler, // 162 MACTimer +#endif +}; + +//***************************************************************************** +// +// This is the code that gets called when the processor is reset. +// +//***************************************************************************** +static void +ResetISR(void) +{ +#ifdef DEBUG + // + // Workaround for System Reset debug issue + // + uint32_t ui32Timeout = 2000000; + volatile uint32_t* pui32StopAtResetIsr = (uint32_t*)0x20003000; + while((*pui32StopAtResetIsr == 0xA5F01248) && (ui32Timeout--)); +#endif + +#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP + // + // Enable alternate interrupt mapping + // + HWREG(SYS_CTRL_I_MAP) |= 1; +#endif + + // + // Jump to IAR initialization routine + // + __iar_program_start(); +} + + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** +static void +NmiISR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a fault +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +FaultISR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +IntDefaultHandler(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} diff --git a/bsp/boards/mimsy2-cc2538/stdint_invensense.h b/bsp/boards/mimsy2-cc2538/stdint_invensense.h new file mode 100644 index 0000000000..ea39b21511 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/stdint_invensense.h @@ -0,0 +1,44 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +#ifndef STDINT_INVENSENSE_H +#define STDINT_INVENSENSE_H + +#ifndef WIN32 + +#if defined __KERNEL__ +#include +#elif defined EMPL +#include +#include +#else +#include +#endif + +#else + +#include + +typedef signed char int8_t; +typedef short int16_t; +typedef long int32_t; +typedef long long int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +typedef unsigned long long uint64_t; + +typedef int int_fast8_t; +typedef int int_fast16_t; +typedef long int_fast32_t; + +typedef unsigned int uint_fast8_t; +typedef unsigned int uint_fast16_t; +typedef unsigned long uint_fast32_t; + +#endif + +#endif // STDINT_INVENSENSE_H \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/storage_manager.c b/bsp/boards/mimsy2-cc2538/storage_manager.c new file mode 100644 index 0000000000..3528731a50 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/storage_manager.c @@ -0,0 +1,204 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ + +/** + * @defgroup Storage_Manager storage_manager + * @brief Motion Library - Stores Data for functions. + * + * + * @{ + * @file storage_manager.c + * @brief Load and Store Manager. + */ + +#include + +#include "storage_manager.h" +#include "log.h" +#include "ml_math_func.h" +#include "mlmath.h" + +/* Must be changed if the format of storage changes */ +#define DEFAULT_KEY 29681 + +typedef inv_error_t (*load_func_t)(const unsigned char *data); +typedef inv_error_t (*save_func_t)(unsigned char *data); +/** Max number of entites that can be stored */ +#define NUM_STORAGE_BOXES 20 + +struct data_header_t { + long size; + uint32_t checksum; + unsigned int key; +}; + +struct data_storage_t { + int num; /**< Number of differnt save entities */ + size_t total_size; /**< Size in bytes to store non volatile data */ + load_func_t load[NUM_STORAGE_BOXES]; /**< Callback to load data */ + save_func_t save[NUM_STORAGE_BOXES]; /**< Callback to save data */ + struct data_header_t hd[NUM_STORAGE_BOXES]; /**< Header info for each entity */ +}; +static struct data_storage_t ds; + +/** Should be called once before using any of the storage methods. Typically +* called first by inv_init_mpl().*/ +void inv_init_storage_manager() +{ + memset(&ds, 0, sizeof(ds)); + ds.total_size = sizeof(struct data_header_t); +} + +/** Used to register your mechanism to load and store non-volative data. This should typical be +* called during the enable function for your feature. +* @param[in] load_func function pointer you will use to receive data that was stored for you. +* @param[in] save_func function pointer you will use to save any data you want saved to +* non-volatile memory between runs. +* @param[in] size The size in bytes of the amount of data you want loaded and saved. +* @param[in] key The key associated with your data type should be unique across MPL. +* The key should change when your type of data for storage changes. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_register_load_store(inv_error_t (*load_func)(const unsigned char *data), + inv_error_t (*save_func)(unsigned char *data), size_t size, unsigned int key) +{ + int kk; + // Check if this has been registered already + for (kk=0; kk= NUM_STORAGE_BOXES) { + return INV_ERROR_INVALID_PARAMETER; + } + // Add to list + ds.hd[ds.num].key = key; + ds.hd[ds.num].size = size; + ds.load[ds.num] = load_func; + ds.save[ds.num] = save_func; + ds.total_size += size + sizeof(struct data_header_t); + ds.num++; + + return INV_SUCCESS; +} + +/** Returns the memory size needed to perform a store +* @param[out] size Size in bytes of memory needed to store. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_get_mpl_state_size(size_t *size) +{ + *size = ds.total_size; + return INV_SUCCESS; +} + +/** @internal + * Finds key in ds.hd[] array and returns location + * @return location where key exists in array, -1 if not found. + */ +static int inv_find_entry(unsigned int key) +{ + int kk; + for (kk=0; kkkey != DEFAULT_KEY) + return INV_ERROR_CALIBRATION_LOAD; // Key changed or data corruption + len = MIN(hd->size, len); + len = hd->size; + len -= sizeof(struct data_header_t); + data += sizeof(struct data_header_t); + checksum = inv_checksum(data, len); + if (checksum != hd->checksum) + return INV_ERROR_CALIBRATION_LOAD; // Data corruption + + while (len > (long)sizeof(struct data_header_t)) { + hd = (struct data_header_t *)data; + entry = inv_find_entry(hd->key); + data += sizeof(struct data_header_t); + len -= sizeof(struct data_header_t); + if (entry >= 0 && len >= hd->size) { + if (hd->size == ds.hd[entry].size) { + checksum = inv_checksum(data, hd->size); + if (checksum == hd->checksum) { + ds.load[entry](data); + } else { + return INV_ERROR_CALIBRATION_LOAD; + } + } + } + len -= hd->size; + if (len >= 0) + data = data + hd->size; + } + + return INV_SUCCESS; +} + +/** This function fills up a block of memory to be stored in non-volatile memory. +* @param[out] data Place to store data, size of sz, must be at least size +* returned by inv_get_mpl_state_size() +* @param[in] sz Size of data. +* @return Returns INV_SUCCESS if successful or an error code if not. +*/ +inv_error_t inv_save_mpl_states(unsigned char *data, size_t sz) +{ + unsigned char *cur; + int kk; + struct data_header_t *hd; + + if (sz >= ds.total_size) { + cur = data + sizeof(struct data_header_t); + for (kk = 0; kk < ds.num; ++kk) { + hd = (struct data_header_t *)cur; + cur += sizeof(struct data_header_t); + ds.save[kk](cur); + hd->checksum = inv_checksum(cur, ds.hd[kk].size); + hd->size = ds.hd[kk].size; + hd->key = ds.hd[kk].key; + cur += ds.hd[kk].size; + } + } else { + return INV_ERROR_CALIBRATION_LOAD; + } + + hd = (struct data_header_t *)data; + hd->checksum = inv_checksum(data + sizeof(struct data_header_t), + ds.total_size - sizeof(struct data_header_t)); + hd->key = DEFAULT_KEY; + hd->size = ds.total_size; + + return INV_SUCCESS; +} + +/** + * @} + */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/storage_manager.h b/bsp/boards/mimsy2-cc2538/storage_manager.h new file mode 100644 index 0000000000..e3dfe52dba --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/storage_manager.h @@ -0,0 +1,32 @@ +/* + $License: + Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + See included License.txt for License information. + $ + */ +#include "mltypes.h" +#include "stdlib.h" + + +#ifndef INV_STORAGE_MANAGER_H__ +#define INV_STORAGE_MANAGER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +inv_error_t inv_register_load_store( + inv_error_t (*load_func)(const unsigned char *data), + inv_error_t (*save_func)(unsigned char *data), + size_t size, unsigned int key); +void inv_init_storage_manager(void); + +inv_error_t inv_get_mpl_state_size(size_t *size); +inv_error_t inv_load_mpl_states(const unsigned char *data, size_t len); +inv_error_t inv_save_mpl_states(unsigned char *data, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* INV_STORAGE_MANAGER_H__ */ \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/uart.c b/bsp/boards/mimsy2-cc2538/uart.c new file mode 100644 index 0000000000..d25f036a69 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/uart.c @@ -0,0 +1,162 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "uart" bsp module. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include "board.h" +#include "debugpins.h" +#include "uart.h" + +//=========================== defines ========================================= + +#define PIN_UART_RXD GPIO_PIN_0 // PA0 is UART RX +#define PIN_UART_TXD GPIO_PIN_1 // PA1 is UART TX + +//=========================== variables ======================================= + +typedef struct { + uart_tx_cbt txCb; + uart_rx_cbt rxCb; +} uart_vars_t; + +uart_vars_t uart_vars; + +//=========================== prototypes ====================================== + +static void uart_isr_private(void); + +//=========================== public ========================================== + +void uart_init() { + // reset local variables + memset(&uart_vars,0,sizeof(uart_vars_t)); + + // Disable UART function + UARTDisable(UART0_BASE); + + // Disable all UART module interrupts + UARTIntDisable(UART0_BASE, 0x1FFF); + + // Set IO clock as UART clock source + UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); + + // Map UART signals to the correct GPIO pins and configure them as + // hardware controlled. GPIO-A pin 0 and 1 + IOCPinConfigPeriphOutput(GPIO_A_BASE, PIN_UART_TXD, IOC_MUX_OUT_SEL_UART0_TXD); + GPIOPinTypeUARTOutput(GPIO_A_BASE, PIN_UART_TXD); + IOCPinConfigPeriphInput(GPIO_A_BASE, PIN_UART_RXD, IOC_UARTRXD_UART0); + GPIOPinTypeUARTInput(GPIO_A_BASE, PIN_UART_RXD); + + // Configure the UART for 115,200, 8-N-1 operation. + // This function uses SysCtrlClockGet() to get the system clock + // frequency. This could be also be a variable or hard coded value + // instead of a function call. + UARTConfigSetExpClk(UART0_BASE, SysCtrlIOClockGet(), 115200, + (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | + UART_CONFIG_PAR_NONE)); + + // Enable UART hardware + UARTEnable(UART0_BASE); + + // Disable FIFO as we only one 1byte buffer + UARTFIFODisable(UART0_BASE); + + // Raise interrupt at end of tx (not by fifo) + UARTTxIntModeSet(UART0_BASE, UART_TXINT_MODE_EOT); + + // Register isr in the nvic and enable isr at the nvic + UARTIntRegister(UART0_BASE, uart_isr_private); + + // Enable the UART0 interrupt + IntEnable(INT_UART0); +} + +void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb) { + uart_vars.txCb = txCb; + uart_vars.rxCb = rxCb; +} + +void uart_enableInterrupts(){ + UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_TX | UART_INT_RT); +} + +void uart_disableInterrupts(){ + UARTIntDisable(UART0_BASE, UART_INT_RX | UART_INT_TX | UART_INT_RT); +} + +void uart_clearRxInterrupts(){ + UARTIntClear(UART0_BASE, UART_INT_RX | UART_INT_RT); +} + +void uart_clearTxInterrupts(){ + UARTIntClear(UART0_BASE, UART_INT_TX); +} + +void uart_writeByte(uint8_t byteToWrite){ + UARTCharPut(UART0_BASE, byteToWrite); +} + +uint8_t uart_readByte(){ + int32_t i32Char; + i32Char = UARTCharGet(UART0_BASE); + return (uint8_t)(i32Char & 0xFF); +} + +//=========================== interrupt handlers ============================== + +static void uart_isr_private(void){ + uint32_t reg; + debugpins_isr_set(); + + // Read interrupt source + reg = UARTIntStatus(UART0_BASE, true); + + // Clear UART interrupt in the NVIC + IntPendClear(INT_UART0); + + // Process TX interrupt + if(reg & UART_INT_TX){ + uart_tx_isr(); + } + + // Process RX interrupt + if((reg & (UART_INT_RX)) || (reg & (UART_INT_RT))) { + uart_rx_isr(); + } + + debugpins_isr_clr(); +} + +kick_scheduler_t uart_tx_isr() { + uart_clearTxInterrupts(); // TODO: do not clear, but disable when done + if (uart_vars.txCb != NULL) { + uart_vars.txCb(); + } + return DO_NOT_KICK_SCHEDULER; +} + +kick_scheduler_t uart_rx_isr() { + uart_clearRxInterrupts(); // TODO: do not clear, but disable when done + if (uart_vars.rxCb != NULL) { + uart_vars.rxCb(); + } + return DO_NOT_KICK_SCHEDULER; +} diff --git a/bsp/boards/mimsy2-cc2538/uart_mimsy.c b/bsp/boards/mimsy2-cc2538/uart_mimsy.c new file mode 100644 index 0000000000..320d6fd86a --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/uart_mimsy.c @@ -0,0 +1,91 @@ +#include "uarthal.h" +#include "uartstdio.h" +#include "hw_memmap.h" +#include "hw_gpio.h" +#include "ioc.h" +#include "string.h" +#include "hw_ioc.h" +#include +#include "sys_ctrl.h" +#include "gpio.h" + +#define EXAMPLE_PIN_UART_RXD GPIO_PIN_1 +#define EXAMPLE_PIN_UART_TXD GPIO_PIN_2 +#define EXAMPLE_GPIO_BASE GPIO_A_BASE + + +void uartMimsyInit(){ + + char cThisChar; + + // + // Set the clocking to run directly from the external crystal/oscillator. + // (no ext 32k osc, no internal osc) + // + // SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ); + + + // + // Enable UART peripheral module + // + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_UART0); + + // + // Disable UART function + // + UARTDisable(UART0_BASE); + + // + // Disable all UART module interrupts + // + UARTIntDisable(UART0_BASE, 0x1FFF); + + // + // Set IO clock as UART clock source + // + UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); + + // + // Map UART signals to the correct GPIO pins and configure them as + // hardware controlled. + // + IOCPinConfigPeriphOutput(EXAMPLE_GPIO_BASE, EXAMPLE_PIN_UART_TXD, IOC_MUX_OUT_SEL_UART0_TXD); + GPIOPinTypeUARTOutput(EXAMPLE_GPIO_BASE, EXAMPLE_PIN_UART_TXD); + IOCPinConfigPeriphInput(EXAMPLE_GPIO_BASE, EXAMPLE_PIN_UART_RXD, IOC_UARTRXD_UART0); + GPIOPinTypeUARTInput(EXAMPLE_GPIO_BASE, EXAMPLE_PIN_UART_RXD); + + // + // Configure the UART for 115,200, 8-N-1 operation. + // This function uses SysCtrlClockGet() to get the system clock + // frequency. This could be also be a variable or hard coded value + // instead of a function call. + // + // UARTConfigSetExpClk(UART0_BASE, SysCtrlClockGet(), 115200, + // (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | + // UART_CONFIG_PAR_NONE)); + // UARTEnable(UART0_BASE); + UARTStdioInitExpClk(0,115200*2); //adjusted to account for clock difference caused by openwsn clock scheme + // + // Put a character to show start of example. This will display on the + // terminal. + // + + +} + +void mimsyPrintf(const char *pcString, ...){ + va_list vaArgP; + + // + // Start the varargs processing. + // + va_start(vaArgP, pcString); + + UARTvprintf(pcString, vaArgP); + + // + // We're finished with the varargs now. + // + va_end(vaArgP); + +} diff --git a/bsp/boards/mimsy2-cc2538/uart_mimsy.h b/bsp/boards/mimsy2-cc2538/uart_mimsy.h new file mode 100644 index 0000000000..572cb6076b --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/uart_mimsy.h @@ -0,0 +1,2 @@ +void uartMimsyInit(); +void mimsyPrintf(const char *pcString, ...); \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/uartstdio.c b/bsp/boards/mimsy2-cc2538/uartstdio.c new file mode 100644 index 0000000000..3279714bd3 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/uartstdio.c @@ -0,0 +1,1812 @@ +/****************************************************************************** +* Filename: uartstdio.c +* Revised: $Date: 2013-04-08 17:38:20 +0200 (Mon, 08 Apr 2013) $ +* Revision: $Revision: 9684 $ +* +* Description: Utility driver to provide simple UART console functions. +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#include +#include +#include +#include "hw_ints.h" +#include "hw_memmap.h" +#include "hw_types.h" +#include "hw_uart.h" +#include "debug.h" +#include "interrupt.h" +#include "rom.h" +#include "sys_ctrl.h" +#include "uarthal.h" +#include "uartstdio.h" + +//***************************************************************************** +// +//! \addtogroup uartstdio_api +//! @{ +// +//***************************************************************************** + + +//***************************************************************************** +// +// If buffered mode is defined, set aside RX and TX buffers and read/write +// pointers to control them. +// +//***************************************************************************** +#ifdef UART_BUFFERED + +//***************************************************************************** +// +// This global controls whether or not we are echoing characters back to the +// transmitter. By default, echo is enabled but if using this module as a +// convenient method of implementing a buffered serial interface over which +// you will be running an application protocol, you are likely to want to +// disable echo by calling UARTEchoSet(false). +// +//***************************************************************************** +static bool g_bDisableEcho; + +//***************************************************************************** +// +// Output ring buffer. Buffer is full if g_ui32UARTTxReadIndex is one ahead of +// g_ui32UARTTxWriteIndex. Buffer is empty if the two indices are the same. +// +//***************************************************************************** +static unsigned char g_pcUARTTxBuffer[UART_TX_BUFFER_SIZE]; +static volatile uint32_t g_ui32UARTTxWriteIndex = 0; +static volatile uint32_t g_ui32UARTTxReadIndex = 0; + +//***************************************************************************** +// +// Input ring buffer. Buffer is full if g_ui32UARTTxReadIndex is one ahead of +// g_ui32UARTTxWriteIndex. Buffer is empty if the two indices are the same. +// +//***************************************************************************** +static unsigned char g_pcUARTRxBuffer[UART_RX_BUFFER_SIZE]; +static volatile uint32_t g_ui32UARTRxWriteIndex = 0; +static volatile uint32_t g_ui32UARTRxReadIndex = 0; + +//***************************************************************************** +// +// Macros to determine number of free and used bytes in the transmit buffer. +// +//***************************************************************************** +#define TX_BUFFER_USED (GetBufferCount(&g_ui32UARTTxReadIndex, \ + &g_ui32UARTTxWriteIndex, \ + UART_TX_BUFFER_SIZE)) +#define TX_BUFFER_FREE (UART_TX_BUFFER_SIZE - TX_BUFFER_USED) +#define TX_BUFFER_EMPTY (IsBufferEmpty(&g_ui32UARTTxReadIndex, \ + &g_ui32UARTTxWriteIndex)) +#define TX_BUFFER_FULL (IsBufferFull(&g_ui32UARTTxReadIndex, \ + &g_ui32UARTTxWriteIndex, \ + UART_TX_BUFFER_SIZE)) +#define ADVANCE_TX_BUFFER_INDEX(Index) \ + (Index) = ((Index) + 1) % UART_TX_BUFFER_SIZE + +//***************************************************************************** +// +// Macros to determine number of free and used bytes in the receive buffer. +// +//***************************************************************************** +#define RX_BUFFER_USED (GetBufferCount(&g_ui32UARTRxReadIndex, \ + &g_ui32UARTRxWriteIndex, \ + UART_RX_BUFFER_SIZE)) +#define RX_BUFFER_FREE (UART_RX_BUFFER_SIZE - RX_BUFFER_USED) +#define RX_BUFFER_EMPTY (IsBufferEmpty(&g_ui32UARTRxReadIndex, \ + &g_ui32UARTRxWriteIndex)) +#define RX_BUFFER_FULL (IsBufferFull(&g_ui32UARTRxReadIndex, \ + &g_ui32UARTRxWriteIndex, \ + UART_RX_BUFFER_SIZE)) +#define ADVANCE_RX_BUFFER_INDEX(Index) \ + (Index) = ((Index) + 1) % UART_RX_BUFFER_SIZE +#endif + +//***************************************************************************** +// +// The base address of the chosen UART. +// +//***************************************************************************** +static uint32_t g_ui32Base = 0; + +//***************************************************************************** +// +// A mapping from an integer between 0 and 15 to its ASCII character +// equivalent. +// +//***************************************************************************** +static const char * const g_pcHex = "0123456789abcdef"; + +//***************************************************************************** +// +// The list of possible base addresses for the console UART. +// +//***************************************************************************** +static const uint32_t g_ui32UARTBase[2] = +{ + UART0_BASE, UART1_BASE +}; + +#ifdef UART_BUFFERED +//***************************************************************************** +// +// The list of possible interrupts for the console UART. +// +//***************************************************************************** +static const uint32_t g_ui32UARTInt[2] = +{ + INT_UART0, INT_UART1 +}; + +//***************************************************************************** +// +// The port number in use. +// +//***************************************************************************** +static uint32_t g_ui32PortNum; +#endif + +//***************************************************************************** +// +// The list of UART peripherals. +// +//***************************************************************************** +static const uint32_t g_ui32UARTPeriph[2] = +{ + SYS_CTRL_PERIPH_UART0, SYS_CTRL_PERIPH_UART1 +}; + +//***************************************************************************** +// +//! Determines whether the ring buffer whose pointers and size are provided +//! is full or not. +//! +//! \param pui32Read points to the read index for the buffer. +//! \param pui32Write points to the write index for the buffer. +//! \param ui32Size is the size of the buffer in bytes. +//! +//! This function is used to determine whether or not a given ring buffer is +//! full. The structure of the code is specifically to ensure that we do not +//! see warnings from the compiler related to the order of volatile accesses +//! being undefined. +//! +//! \return Returns \b true if the buffer is full or \b false otherwise. +// +//***************************************************************************** +#ifdef UART_BUFFERED +static bool +IsBufferFull(volatile uint32_t *pui32Read, + volatile uint32_t *pui32Write, uint32_t ui32Size) +{ + uint32_t ui32Write; + uint32_t ui32Read; + + ui32Write = *pui32Write; + ui32Read = *pui32Read; + + return((((ui32Write + 1) % ui32Size) == ui32Read) ? true : false); +} +#endif + +//***************************************************************************** +// +//! Determines whether the ring buffer whose pointers and size are provided +//! is empty or not. +//! +//! \param pui32Read points to the read index for the buffer. +//! \param pui32Write points to the write index for the buffer. +//! +//! This function is used to determine whether or not a given ring buffer is +//! empty. The structure of the code is specifically to ensure that we do not +//! see warnings from the compiler related to the order of volatile accesses +//! being undefined. +//! +//! \return Returns \b true if the buffer is empty or \b false otherwise. +// +//***************************************************************************** +#ifdef UART_BUFFERED +static bool +IsBufferEmpty(volatile uint32_t *pui32Read, + volatile uint32_t *pui32Write) +{ + uint32_t ui32Write; + uint32_t ui32Read; + + ui32Write = *pui32Write; + ui32Read = *pui32Read; + + return((ui32Write == ui32Read) ? true : false); +} +#endif + +//***************************************************************************** +// +//! Determines the number of bytes of data contained in a ring buffer. +//! +//! \param pui32Read points to the read index for the buffer. +//! \param pui32Write points to the write index for the buffer. +//! \param ui32Size is the size of the buffer in bytes. +//! +//! This function is used to determine how many bytes of data a given ring +//! buffer currently contains. The structure of the code is specifically to +//! ensure that we do not see warnings from the compiler related to the order +//! of volatile accesses being undefined. +//! +//! \return Returns the number of bytes of data currently in the buffer. +// +//***************************************************************************** +#ifdef UART_BUFFERED +static uint32_t +GetBufferCount(volatile uint32_t *pui32Read, + volatile uint32_t *pui32Write, uint32_t ui32Size) +{ + uint32_t ui32Write; + uint32_t ui32Read; + + ui32Write = *pui32Write; + ui32Read = *pui32Read; + + return((ui32Write >= ui32Read) ? (ui32Write - ui32Read) : + (ui32Size - (ui32Read - ui32Write))); +} +#endif + +//***************************************************************************** +// +// Take as many bytes from the transmit buffer as we have space for and move +// them into the UART transmit FIFO. +// +//***************************************************************************** +#ifdef UART_BUFFERED +static void +UARTPrimeTransmit(uint32_t ui32Base) +{ + // + // Do we have any data to transmit? + // + if(!TX_BUFFER_EMPTY) + { + // + // Disable the UART interrupt. If we don't do this there is a race + // condition which can cause the read index to be corrupted. + // + IntDisable(g_ui32UARTInt[g_ui32PortNum]); + + // + // Yes - take some characters out of the transmit buffer and feed + // them to the UART transmit FIFO. + // + while(UARTSpaceAvail(ui32Base) && !TX_BUFFER_EMPTY) + { + UARTCharPutNonBlocking(ui32Base, + g_pcUARTTxBuffer[g_ui32UARTTxReadIndex]); + ADVANCE_TX_BUFFER_INDEX(g_ui32UARTTxReadIndex); + } + + // + // Reenable the UART interrupt. + // + IntEnable(g_ui32UARTInt[g_ui32PortNum]); + } +} +#endif + +//***************************************************************************** +// +//! Configures the UART console. +//! +//! \param ui32PortNum is the number of UART port to use for the serial console +//! (0-1) +//! \param ui32Baud is the bit rate that the UART is to be configured to use. +//! \param ui32SrcClock is the frequency of the source clock for the UART module. +//! +//! This function will configure the specified serial port to be used as a +//! serial console. The serial parameters are set to the baud rate +//! specified by the \e ui32Baud parameter and use 8 bit, no parity, and 1 stop +//! bit. +//! +//! This function must be called prior to using any of the other UART console +//! functions: UARTprintf() or UARTgets(). This function assumes that the +//! caller has previously configured the relevant UART pins for operation as a +//! UART rather than as GPIOs. +//! +//! \return None. +// +//***************************************************************************** +void +UARTStdioConfig(uint32_t ui32PortNum, uint32_t ui32Baud, + uint32_t ui32SrcClock) +{ + // + // Check the arguments. + // + ASSERT((ui32PortNum == 0) || (ui32PortNum == 1)); + +#ifdef UART_BUFFERED + // + // In buffered mode, we only allow a single instance to be opened. + // + ASSERT(g_ui32Base == 0); +#endif + + // + // Check to make sure the UART peripheral is present. + // + if(!SysCtrlPeripheralPresent(g_ui32UARTPeriph[ui32PortNum])) + { + return; + } + + // + // Select the base address of the UART. + // + g_ui32Base = g_ui32UARTBase[ui32PortNum]; + + // + // Enable UART peripheral module + // + SysCtrlPeripheralEnable(g_ui32UARTPeriph[ui32PortNum]); + + // + // Disable UART function + // + UARTDisable(g_ui32Base); + + // + // Disable all UART module interrupts + // + UARTIntDisable(g_ui32Base, 0x1FFF); + + // + // Set IO clock as UART clock source + // + UARTClockSourceSet(g_ui32Base, UART_CLOCK_PIOSC); + + + + + // + // Configure the UART for 115200, n, 8, 1 + // + UARTConfigSetExpClk(g_ui32Base, ui32SrcClock, ui32Baud, + (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE | + UART_CONFIG_WLEN_8)); +#ifdef UART_BUFFERED + // + // Set the UART to interrupt whenever the TX FIFO is almost empty or + // when any character is received. + // + UARTFIFOLevelSet(g_ui32Base, UART_FIFO_TX1_8, UART_FIFO_RX1_8); + + // + // Flush both the buffers. + // + UARTFlushRx(); + UARTFlushTx(true); + + // + // Remember which interrupt we are dealing with. + // + g_ui32PortNum = ui32PortNum; + + // + // We are configured for buffered output so enable the master interrupt + // for this UART and the receive interrupts. We don't actually enable the + // transmit interrupt in the UART itself until some data has been placed + // in the transmit buffer. + // + UARTIntDisable(g_ui32Base, 0x1FFF); + UARTIntRegister(g_ui32Base, UARTStdioIntHandler); + UARTIntEnable(g_ui32Base, UART_INT_RX | UART_INT_RT); + IntEnable(g_ui32UARTInt[ui32PortNum]); +#endif + + // + // Enable the UART operation. + // + UARTEnable(g_ui32Base); +} + +//***************************************************************************** +// +//! Initializes the UART console. +//! +//! \param ui32PortNum is the number of UART port to use for the serial console +//! (0-2) +//! +//! This function will initialize the specified serial port to be used as a +//! serial console. The serial parameters will be set to 115200, 8-N-1. +//! An application wishing to use a different baud rate may call +//! UARTStdioInitExpClk() instead of this function. +//! +//! This function or UARTStdioInitExpClk() must be called prior to using any +//! of the other UART console functions: UARTprintf() or UARTgets(). In order +//! for this function to work correctly, SysCtlClockSet() must be called prior +//! to calling this function. +//! +//! It is assumed that the caller has previously configured the relevant UART +//! pins for operation as a UART rather than as GPIOs. +//! +//! \return None. +// +//***************************************************************************** +void +UARTStdioInit(uint32_t ui32PortNum) +{ + // + // Pass this call on to the version of the function allowing the baud rate + // to be specified. + // + UARTStdioConfig(ui32PortNum, 115200, SysCtrlClockGet()); +} + +//***************************************************************************** +// +//! Initializes the UART console and allows the baud rate to be selected. +//! +//! \param ui32PortNum is the number of UART port to use for the serial console +//! (0-2) +//! \param ui32Baud is the bit rate that the UART is to be configured to use. +//! +//! This function will initialize the specified serial port to be used as a +//! serial console. The serial parameters will be set to 8-N-1 and the bit +//! rate set according to the value of the \e ui32Baud parameter. +//! +//! This function or UARTStdioInit() must be called prior to using any of the +//! other UART console functions: UARTprintf() or UARTgets(). In order for +//! this function to work correctly, SysCtlClockSet() must be called prior to +//! calling this function. An application wishing to use 115,200 baud may call +//! UARTStdioInit() instead of this function but should not call both +//! functions. +//! +//! It is assumed that the caller has previously configured the relevant UART +//! pins for operation as a UART rather than as GPIOs. +//! +//! \return None. +// +//***************************************************************************** +void +UARTStdioInitExpClk(uint32_t ui32PortNum, uint32_t ui32Baud) +{ + UARTStdioConfig(ui32PortNum, ui32Baud, SysCtrlClockGet()); +} + +//***************************************************************************** +// +//! Writes a string of characters to the UART output. +//! +//! \param pcBuf points to a buffer containing the string to transmit. +//! \param ui32Len is the length of the string to transmit. +//! +//! This function will transmit the string to the UART output. The number of +//! characters transmitted is determined by the \e ui32Len parameter. This +//! function does no interpretation or translation of any characters. Since +//! the output is sent to a UART, any LF (/n) characters encountered will be +//! replaced with a CRLF pair. +//! +//! Besides using the \e ui32Len parameter to stop transmitting the string, if a +//! null character (0) is encountered, then no more characters will be +//! transmitted and the function will return. +//! +//! In non-buffered mode, this function is blocking and will not return until +//! all the characters have been written to the output FIFO. In buffered mode, +//! the characters are written to the UART transmit buffer and the call returns +//! immediately. If insufficient space remains in the transmit buffer, +//! additional characters are discarded. +//! +//! \return Returns the count of characters written. +// +//***************************************************************************** +int +UARTwrite(const char *pcBuf, uint32_t ui32Len) +{ +#ifdef UART_BUFFERED + unsigned int uIdx; + + // + // Check for valid arguments. + // + ASSERT(pcBuf != 0); + ASSERT(g_ui32Base != 0); + + // + // Send the characters + // + for(uIdx = 0; uIdx < ui32Len; uIdx++) + { + // + // If the character to the UART is \n, then add a \r before it so that + // \n is translated to \n\r in the output. + // + if(pcBuf[uIdx] == '\n') + { + if(!TX_BUFFER_FULL) + { + g_pcUARTTxBuffer[g_ui32UARTTxWriteIndex] = '\r'; + ADVANCE_TX_BUFFER_INDEX(g_ui32UARTTxWriteIndex); + } + else + { + // + // Buffer is full - discard remaining characters and return. + // + break; + } + } + + // + // Send the character to the UART output. + // + if(!TX_BUFFER_FULL) + { + g_pcUARTTxBuffer[g_ui32UARTTxWriteIndex] = pcBuf[uIdx]; + ADVANCE_TX_BUFFER_INDEX(g_ui32UARTTxWriteIndex); + } + else + { + // + // Buffer is full - discard remaining characters and return. + // + break; + } + } + + // + // If we have anything in the buffer, make sure that the UART is set + // up to transmit it. + // + if(!TX_BUFFER_EMPTY) + { + UARTPrimeTransmit(g_ui32Base); + UARTIntEnable(g_ui32Base, UART_INT_TX); + } + + // + // Return the number of characters written. + // + return(uIdx); +#else + unsigned int uIdx; + + // + // Check for valid UART base address, and valid arguments. + // + ASSERT(g_ui32Base != 0); + ASSERT(pcBuf != 0); + + // + // Send the characters + // + for(uIdx = 0; uIdx < ui32Len; uIdx++) + { + // + // If the character to the UART is \n, then add a \r before it so that + // \n is translated to \n\r in the output. + // + if(pcBuf[uIdx] == '\n') + { + UARTCharPut(g_ui32Base, '\r'); + } + + // + // Send the character to the UART output. + // + UARTCharPut(g_ui32Base, pcBuf[uIdx]); + } + + // + // Return the number of characters written. + // + return(uIdx); +#endif +} + +//***************************************************************************** +// +//! A simple UART based get string function, with some line processing. +//! +//! \param pcBuf points to a buffer for the incoming string from the UART. +//! \param ui32Len is the length of the buffer for storage of the string, +//! including the trailing 0. +//! +//! This function will receive a string from the UART input and store the +//! characters in the buffer pointed to by \e pcBuf. The characters will +//! continue to be stored until a termination character is received. The +//! termination characters are CR, LF, or ESC. A CRLF pair is treated as a +//! single termination character. The termination characters are not stored in +//! the string. The string will be terminated with a 0 and the function will +//! return. +//! +//! In both buffered and unbuffered modes, this function will block until +//! a termination character is received. If non-blocking operation is required +//! in buffered mode, a call to UARTPeek() may be made to determine whether +//! a termination character already exists in the receive buffer prior to +//! calling UARTgets(). +//! +//! Since the string will be null terminated, the user must ensure that the +//! buffer is sized to allow for the additional null character. +//! +//! \return Returns the count of characters that were stored, not including +//! the trailing 0. +// +//***************************************************************************** +int +UARTgets(char *pcBuf, uint32_t ui32Len) +{ +#ifdef UART_BUFFERED + uint32_t ui32Count = 0; + int8_t cChar; + + // + // Check the arguments. + // + ASSERT(pcBuf != 0); + ASSERT(ui32Len != 0); + ASSERT(g_ui32Base != 0); + + // + // Adjust the length back by 1 to leave space for the trailing + // null terminator. + // + ui32Len--; + + // + // Process characters until a newline is received. + // + while(1) + { + // + // Read the next character from the receive buffer. + // + if(!RX_BUFFER_EMPTY) + { + cChar = g_pcUARTRxBuffer[g_ui32UARTRxReadIndex]; + ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxReadIndex); + + // + // See if a newline or escape character was received. + // + if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b)) + { + // + // Stop processing the input and end the line. + // + break; + } + + // + // Process the received character as int32_t as we are not at the end + // of the buffer. If the end of the buffer has been reached then + // all additional characters are ignored until a newline is + // received. + // + if(ui32Count < ui32Len) + { + // + // Store the character in the caller supplied buffer. + // + pcBuf[ui32Count] = cChar; + + // + // Increment the count of characters received. + // + ui32Count++; + } + } + } + + // + // Add a null termination to the string. + // + pcBuf[ui32Count] = 0; + + // + // Return the count of int8_ts in the buffer, not counting the trailing 0. + // + return(ui32Count); +#else + uint32_t ui32Count = 0; + int8_t cChar; + static int8_t bLastWasCR = 0; + + // + // Check the arguments. + // + ASSERT(pcBuf != 0); + ASSERT(ui32Len != 0); + ASSERT(g_ui32Base != 0); + + // + // Adjust the length back by 1 to leave space for the trailing + // null terminator. + // + ui32Len--; + + // + // Process characters until a newline is received. + // + while(1) + { + // + // Read the next character from the console. + // + cChar = UARTCharGet(g_ui32Base); + + // + // See if the backspace key was pressed. + // + if(cChar == '\b') + { + // + // If there are any characters already in the buffer, then delete + // the last. + // + if(ui32Count) + { + // + // Rub out the previous character. + // + UARTwrite("\b \b", 3); + + // + // Decrement the number of characters in the buffer. + // + ui32Count--; + } + + // + // Skip ahead to read the next character. + // + continue; + } + + // + // If this character is LF and last was CR, then just gobble up the + // character because the EOL processing was taken care of with the CR. + // + if((cChar == '\n') && bLastWasCR) + { + bLastWasCR = 0; + continue; + } + + // + // See if a newline or escape character was received. + // + if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b)) + { + // + // If the character is a CR, then it may be followed by a LF which + // should be paired with the CR. So remember that a CR was + // received. + // + if(cChar == '\r') + { + bLastWasCR = 1; + } + + // + // Stop processing the input and end the line. + // + break; + } + + // + // Process the received character as int32_t as we are not at the end of + // the buffer. If the end of the buffer has been reached then all + // additional characters are ignored until a newline is received. + // + if(ui32Count < ui32Len) + { + // + // Store the character in the caller supplied buffer. + // + pcBuf[ui32Count] = cChar; + + // + // Increment the count of characters received. + // + ui32Count++; + + // + // Reflect the character back to the user. + // + UARTCharPut(g_ui32Base, cChar); + } + } + + // + // Add a null termination to the string. + // + pcBuf[ui32Count] = 0; + + // + // Send a CRLF pair to the terminal to end the line. + // + UARTwrite("\r\n", 2); + + // + // Return the count of int8_ts in the buffer, not counting the trailing 0. + // + return(ui32Count); +#endif +} + +//***************************************************************************** +// +//! Read a single character from the UART, blocking if necessary. +//! +//! This function will receive a single character from the UART and store it at +//! the supplied address. +//! +//! In both buffered and unbuffered modes, this function will block until a +//! character is received. If non-blocking operation is required in buffered +//! mode, a call to UARTRxAvail() may be made to determine whether any +//! characters are currently available for reading. +//! +//! \return Returns the character read. +// +//***************************************************************************** +unsigned char +UARTgetc(void) +{ +#ifdef UART_BUFFERED + unsigned char cChar; + + // + // Wait for a character to be received. + // + while(RX_BUFFER_EMPTY) + { + // + // Block waiting for a character to be received (if the buffer is + // currently empty). + // + } + + // + // Read a character from the buffer. + // + cChar = g_pcUARTRxBuffer[g_ui32UARTRxReadIndex]; + ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxReadIndex); + + // + // Return the character to the caller. + // + return(cChar); +#else + // + // Block until a character is received by the UART then return it to + // the caller. + // + return(UARTCharGet(g_ui32Base)); +#endif +} + +//***************************************************************************** +// +//! A simple UART based vprintf function supporting \%c, \%d, \%p, \%s, \%u, +//! \%x, and \%X. +//! +//! \param pcString is the format string. +//! \param vaArgP is a variable argument list pointer whose content will depend +//! upon the format string passed in \e pcString. +//! +//! This function is very similar to the C library vprintf() function. +//! All of its output will be sent to the UART. Only the following formatting +//! characters are supported: +//! +//! - \%c to print a character +//! - \%d or \%i to print a decimal value +//! - \%s to print a string +//! - \%u to print an unsigned decimal value +//! - \%x to print a hexadecimal value using lower case letters +//! - \%X to print a hexadecimal value using lower case letters (not upper case +//! letters as would typically be used) +//! - \%p to print a pointer as a hexadecimal value +//! - \%\% to print out a \% character +//! +//! For \%s, \%d, \%i, \%u, \%p, \%x, and \%X, an optional number may reside +//! between the \% and the format character, which specifies the minimum number +//! of characters to use for that value; if preceded by a 0 then the extra +//! characters will be filled with zeros instead of spaces. For example, +//! ``\%8d'' will use eight characters to print the decimal value with spaces +//! added to reach eight; ``\%08d'' will use eight characters as well but will +//! add zeroes instead of spaces. +//! +//! The type of the arguments in the variable arguments list must match the +//! requirements of the format string. For example, if an integer was passed +//! where a string was expected, an error of some kind will most likely occur. +//! +//! \return None. +// +//***************************************************************************** +void +UARTvprintf(const char *pcString, va_list vaArgP) +{ + uint32_t ui32Idx, ui32Value, ui32Pos, ui32Count, ui32Base, ui32Neg; + char *pcStr, pcBuf[16], cFill; + + // + // Check the arguments. + // + ASSERT(pcString != 0); + + // + // Loop while there are more characters in the string. + // + while(*pcString) + { + // + // Find the first non-% character, or the end of the string. + // + for(ui32Idx = 0; (pcString[ui32Idx] != '%') && (pcString[ui32Idx] != '\0'); + ui32Idx++) + { + } + + // + // Write this portion of the string. + // + UARTwrite(pcString, ui32Idx); + + // + // Skip the portion of the string that was written. + // + pcString += ui32Idx; + + // + // See if the next character is a %. + // + if(*pcString == '%') + { + // + // Skip the %. + // + pcString++; + + // + // Set the digit count to zero, and the fill character to space + // (i.e. to the defaults). + // + ui32Count = 0; + cFill = ' '; + + // + // It may be necessary to get back here to process more characters. + // Goto's aren't pretty, but effective. I feel extremely dirty for + // using not one but two of the beasts. + // +again: + + // + // Determine how to handle the next character. + // + switch(*pcString++) + { + // + // Handle the digit characters. + // + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + // + // If this is a zero, and it is the first digit, then the + // fill character is a zero instead of a space. + // + if((pcString[-1] == '0') && (ui32Count == 0)) + { + cFill = '0'; + } + + // + // Update the digit count. + // + ui32Count *= 10; + ui32Count += pcString[-1] - '0'; + + // + // Get the next character. + // + goto again; + } + + // + // Handle the %c command. + // + case 'c': + { + // + // Get the value from the varargs. + // + ui32Value = va_arg(vaArgP, uint32_t); + + // + // Print out the character. + // + UARTwrite((char *)&ui32Value, 1); + + // + // This command has been handled. + // + break; + } + + // + // Handle the %d and %i commands. + // + case 'd': + case 'i': + { + // + // Get the value from the varargs. + // + ui32Value = va_arg(vaArgP, uint32_t); + + // + // Reset the buffer position. + // + ui32Pos = 0; + + // + // If the value is negative, make it positive and indicate + // that a minus sign is needed. + // + if((int32_t)ui32Value < 0) + { + // + // Make the value positive. + // + ui32Value = -(int32_t)ui32Value; + + // + // Indicate that the value is negative. + // + ui32Neg = 1; + } + else + { + // + // Indicate that the value is positive so that a minus + // sign isn't inserted. + // + ui32Neg = 0; + } + + // + // Set the base to 10. + // + ui32Base = 10; + + // + // Convert the value to ASCII. + // + goto convert; + } + + // + // Handle the %s command. + // + case 's': + { + // + // Get the string pointer from the varargs. + // + pcStr = va_arg(vaArgP, char *); + + // + // Determine the length of the string. + // + for(ui32Idx = 0; pcStr[ui32Idx] != '\0'; ui32Idx++) + { + } + + // + // Write the string. + // + UARTwrite(pcStr, ui32Idx); + + // + // Write any required padding spaces + // + if(ui32Count > ui32Idx) + { + ui32Count -= ui32Idx; + while(ui32Count--) + { + UARTwrite(" ", 1); + } + } + + // + // This command has been handled. + // + break; + } + + // + // Handle the %u command. + // + case 'u': + { + // + // Get the value from the varargs. + // + ui32Value = va_arg(vaArgP, uint32_t); + + // + // Reset the buffer position. + // + ui32Pos = 0; + + // + // Set the base to 10. + // + ui32Base = 10; + + // + // Indicate that the value is positive so that a minus sign + // isn't inserted. + // + ui32Neg = 0; + + // + // Convert the value to ASCII. + // + goto convert; + } + + // + // Handle the %x and %X commands. Note that they are treated + // identically; i.e. %X will use lower case letters for a-f + // instead of the upper case letters is should use. We also + // alias %p to %x. + // + case 'x': + case 'X': + case 'p': + { + // + // Get the value from the varargs. + // + ui32Value = va_arg(vaArgP, uint32_t); + + // + // Reset the buffer position. + // + ui32Pos = 0; + + // + // Set the base to 16. + // + ui32Base = 16; + + // + // Indicate that the value is positive so that a minus sign + // isn't inserted. + // + ui32Neg = 0; + + // + // Determine the number of digits in the string version of + // the value. + // +convert: + for(ui32Idx = 1; + (((ui32Idx * ui32Base) <= ui32Value) && + (((ui32Idx * ui32Base) / ui32Base) == ui32Idx)); + ui32Idx *= ui32Base, ui32Count--) + { + } + + // + // If the value is negative, reduce the count of padding + // characters needed. + // + if(ui32Neg) + { + ui32Count--; + } + + // + // If the value is negative and the value is padded with + // zeros, then place the minus sign before the padding. + // + if(ui32Neg && (cFill == '0')) + { + // + // Place the minus sign in the output buffer. + // + pcBuf[ui32Pos++] = '-'; + + // + // The minus sign has been placed, so turn off the + // negative flag. + // + ui32Neg = 0; + } + + // + // Provide additional padding at the beginning of the + // string conversion if needed. + // + if((ui32Count > 1) && (ui32Count < 16)) + { + for(ui32Count--; ui32Count; ui32Count--) + { + pcBuf[ui32Pos++] = cFill; + } + } + + // + // If the value is negative, then place the minus sign + // before the number. + // + if(ui32Neg) + { + // + // Place the minus sign in the output buffer. + // + pcBuf[ui32Pos++] = '-'; + } + + // + // Convert the value into a string. + // + for(; ui32Idx; ui32Idx /= ui32Base) + { + pcBuf[ui32Pos++] = g_pcHex[(ui32Value / ui32Idx) % ui32Base]; + } + + // + // Write the string. + // + UARTwrite(pcBuf, ui32Pos); + + // + // This command has been handled. + // + break; + } + + // + // Handle the %% command. + // + case '%': + { + // + // Simply write a single %. + // + UARTwrite(pcString - 1, 1); + + // + // This command has been handled. + // + break; + } + + // + // Handle all other commands. + // + default: + { + // + // Indicate an error. + // + UARTwrite("ERROR", 5); + + // + // This command has been handled. + // + break; + } + } + } + } +} + +//***************************************************************************** +// +//! A simple UART based printf function supporting \%c, \%d, \%p, \%s, \%u, +//! \%x, and \%X. +//! +//! \param pcString is the format string. +//! \param ... are the optional arguments, which depend on the contents of the +//! format string. +//! +//! This function is very similar to the C library fprintf() function. +//! All of its output will be sent to the UART. Only the following formatting +//! characters are supported: +//! +//! - \%c to print a character +//! - \%d or \%i to print a decimal value +//! - \%s to print a string +//! - \%u to print an unsigned decimal value +//! - \%x to print a hexadecimal value using lower case letters +//! - \%X to print a hexadecimal value using lower case letters (not upper case +//! letters as would typically be used) +//! - \%p to print a pointer as a hexadecimal value +//! - \%\% to print out a \% character +//! +//! For \%s, \%d, \%i, \%u, \%p, \%x, and \%X, an optional number may reside +//! between the \% and the format character, which specifies the minimum number +//! of characters to use for that value; if preceded by a 0 then the extra +//! characters will be filled with zeros instead of spaces. For example, +//! ``\%8d'' will use eight characters to print the decimal value with spaces +//! added to reach eight; ``\%08d'' will use eight characters as well but will +//! add zeroes instead of spaces. +//! +//! The type of the arguments after \e pcString must match the requirements of +//! the format string. For example, if an integer was passed where a string +//! was expected, an error of some kind will most likely occur. +//! +//! \return None. +// +//***************************************************************************** +void +UARTprintf(const char *pcString, ...) +{ + va_list vaArgP; + + // + // Start the varargs processing. + // + va_start(vaArgP, pcString); + + UARTvprintf(pcString, vaArgP); + + // + // We're finished with the varargs now. + // + va_end(vaArgP); +} + +//***************************************************************************** +// +//! Returns the number of bytes available in the receive buffer. +//! +//! This function, available only when the module is built to operate in +//! buffered mode using \b UART_BUFFERED, may be used to determine the number +//! of bytes of data currently available in the receive buffer. +//! +//! \return Returns the number of available bytes. +// +//***************************************************************************** +#if defined(UART_BUFFERED) || defined(DOXYGEN) +int +UARTRxBytesAvail(void) +{ + return(RX_BUFFER_USED); +} +#endif + +#if defined(UART_BUFFERED) || defined(DOXYGEN) +//***************************************************************************** +// +//! Returns the number of bytes free in the transmit buffer. +//! +//! This function, available only when the module is built to operate in +//! buffered mode using \b UART_BUFFERED, may be used to determine the amount +//! of space currently available in the transmit buffer. +//! +//! \return Returns the number of free bytes. +// +//***************************************************************************** +int +UARTTxBytesFree(void) +{ + return(TX_BUFFER_FREE); +} +#endif + +//***************************************************************************** +// +//! Looks ahead in the receive buffer for a particular character. +//! +//! \param ucChar is the character that is to be searched for. +//! +//! This function, available only when the module is built to operate in +//! buffered mode using \b UART_BUFFERED, may be used to look ahead in the +//! receive buffer for a particular character and report its position if found. +//! It is typically used to determine whether a complete line of user input is +//! available, in which case ucChar should be set to CR ('\\r') which is used +//! as the line end marker in the receive buffer. +//! +//! \return Returns -1 to indicate that the requested character does not exist +//! in the receive buffer. Returns a non-negative number if the character was +//! found in which case the value represents the position of the first instance +//! of \e ucChar relative to the receive buffer read pointer. +// +//***************************************************************************** +#if defined(UART_BUFFERED) || defined(DOXYGEN) +int +UARTPeek(unsigned char ucChar) +{ + int iCount; + int iAvail; + uint32_t ui32ReadIndex; + + // + // How many characters are there in the receive buffer? + // + iAvail = (int)RX_BUFFER_USED; + ui32ReadIndex = g_ui32UARTRxReadIndex; + + // + // Check all the unread characters looking for the one passed. + // + for(iCount = 0; iCount < iAvail; iCount++) + { + if(g_pcUARTRxBuffer[ui32ReadIndex] == ucChar) + { + // + // We found it so return the index + // + return(iCount); + } + else + { + // + // This one didn't match so move on to the next character. + // + ADVANCE_RX_BUFFER_INDEX(ui32ReadIndex); + } + } + + // + // If we drop out of the loop, we didn't find the character in the receive + // buffer. + // + return(-1); +} +#endif + +//***************************************************************************** +// +//! Flushes the receive buffer. +//! +//! This function, available only when the module is built to operate in +//! buffered mode using \b UART_BUFFERED, may be used to discard any data +//! received from the UART but not yet read using UARTgets(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(UART_BUFFERED) || defined(DOXYGEN) +void +UARTFlushRx(void) +{ + uint32_t ui32Int; + + // + // Temporarily turn off interrupts. + // + ui32Int = IntMasterDisable(); + + // + // Flush the receive buffer. + // + g_ui32UARTRxReadIndex = 0; + g_ui32UARTRxWriteIndex = 0; + + // + // If interrupts were enabled when we turned them off, turn them + // back on again. + // + if(!ui32Int) + { + IntMasterEnable(); + } +} +#endif + +//***************************************************************************** +// +//! Flushes the transmit buffer. +//! +//! \param bDiscard indicates whether any remaining data in the buffer should +//! be discarded (\b true) or transmitted (\b false). +//! +//! This function, available only when the module is built to operate in +//! buffered mode using \b UART_BUFFERED, may be used to flush the transmit +//! buffer, either discarding or transmitting any data received via calls to +//! UARTprintf() that is waiting to be transmitted. On return, the transmit +//! buffer will be empty. +//! +//! \return None. +// +//***************************************************************************** +#if defined(UART_BUFFERED) || defined(DOXYGEN) +void +UARTFlushTx(bool bDiscard) +{ + uint32_t ui32Int; + + // + // Should the remaining data be discarded or transmitted? + // + if(bDiscard) + { + // + // The remaining data should be discarded, so temporarily turn off + // interrupts. + // + ui32Int = IntMasterDisable(); + + // + // Flush the transmit buffer. + // + g_ui32UARTTxReadIndex = 0; + g_ui32UARTTxWriteIndex = 0; + + // + // If interrupts were enabled when we turned them off, turn them + // back on again. + // + if(!ui32Int) + { + IntMasterEnable(); + } + } + else + { + // + // Wait for all remaining data to be transmitted before returning. + // + while(!TX_BUFFER_EMPTY) + { + } + } +} +#endif + +//***************************************************************************** +// +//! Enables or disables echoing of received characters to the transmitter. +//! +//! \param bEnable must be set to \b true to enable echo or \b false to +//! disable it. +//! +//! This function, available only when the module is built to operate in +//! buffered mode using \b UART_BUFFERED, may be used to control whether or not +//! received characters are automatically echoed back to the transmitter. By +//! default, echo is enabled and this is typically the desired behavior if +//! the module is being used to support a serial command line. In applications +//! where this module is being used to provide a convenient, buffered serial +//! interface over which application-specific binary protocols are being run, +//! however, echo may be undesirable and this function can be used to disable +//! it. +//! +//! \return None. +// +//***************************************************************************** +#if defined(UART_BUFFERED) || defined(DOXYGEN) +void +UARTEchoSet(bool bEnable) +{ + g_bDisableEcho = !bEnable; +} +#endif + +//***************************************************************************** +// +//! Handles UART interrupts. +//! +//! This function handles interrupts from the UART. It will copy data from the +//! transmit buffer to the UART transmit FIFO if space is available, and it +//! will copy data from the UART receive FIFO to the receive buffer if data is +//! available. +//! +//! \return None. +// +//***************************************************************************** +#if defined(UART_BUFFERED) || defined(DOXYGEN) +void +UARTStdioIntHandler(void) +{ + uint32_t ui32Ints; + int8_t cChar; + int32_t i32Char; + static bool bLastWasCR = false; + + // + // Get and clear the current interrupt source(s) + // + ui32Ints = UARTIntStatus(g_ui32Base, true); + UARTIntClear(g_ui32Base, ui32Ints); + + // + // Are we being interrupted because the TX FIFO has space available? + // + if(ui32Ints & UART_INT_TX) + { + // + // Move as many bytes as we can into the transmit FIFO. + // + UARTPrimeTransmit(g_ui32Base); + + // + // If the output buffer is empty, turn off the transmit interrupt. + // + if(TX_BUFFER_EMPTY) + { + UARTIntDisable(g_ui32Base, UART_INT_TX); + } + } + + // + // Are we being interrupted due to a received character? + // + if(ui32Ints & (UART_INT_RX | UART_INT_RT)) + { + // + // Get all the available characters from the UART. + // + while(UARTCharsAvail(g_ui32Base)) + { + // + // Read a character + // + i32Char = UARTCharGetNonBlocking(g_ui32Base); + cChar = (unsigned char)(i32Char & 0xFF); + + // + // If echo is disabled, we skip the various text filtering + // operations that would typically be required when supporting a + // command line. + // + if(!g_bDisableEcho) + { + // + // Handle backspace by erasing the last character in the buffer. + // + if(cChar == '\b') + { + // + // If there are any characters already in the buffer, then + // delete the last. + // + if(!RX_BUFFER_EMPTY) + { + // + // Rub out the previous character on the users terminal. + // + UARTwrite("\b \b", 3); + + // + // Decrement the number of characters in the buffer. + // + if(g_ui32UARTRxWriteIndex == 0) + { + g_ui32UARTRxWriteIndex = UART_RX_BUFFER_SIZE - 1; + } + else + { + g_ui32UARTRxWriteIndex--; + } + } + + // + // Skip ahead to read the next character. + // + continue; + } + + // + // If this character is LF and last was CR, then just gobble up + // the character since we already echoed the previous CR and we + // don't want to store 2 characters in the buffer if we don't + // need to. + // + if((cChar == '\n') && bLastWasCR) + { + bLastWasCR = false; + continue; + } + + // + // See if a newline or escape character was received. + // + if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b)) + { + // + // If the character is a CR, then it may be followed by an + // LF which should be paired with the CR. So remember that + // a CR was received. + // + if(cChar == '\r') + { + bLastWasCR = 1; + } + + // + // Regardless of the line termination character received, + // put a CR in the receive buffer as a marker telling + // UARTgets() where the line ends. We also send an + // additional LF to ensure that the local terminal echo + // receives both CR and LF. + // + cChar = '\r'; + UARTwrite("\n", 1); + } + } + + // + // If there is space in the receive buffer, put the character + // there, otherwise throw it away. + // + if(!RX_BUFFER_FULL) + { + // + // Store the new character in the receive buffer + // + g_pcUARTRxBuffer[g_ui32UARTRxWriteIndex] = + (unsigned char)(i32Char & 0xFF); + ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxWriteIndex); + + // + // If echo is enabled, write the character to the transmit + // buffer so that the user gets some immediate feedback. + // + if(!g_bDisableEcho) + { + UARTwrite((const char *)&cChar, 1); + } + } + } + + // + // If we wrote anything to the transmit buffer, make sure it actually + // gets transmitted. + // + UARTPrimeTransmit(g_ui32Base); + UARTIntEnable(g_ui32Base, UART_INT_TX); + } +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/boards/mimsy2-cc2538/uartstdio.h b/bsp/boards/mimsy2-cc2538/uartstdio.h new file mode 100644 index 0000000000..6083aa6bc2 --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/uartstdio.h @@ -0,0 +1,104 @@ +/****************************************************************************** +* Filename: uartstdio.h +* Revised: $Date: 2013-04-08 17:38:20 +0200 (Mon, 08 Apr 2013) $ +* Revision: $Revision: 9684 $ +* +* Description: Prototypes for the UART console functions. +* +* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef __UARTSTDIO_H__ +#define __UARTSTDIO_H__ + +#include +#include +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// If built for buffered operation, the following labels define the sizes of +// the transmit and receive buffers respectively. +// +//***************************************************************************** +#ifdef UART_BUFFERED +#ifndef UART_RX_BUFFER_SIZE +#define UART_RX_BUFFER_SIZE 128 +#endif +#ifndef UART_TX_BUFFER_SIZE +#define UART_TX_BUFFER_SIZE 1024 +#endif +#endif + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void UARTStdioConfig(uint32_t ui32Port, uint32_t ui32Baud, + uint32_t ui32SrcClock); +extern void UARTStdioInit(uint32_t ui32Port); +extern void UARTStdioInitExpClk(uint32_t ui32Port, uint32_t ui32Baud); +extern int UARTgets(char *pcBuf, uint32_t ui32Len); +extern unsigned char UARTgetc(void); +extern void UARTprintf(const char *pcString, ...); +extern void UARTvprintf(const char *pcString, va_list vaArgP); +extern int UARTwrite(const char *pcBuf, uint32_t ui32Len); +#ifdef UART_BUFFERED +extern int UARTPeek(unsigned char ucChar); +extern void UARTFlushTx(bool bDiscard); +extern void UARTFlushRx(void); +extern int UARTRxBytesAvail(void); +extern int UARTTxBytesFree(void); +extern void UARTEchoSet(bool bEnable); +extern void UARTStdioIntHandler(void); +#endif + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __UARTSTDIO_H__ From aca6f1f85df68f1ee7c21a1173789d9b5075d05b Mon Sep 17 00:00:00 2001 From: skrillberg Date: Fri, 27 Apr 2018 17:01:54 -0700 Subject: [PATCH 2/5] cleaned up sconscript file --- SConscript | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SConscript b/SConscript index 32ee068c07..2d0bca2e46 100644 --- a/SConscript +++ b/SConscript @@ -218,8 +218,7 @@ elif env['toolchain']=='armgcc': env.Append(CCFLAGS = '-mthumb') env.Append(CCFLAGS = '-g3') env.Append(CCFLAGS = '-Wstrict-prototypes') - #if env['board'] == "mimsy2-cc2538": - # env.Append(CCFLAGS = '-lm') #added to hopefully prevent a linker overlap between .ARM.exidx and .data + if env['revision'] == "A1": env.Append(CCFLAGS = '-DREVA1=1') From 4518e97d491bbf8666004fd533f273d50b1391f9 Mon Sep 17 00:00:00 2001 From: skrillberg Date: Fri, 27 Apr 2018 17:04:56 -0700 Subject: [PATCH 3/5] cleaned up sconscript file again --- SConscript | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/SConscript b/SConscript index 2d0bca2e46..b592adf49d 100644 --- a/SConscript +++ b/SConscript @@ -231,12 +231,7 @@ elif env['toolchain']=='armgcc': # linker env.Append(LINKFLAGS = '-Tbsp/boards/'+env['board']+'/' + linker_file) env.Append(LINKFLAGS = '-nostartfiles') - #if env['board'] == "mimsy2-cc2538": - #env.Replace(LIBLINKPREFIX = 'lib') - #env.Replace(LIBLINKSUFFIX = '.a') - #env.Replace(LIBS = 'm') - #env.Append(LIBLINKSUFFIXES='.a') - #env.Append(LIBPATH='#C:\Program Files (x86)\GNU Tools ARM Embedded\5.4 2016q3\arm-none-eabi\lib\armv7-m') + env.Append(LINKFLAGS = '-Wl,-Map,${TARGET.base}.map') env.Append(LINKFLAGS = '-mcpu=cortex-m3') env.Append(LINKFLAGS = '-mthumb') @@ -1065,5 +1060,5 @@ buildEnv.SConscript( variant_dir = projectsVarDir, ) -buildEnv.Append(LIBPATH = '#C:\Program Files (x86)\GNU Tools ARM Embedded\5.4 2016q3\arm-none-eabi\lib\armv7-m') + buildEnv.Append(LIBS = "libm") \ No newline at end of file From 0464b0a41b567328deb452bd48ff6d48a0db5a6e Mon Sep 17 00:00:00 2001 From: skrillberg Date: Thu, 10 May 2018 18:14:28 -0700 Subject: [PATCH 4/5] added sconstruct file --- SConstruct | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/SConstruct b/SConstruct index b0dd6e104b..b6e8b24329 100644 --- a/SConstruct +++ b/SConstruct @@ -78,9 +78,7 @@ project: openstack/02a-MAClow/topology.c file. noadaptivesync Do not use adaptive synchronization. l2_security Use hop-by-hop encryption and authentication. - 0 (off), 1 (on) - printf Sends the string messages to openvisualizer - 0 (off ), 1 (on, default) + 0 (off), 1 (on) ide qtcreator Common variables: @@ -108,6 +106,7 @@ command_line_options = { 'z1', # Cortex-M3 'openmote-cc2538', + 'mimsy2-cc2538', 'openmote-b', 'silabs-ezr32wg', 'openmotestm', @@ -139,8 +138,7 @@ command_line_options = { 'forcetopology': ['0','1'], 'debug': ['0','1'], 'noadaptivesync': ['0','1'], - 'l2_security': ['0','1'], - 'printf': ['1','0'], # 1=on (default), 0=off + 'l2_security': ['0','1'], 'deadline_option': ['0','1'], 'ide': ['none','qtcreator'], 'revision': [''] @@ -287,13 +285,6 @@ command_line_vars.AddVariables( command_line_options['l2_security'][0], # default validate_option, # validator int, # converter - ), - ( - 'printf', # key - '', # help - command_line_options['printf'][0], # default - validate_option, # validator - int, # converter ), ( 'deadline_option', # key From 9be32c089d15c73f14d473690415b470a4b12cd2 Mon Sep 17 00:00:00 2001 From: skrillberg Date: Tue, 15 May 2018 20:34:49 +0000 Subject: [PATCH 5/5] builds now --- SConscript | 6 +- bsp/boards/mimsy2-cc2538/README.md | 14 +- bsp/boards/mimsy2-cc2538/SConscript | 84 +- bsp/boards/mimsy2-cc2538/accel_mimsy.c | 2 +- bsp/boards/mimsy2-cc2538/board.c | 634 ++-- bsp/boards/mimsy2-cc2538/board_info.h | 236 +- bsp/boards/mimsy2-cc2538/cc2538rf.h | 186 +- bsp/boards/mimsy2-cc2538/cc2538sf23.lds | 124 +- bsp/boards/mimsy2-cc2538/cc2538sf53.lds | 124 +- bsp/boards/mimsy2-cc2538/debugpins.c | 263 +- bsp/boards/mimsy2-cc2538/eui64.c | 80 +- bsp/boards/mimsy2-cc2538/i2c.c | 399 ++- bsp/boards/mimsy2-cc2538/leds.c | 422 ++- bsp/boards/mimsy2-cc2538/pwm.c | 62 + bsp/boards/mimsy2-cc2538/pwm.h | 31 + bsp/boards/mimsy2-cc2538/radio.c | 1062 +++---- bsp/boards/mimsy2-cc2538/sctimer.c | 4 +- bsp/boards/mimsy2-cc2538/startup_gcc.c | 730 ++--- bsp/boards/mimsy2-cc2538/uart.c | 324 +- .../01bsp_infrared/01bsp_infrared.c | 155 + .../01bsp_infrared/01bsp_infrared.ewd | 2641 +++++++++++++++++ .../01bsp_infrared/01bsp_infrared.ewp | 2232 ++++++++++++++ .../01bsp_sctimer/01bsp_sctimer.ewd | 2641 +++++++++++++++++ .../01bsp_sctimer/01bsp_sctimer.ewp | 2256 ++++++++++++++ .../02drv_opentimers/02drv_opentimers.ewd | 2641 +++++++++++++++++ .../02drv_opentimers/02drv_opentimers.ewp | 2291 ++++++++++++++ .../03oos_macpong/03oos_macpong.ewd | 2641 +++++++++++++++++ .../03oos_macpong/03oos_macpong.ewp | 2395 +++++++++++++++ .../03oos_openwsn/03oos_openwsn.ewd | 2641 +++++++++++++++++ .../03oos_openwsn/03oos_openwsn.ewp | 2640 ++++++++++++++++ .../03oos_sniffer/03oos_sniffer.ewd | 2641 +++++++++++++++++ .../03oos_sniffer/03oos_sniffer.ewp | 2309 ++++++++++++++ .../mimsy2-cc2538/Eclipse-format/.cproject | 454 +++ .../mimsy2-cc2538/Eclipse-format/.project | 133 + .../.settings/language.settings.xml | 26 + .../Eclipse-format/OpenWSN Debug.launch | 82 + .../mimsy2-cc2538/Eclipse-format/README.txt | 50 + projects/mimsy2-cc2538/SConscript | 5 + projects/mimsy2-cc2538/SConscript.env | 27 + projects/mimsy2-cc2538/cc2538_gdb.gdb | 14 + projects/mimsy2-cc2538/openmote_cc2538.eww | 49 + .../openmote-cc2538/Eclipse-format/.cproject | 676 +++-- .../.settings/language.settings.xml | 26 + .../Eclipse-format/OpenWSN Debug.launch | 159 +- 44 files changed, 33954 insertions(+), 2658 deletions(-) create mode 100644 bsp/boards/mimsy2-cc2538/pwm.c create mode 100644 bsp/boards/mimsy2-cc2538/pwm.h create mode 100644 projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.c create mode 100644 projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.ewd create mode 100644 projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.ewp create mode 100644 projects/mimsy2-cc2538/01bsp_sctimer/01bsp_sctimer.ewd create mode 100644 projects/mimsy2-cc2538/01bsp_sctimer/01bsp_sctimer.ewp create mode 100644 projects/mimsy2-cc2538/02drv_opentimers/02drv_opentimers.ewd create mode 100644 projects/mimsy2-cc2538/02drv_opentimers/02drv_opentimers.ewp create mode 100644 projects/mimsy2-cc2538/03oos_macpong/03oos_macpong.ewd create mode 100644 projects/mimsy2-cc2538/03oos_macpong/03oos_macpong.ewp create mode 100644 projects/mimsy2-cc2538/03oos_openwsn/03oos_openwsn.ewd create mode 100644 projects/mimsy2-cc2538/03oos_openwsn/03oos_openwsn.ewp create mode 100644 projects/mimsy2-cc2538/03oos_sniffer/03oos_sniffer.ewd create mode 100644 projects/mimsy2-cc2538/03oos_sniffer/03oos_sniffer.ewp create mode 100644 projects/mimsy2-cc2538/Eclipse-format/.cproject create mode 100644 projects/mimsy2-cc2538/Eclipse-format/.project create mode 100644 projects/mimsy2-cc2538/Eclipse-format/.settings/language.settings.xml create mode 100644 projects/mimsy2-cc2538/Eclipse-format/OpenWSN Debug.launch create mode 100644 projects/mimsy2-cc2538/Eclipse-format/README.txt create mode 100644 projects/mimsy2-cc2538/SConscript create mode 100644 projects/mimsy2-cc2538/SConscript.env create mode 100644 projects/mimsy2-cc2538/cc2538_gdb.gdb create mode 100644 projects/mimsy2-cc2538/openmote_cc2538.eww create mode 100644 projects/openmote-cc2538/Eclipse-format/.settings/language.settings.xml diff --git a/SConscript b/SConscript index b592adf49d..df96a6ce9d 100644 --- a/SConscript +++ b/SConscript @@ -46,8 +46,8 @@ if env['noadaptivesync']==1: env.Append(CPPDEFINES = 'NOADAPTIVESYNC') if env['l2_security']==1: env.Append(CPPDEFINES = 'L2_SECURITY_ACTIVE') -if env['printf']==1: - env.Append(CPPDEFINES = 'OPENSERIAL_PRINTF') +#if env['printf']==1: + # env.Append(CPPDEFINES = 'OPENSERIAL_PRINTF') if env['deadline_option']==1: env.Append(CPPDEFINES = 'DEADLINE_OPTION_ENABLED') @@ -1061,4 +1061,4 @@ buildEnv.SConscript( ) -buildEnv.Append(LIBS = "libm") \ No newline at end of file +buildEnv.Append(LIBS = "libm") diff --git a/bsp/boards/mimsy2-cc2538/README.md b/bsp/boards/mimsy2-cc2538/README.md index 4a652188d2..2d1e1b2d5c 100644 --- a/bsp/boards/mimsy2-cc2538/README.md +++ b/bsp/boards/mimsy2-cc2538/README.md @@ -1,7 +1,7 @@ -The OpenWSN BSP (Board Support Package) for the CC2538 platform is based on the -CC2538 Foundation Firmware provided by Texas Instruments (available at: -http://www.ti.com/tool/cc2538-sw). The current version of the CC2538 Foundation -Firmware is Rev. A which dates from May 6, 2013. Information regarding the -CC2538 Foundation Firmware can be found in the CC2538 Peripheral Driver Library -User's Guide (available at: http://www.ti.com/lit/pdf/swru325) which also -dates from May 6, 2013. +The OpenWSN BSP (Board Support Package) for the CC2538 platform is based on the +CC2538 Foundation Firmware provided by Texas Instruments (available at: +http://www.ti.com/tool/cc2538-sw). The current version of the CC2538 Foundation +Firmware is Rev. A which dates from May 6, 2013. Information regarding the +CC2538 Foundation Firmware can be found in the CC2538 Peripheral Driver Library +User's Guide (available at: http://www.ti.com/lit/pdf/swru325) which also +dates from May 6, 2013. diff --git a/bsp/boards/mimsy2-cc2538/SConscript b/bsp/boards/mimsy2-cc2538/SConscript index 64f3e095db..4777294c0c 100644 --- a/bsp/boards/mimsy2-cc2538/SConscript +++ b/bsp/boards/mimsy2-cc2538/SConscript @@ -1,42 +1,42 @@ -import os - -Import('env') - -localEnv = env.Clone() - -adxl346 = localEnv.SConscript( - os.path.join('#','bsp','chips','adxl346','SConscript'), - variant_dir = 'adxl346', - exports = {'env': env}, -) - -max44009 = localEnv.SConscript( - os.path.join('#','bsp','chips','max44009','SConscript'), - variant_dir = 'max44009', - exports = {'env': env}, -) - -sht21 = localEnv.SConscript( - os.path.join('#','bsp','chips','sht21','SConscript'), - variant_dir = 'sht21', - exports = {'env': env}, -) - -source = \ - [file for file in Glob('*.c') if file.name.find('iar')==-1] + \ - Glob('source/*.c') - -localEnv.Append( - CPPPATH = [ - os.path.join('#','bsp','boards','mimsy2-cc2538'), - os.path.join('#','bsp','boards','mimsy2-cc2538','headers'), - os.path.join('#','bsp','boards','mimsy2-cc2538','source'), - os.path.join('#','bsp','chips','adxl346'), - os.path.join('#','bsp','chips','max44009'), - os.path.join('#','bsp','chips','sht21'), - ], -) - -board = localEnv.Object(source=source) + adxl346 + max44009 + sht21 - -Return('board') +import os + +Import('env') + +localEnv = env.Clone() + +adxl346 = localEnv.SConscript( + os.path.join('#','bsp','chips','adxl346','SConscript'), + variant_dir = 'adxl346', + exports = {'env': env}, +) + +max44009 = localEnv.SConscript( + os.path.join('#','bsp','chips','max44009','SConscript'), + variant_dir = 'max44009', + exports = {'env': env}, +) + +sht21 = localEnv.SConscript( + os.path.join('#','bsp','chips','sht21','SConscript'), + variant_dir = 'sht21', + exports = {'env': env}, +) + +source = \ + [file for file in Glob('*.c') if file.name.find('iar')==-1] + \ + Glob('source/*.c') + +localEnv.Append( + CPPPATH = [ + os.path.join('#','bsp','boards','openmote-cc2538'), + os.path.join('#','bsp','boards','openmote-cc2538','headers'), + os.path.join('#','bsp','boards','openmote-cc2538','source'), + os.path.join('#','bsp','chips','adxl346'), + os.path.join('#','bsp','chips','max44009'), + os.path.join('#','bsp','chips','sht21'), + ], +) + +board = localEnv.Object(source=source) + adxl346 + max44009 + sht21 + +Return('board') diff --git a/bsp/boards/mimsy2-cc2538/accel_mimsy.c b/bsp/boards/mimsy2-cc2538/accel_mimsy.c index 5b660a1a97..55d0b60527 100644 --- a/bsp/boards/mimsy2-cc2538/accel_mimsy.c +++ b/bsp/boards/mimsy2-cc2538/accel_mimsy.c @@ -1,6 +1,6 @@ #include "i2c_mimsy.h" #include "i2c.h" -#include "MPU9250_RegisterMap.h" +#include "headers/MPU9250_RegisterMap.h" #include "flash_mimsy.h" //TODO: mive imu_data type to a new mimsy.h file #include "gptimer.h" #include "hw_gptimer.h" diff --git a/bsp/boards/mimsy2-cc2538/board.c b/bsp/boards/mimsy2-cc2538/board.c index 7a15a8f46b..9195d655a5 100644 --- a/bsp/boards/mimsy2-cc2538/board.c +++ b/bsp/boards/mimsy2-cc2538/board.c @@ -1,315 +1,319 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "board" bsp module. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "board.h" -#include "debugpins.h" -#include "i2c.h" -#include "leds.h" -#include "radio.h" -#include "sensors.h" -#include "sctimer.h" -#include "uart.h" -#include "cryptoengine.h" -#include "uart_mimsy.h" - -//=========================== variables ======================================= - -#define BSP_BUTTON_BASE ( GPIO_C_BASE ) -#define BSP_BUTTON_USER ( GPIO_PIN_3 ) - -#ifdef REVA1 //Rev.A1 uses SF23 cc2538 which start at diffferent location - #define CC2538_FLASH_ADDRESS ( 0x0023F800 ) -#else - #define CC2538_FLASH_ADDRESS ( 0x0027F800 ) -#endif -//=========================== prototypes ====================================== - -void board_timer_init(void); -uint32_t board_timer_get(void); -bool board_timer_expired(uint32_t future); - -static void clock_init(void); -static void gpio_init(void); -static void button_init(void); - -static void SysCtrlDeepSleepSetting(void); -static void SysCtrlSleepSetting(void); -static void SysCtrlRunSetting(void); -static void SysCtrlWakeupSetting(void); - -static void GPIO_C_Handler(void); - -bool user_button_initialized; - -//=========================== main ============================================ - -extern int mote_main(void); - -int main(void) { - return mote_main(); -} - -//=========================== public ========================================== - -void board_init(void) { - user_button_initialized = FALSE; - - gpio_init(); - clock_init(); - //board_timer_init(); changed for inchwrom code - //leds_init(); changed for incworm code - //debugpins_init(); changed for inchworm code - //button_init(); - //sctimer_init(); changed for inchworm code - //uart_init(); changed for inchwrom code - //radio_init(); changed for incwhorm code - //i2c_init(); changed for inchworm code - // sensors_init(); - // cryptoengine_init(); -} - -/** - * Puts the board to sleep - */ -void board_sleep(void) { - SysCtrlPowerModeSet(SYS_CTRL_PM_NOACTION); - SysCtrlSleep(); -} - -/** - * Timer runs at 32 MHz and is 32-bit wide - * The timer is divided by 32, whichs gives a 1 microsecond ticks - */ -void board_timer_init(void) { - // Configure the timer - TimerConfigure(GPTIMER2_BASE, GPTIMER_CFG_PERIODIC_UP); - - // Enable the timer - TimerEnable(GPTIMER2_BASE, GPTIMER_BOTH); -} - -/** - * Returns the current value of the timer - * The timer is divided by 32, whichs gives a 1 microsecond ticks - */ -uint32_t board_timer_get(void) { - uint32_t current; - - current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; - - return current; -} - -/** - * Returns true if the timer has expired - * The timer is divided by 32, whichs gives a 1 microsecond ticks - */ -bool board_timer_expired(uint32_t future) { - uint32_t current; - int32_t remaining; - - current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; - - remaining = (int32_t) (future - current); - - if (remaining > 0) { - return false; - } else { - return true; - } -} - -/** - * Resets the board - */ -void board_reset(void) { - SysCtrlReset(); -} - -//=========================== private ========================================= - -static void gpio_init(void) { - /* Set GPIOs as output */ - GPIOPinTypeGPIOOutput(GPIO_A_BASE, 0xFF); - GPIOPinTypeGPIOOutput(GPIO_B_BASE, 0xFF); - GPIOPinTypeGPIOOutput(GPIO_C_BASE, 0xFF); - GPIOPinTypeGPIOOutput(GPIO_D_BASE, 0xFF); - - /* Initialize GPIOs to low */ - GPIOPinWrite(GPIO_A_BASE, 0xFF, 0x00); - GPIOPinWrite(GPIO_B_BASE, 0xFF, 0x00); - GPIOPinWrite(GPIO_C_BASE, 0xFF, 0x00); - GPIOPinWrite(GPIO_D_BASE, 0xFF, 0x00); -} - -static void clock_init(void) { - /* Disable global interrupts */ - bool bIntDisabled = IntMasterDisable(); - - /* Configure the 32 kHz pins, PD6 and PD7, for crystal operation */ - /* By default they are configured as GPIOs */ - GPIODirModeSet(GPIO_D_BASE, 0x40, GPIO_DIR_MODE_IN); - GPIODirModeSet(GPIO_D_BASE, 0x80, GPIO_DIR_MODE_IN); - IOCPadConfigSet(GPIO_D_BASE, 0x40, IOC_OVERRIDE_ANA); - IOCPadConfigSet(GPIO_D_BASE, 0x80, IOC_OVERRIDE_ANA); - - /* Set the real-time clock to use the 32 kHz external crystal */ - /* Set the system clock to use the external 32 MHz crystal */ - /* Set the system clock to 32 MHz */ - SysCtrlClockSet(true, false, SYS_CTRL_SYSDIV_32MHZ); - - /* Set the IO clock to operate at 16 MHz */ - /* This way peripherals can run while the system clock is gated */ - SysCtrlIOClockSet(SYS_CTRL_SYSDIV_16MHZ); - - /* Wait until the selected clock configuration is stable */ - while (!((HWREG(SYS_CTRL_CLOCK_STA)) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); - - /* Define what peripherals run in each mode */ - SysCtrlRunSetting(); - SysCtrlSleepSetting(); - SysCtrlDeepSleepSetting(); - SysCtrlWakeupSetting(); - /* Re-enable interrupt if initially enabled */ - if (!bIntDisabled) { - IntMasterEnable(); - } -} - -/** - * Configures the user button as input source - */ -static void button_init(void) { - volatile uint32_t i; - - /* Delay to avoid pin floating problems */ - for (i = 0xFFFF; i != 0; i--); - - GPIOPinIntDisable(BSP_BUTTON_BASE, BSP_BUTTON_USER); - GPIOPinIntClear(BSP_BUTTON_BASE, BSP_BUTTON_USER); - - /* The button is an input GPIO on falling edge */ - GPIOPinTypeGPIOInput(BSP_BUTTON_BASE, BSP_BUTTON_USER); - GPIOIntTypeSet(BSP_BUTTON_BASE, BSP_BUTTON_USER, GPIO_FALLING_EDGE); - - /* Register the interrupt */ - GPIOPortIntRegister(BSP_BUTTON_BASE, GPIO_C_Handler); - - /* Clear and enable the interrupt */ - GPIOPinIntClear(BSP_BUTTON_BASE, BSP_BUTTON_USER); - GPIOPinIntEnable(BSP_BUTTON_BASE, BSP_BUTTON_USER); - user_button_initialized = TRUE; -} - -static void SysCtrlRunSetting(void) { - /* Disable General Purpose Timers 0, 1, 2, 3 when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT0); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT1); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT3); - - /* Disable SSI 0, 1 when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI0); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI1); - - /* Disable UART1 when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_UART1); - - /* Disable I2C, AES and PKA when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_I2C); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_PKA); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_AES); - - /* Enable UART0 and RFC when running */ - SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT2); - SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_UART0); - SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_RFC); -} - -static void SysCtrlSleepSetting(void) { - /* Disable General Purpose Timers 0, 1, 2, 3 during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT0); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT1); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT3); - - /* Disable SSI 0, 1 during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI0); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI1); - - /* Disable UART 0, 1 during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_UART1); - - /* Disable I2C, PKA, AES during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_I2C); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_PKA); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_AES); - - /* Enable UART and RFC during sleep */ - SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_GPT2); - SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_UART0); - SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_RFC); -} - -static void SysCtrlDeepSleepSetting(void) { - /* Disable General Purpose Timers 0, 1, 2, 3 during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT0); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT1); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT2); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT3); - - /* Disable SSI 0, 1 during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI0); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI1); - - /* Disable UART 0, 1 during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART0); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART1); - - /* Disable I2C, PKA, AES during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_I2C); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_PKA); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_AES); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_RFC); -} - -static void SysCtrlWakeupSetting(void) { - /* Allow the SMTimer to wake up the processor */ - GPIOIntWakeupEnable(GPIO_IWE_SM_TIMER); -} - -//=========================== interrupt handlers ============================== - -/** - * GPIO_C interrupt handler. User button is GPIO_C_3 - * Erases a Flash sector to trigger the bootloader backdoor - */ -static void GPIO_C_Handler(void) { - if (!user_button_initialized) return; - /* Disable the interrupts */ - IntMasterDisable(); - leds_all_off(); - - /* Eras the CCA flash page */ - FlashMainPageErase(CC2538_FLASH_ADDRESS); - - leds_circular_shift(); - - /* Reset the board */ - SysCtrlReset(); -} +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "board" bsp module. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include "debugpins.h" +#include "i2c.h" +#include "leds.h" +#include "radio.h" +#include "sensors.h" +#include "sctimer.h" +#include "uart.h" +#include "cryptoengine.h" +#include "pwm.h" + +//=========================== variables ======================================= + +#define BSP_BUTTON_BASE ( GPIO_C_BASE ) +#define BSP_BUTTON_USER ( GPIO_PIN_3 ) + +#ifdef REVA1 //Rev.A1 uses SF23 cc2538 which start at diffferent location + #define CC2538_FLASH_ADDRESS ( 0x0023F800 ) +#else + #define CC2538_FLASH_ADDRESS ( 0x0027F800 ) +#endif +//=========================== prototypes ====================================== + +void board_timer_init(void); +uint32_t board_timer_get(void); +bool board_timer_expired(uint32_t future); + +static void clock_init(void); +static void gpio_init(void); +static void button_init(void); + +static void SysCtrlDeepSleepSetting(void); +static void SysCtrlSleepSetting(void); +static void SysCtrlRunSetting(void); +static void SysCtrlWakeupSetting(void); + +static void GPIO_C_Handler(void); + +bool user_button_initialized; + +//=========================== main ============================================ + +extern int mote_main(void); + +int main(void) { + return mote_main(); +} + +//=========================== public ========================================== + +void board_init(void) { + user_button_initialized = FALSE; + + gpio_init(); + clock_init(); + board_timer_init(); + leds_init(); + debugpins_init(); + button_init(); + sctimer_init(); + uart_init(); + radio_init(); + i2c_init(); + sensors_init(); + cryptoengine_init(); + pwm_init(); +} + +/** + * Puts the board to sleep + */ +void board_sleep(void) { + SysCtrlPowerModeSet(SYS_CTRL_PM_NOACTION); + SysCtrlSleep(); +} + +/** + * Timer runs at 32 MHz and is 32-bit wide + * The timer is divided by 32, whichs gives a 1 microsecond ticks + */ +void board_timer_init(void) { + // Configure the timer + TimerConfigure(GPTIMER2_BASE, GPTIMER_CFG_PERIODIC_UP); + + // Enable the timer + TimerEnable(GPTIMER2_BASE, GPTIMER_BOTH); +} + +/** + * Returns the current value of the timer + * The timer is divided by 32, whichs gives a 1 microsecond ticks + */ +uint32_t board_timer_get(void) { + uint32_t current; + + current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; + + return current; +} + +/** + * Returns true if the timer has expired + * The timer is divided by 32, whichs gives a 1 microsecond ticks + */ +bool board_timer_expired(uint32_t future) { + uint32_t current; + int32_t remaining; + + current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; + + remaining = (int32_t) (future - current); + + if (remaining > 0) { + return false; + } else { + return true; + } +} + +/** + * Resets the board + */ +void board_reset(void) { + SysCtrlReset(); +} + +//=========================== private ========================================= + +static void gpio_init(void) { + /* Set GPIOs as output */ + GPIOPinTypeGPIOOutput(GPIO_A_BASE, 0xFF); + GPIOPinTypeGPIOOutput(GPIO_B_BASE, 0xFF); + GPIOPinTypeGPIOOutput(GPIO_C_BASE, 0xFF); + GPIOPinTypeGPIOOutput(GPIO_D_BASE, 0xFF); + + /* Initialize GPIOs to low */ + GPIOPinWrite(GPIO_A_BASE, 0xFF, 0x00); + GPIOPinWrite(GPIO_B_BASE, 0xFF, 0x00); + GPIOPinWrite(GPIO_C_BASE, 0xFF, 0x00); + GPIOPinWrite(GPIO_D_BASE, 0xFF, 0x00); +} + +static void clock_init(void) { + /* Disable global interrupts */ + bool bIntDisabled = IntMasterDisable(); + + /* Configure the 32 kHz pins, PD6 and PD7, for crystal operation */ + /* By default they are configured as GPIOs */ + GPIODirModeSet(GPIO_D_BASE, 0x40, GPIO_DIR_MODE_IN); + GPIODirModeSet(GPIO_D_BASE, 0x80, GPIO_DIR_MODE_IN); + IOCPadConfigSet(GPIO_D_BASE, 0x40, IOC_OVERRIDE_ANA); + IOCPadConfigSet(GPIO_D_BASE, 0x80, IOC_OVERRIDE_ANA); + + /* Set the real-time clock to use the 32 kHz external crystal */ + /* Set the system clock to use the external 32 MHz crystal */ + /* Set the system clock to 32 MHz */ + SysCtrlClockSet(true, false, SYS_CTRL_SYSDIV_32MHZ); + + /* Set the IO clock to operate at 16 MHz */ + /* This way peripherals can run while the system clock is gated */ + SysCtrlIOClockSet(SYS_CTRL_SYSDIV_16MHZ); + + /* Wait until the selected clock configuration is stable */ + while (!((HWREG(SYS_CTRL_CLOCK_STA)) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); + + /* Define what peripherals run in each mode */ + SysCtrlRunSetting(); + SysCtrlSleepSetting(); + SysCtrlDeepSleepSetting(); + SysCtrlWakeupSetting(); + + /* Re-enable interrupt if initially enabled */ + if (!bIntDisabled) { + IntMasterEnable(); + } +} + +/** + * Configures the user button as input source + */ +static void button_init(void) { + volatile uint32_t i; + + /* Delay to avoid pin floating problems */ + for (i = 0xFFFF; i != 0; i--); + + GPIOPinIntDisable(BSP_BUTTON_BASE, BSP_BUTTON_USER); + GPIOPinIntClear(BSP_BUTTON_BASE, BSP_BUTTON_USER); + + /* The button is an input GPIO on falling edge */ + GPIOPinTypeGPIOInput(BSP_BUTTON_BASE, BSP_BUTTON_USER); + GPIOIntTypeSet(BSP_BUTTON_BASE, BSP_BUTTON_USER, GPIO_FALLING_EDGE); + + /* Register the interrupt */ + GPIOPortIntRegister(BSP_BUTTON_BASE, GPIO_C_Handler); + + /* Clear and enable the interrupt */ + GPIOPinIntClear(BSP_BUTTON_BASE, BSP_BUTTON_USER); + GPIOPinIntEnable(BSP_BUTTON_BASE, BSP_BUTTON_USER); + user_button_initialized = TRUE; +} + +static void SysCtrlRunSetting(void) { + /* Disable General Purpose Timers 0, 1, 2, 3 when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT3); + + /* Disable SSI 0, 1 when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI1); + + /* Disable UART1 when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_UART1); + + /* Disable I2C, AES and PKA when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_AES); + + /* Enable UART0 and RFC when running */ + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT3); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_RFC); +} + +static void SysCtrlSleepSetting(void) { + /* Disable General Purpose Timers 0, 1, 2, 3 during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT3); + + /* Disable SSI 0, 1 during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI1); + + /* Disable UART 0, 1 during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_UART1); + + /* Disable I2C, PKA, AES during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_AES); + + /* Enable UART and RFC during sleep */ + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_GPT3); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_RFC); +} + +static void SysCtrlDeepSleepSetting(void) { + /* Disable General Purpose Timers 0, 1, 2, 3 during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT3); + + /* Disable SSI 0, 1 during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI1); + + /* Disable UART 0, 1 during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART1); + + /* Disable I2C, PKA, AES during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_AES); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_RFC); +} + +static void SysCtrlWakeupSetting(void) { + /* Allow the SMTimer to wake up the processor */ + GPIOIntWakeupEnable(GPIO_IWE_SM_TIMER); +} + +//=========================== interrupt handlers ============================== + +/** + * GPIO_C interrupt handler. User button is GPIO_C_3 + * Erases a Flash sector to trigger the bootloader backdoor + */ +static void GPIO_C_Handler(void) { + if (!user_button_initialized) return; + /* Disable the interrupts */ + IntMasterDisable(); + leds_all_off(); + + /* Eras the CCA flash page */ + FlashMainPageErase(CC2538_FLASH_ADDRESS); + + leds_circular_shift(); + + /* Reset the board */ + SysCtrlReset(); +} diff --git a/bsp/boards/mimsy2-cc2538/board_info.h b/bsp/boards/mimsy2-cc2538/board_info.h index 74b7ce551c..d7f058937f 100644 --- a/bsp/boards/mimsy2-cc2538/board_info.h +++ b/bsp/boards/mimsy2-cc2538/board_info.h @@ -1,117 +1,119 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Modified: Tengfei Chang (tengfei.chang@eecs.berkeley.edu) - * Date: July 2013 - * Description: CC2538-specific board information bsp module. - */ - -#ifndef __BOARD_INFO_H -#define __BOARD_INFO_H - -#include -#include - -#include -#include - -//=========================== defines ========================================= - -//===== interrupt state - -#define INTERRUPT_DECLARATION() -#define DISABLE_INTERRUPTS() IntMasterDisable() - -#define ENABLE_INTERRUPTS() IntMasterEnable() - -//===== timer - -#define PORT_TIMER_WIDTH uint32_t -#define PORT_RADIOTIMER_WIDTH uint32_t - -#define PORT_SIGNED_INT_WIDTH int32_t -#define PORT_TICS_PER_MS 33 - -// on GINA, we use the comparatorA interrupt for the OS -#define SCHEDULER_WAKEUP() -#define SCHEDULER_ENABLE_INTERRUPT() - -// this is a workaround from the fact that the interrupt pin for the GINA radio -// is not connected to a pin on the MSP which allows time capture. -#define CAPTURE_TIME() - -/* sleep timer interrupt */ -#define HAL_INT_PRIOR_ST (4 << 5) -/* MAC interrupts */ -#define HAL_INT_PRIOR_MAC (4 << 5) -/* UART interrupt */ -#define HAL_INT_PRIOR_UART (5 << 5) - -//===== pinout - -// [P4.7] radio SLP_TR_CNTL -#define PORT_PIN_RADIO_SLP_TR_CNTL_HIGH() -#define PORT_PIN_RADIO_SLP_TR_CNTL_LOW() -// radio reset line -// on cc2538, the /RST line is not connected to the uC -#define PORT_PIN_RADIO_RESET_HIGH() // nothing -#define PORT_PIN_RADIO_RESET_LOW() // nothing - -//===== IEEE802154E timing - -#define SLOTDURATION_10MS // by default, we use 10ms time slot - -#ifdef SLOTDURATION_10MS -// time-slot related -#define PORT_TsSlotDuration 328 // counter counts one extra count, see datasheet -// execution speed related -#define PORT_maxTxDataPrepare 10 // 305us (measured 82us) -#define PORT_maxRxAckPrepare 10 // 305us (measured 83us) -#define PORT_maxRxDataPrepare 4 // 122us (measured 22us) -#define PORT_maxTxAckPrepare 10 // 122us (measured 94us) -// radio speed related -#ifdef L2_SECURITY_ACTIVE -#define PORT_delayTx 14 // 366us (measured xxxus) -#else -#define PORT_delayTx 12 // 366us (measured xxxus) -#endif -#define PORT_delayRx 0 // 0us (can not measure) -// radio watchdog -#else -// time-slot related -#define PORT_TsSlotDuration 492 // counter counts one extra count, see datasheet -// execution speed related -#define PORT_maxTxDataPrepare 66 // 2014us (measured 746us) -#define PORT_maxRxAckPrepare 10 // 305us (measured 83us) -#define PORT_maxRxDataPrepare 33 // 1007us (measured 84us) -#define PORT_maxTxAckPrepare 22 // 305us (measured 219us) -// radio speed related -#define PORT_delayTx 12 // 214us (measured 219us) -#define PORT_delayRx 0 // 0us (can not measure) -// radio watchdog -#endif - -//===== adaptive_sync accuracy - -#define SYNC_ACCURACY 1 // ticks - -//===== per-board number of sensors - -#define NUMSENSORS 7 - -//=========================== typedef ======================================== - -//=========================== variables ======================================= - -static const uint8_t rreg_uriquery[] = "h=ucb"; -static const uint8_t infoBoardname[] = "CC2538"; -static const uint8_t infouCName[] = "CC2538"; -static const uint8_t infoRadioName[] = "CC2538 SoC"; - -//=========================== prototypes ====================================== - -//=========================== public ========================================== - -//=========================== private ========================================= - -#endif +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Modified: Tengfei Chang (tengfei.chang@eecs.berkeley.edu) + * Date: July 2013 + * Description: CC2538-specific board information bsp module. + */ + +#ifndef __BOARD_INFO_H +#define __BOARD_INFO_H + +#include +#include + +#include +#include + +//=========================== defines ========================================= + +//===== interrupt state + +#define INTERRUPT_DECLARATION() +#define DISABLE_INTERRUPTS() IntMasterDisable() + +#define ENABLE_INTERRUPTS() IntMasterEnable() + +//===== timer + +#define PORT_TIMER_WIDTH uint32_t +#define PORT_RADIOTIMER_WIDTH uint32_t + +#define PORT_SIGNED_INT_WIDTH int32_t +#define PORT_TICS_PER_MS 33 + +// on GINA, we use the comparatorA interrupt for the OS +#define SCHEDULER_WAKEUP() +#define SCHEDULER_ENABLE_INTERRUPT() + +// this is a workaround from the fact that the interrupt pin for the GINA radio +// is not connected to a pin on the MSP which allows time capture. +#define CAPTURE_TIME() + +/* sleep timer interrupt */ +#define HAL_INT_PRIOR_ST (4 << 5) +/* MAC interrupts */ +#define HAL_INT_PRIOR_MAC (4 << 5) +/* UART interrupt */ +#define HAL_INT_PRIOR_UART (5 << 5) + +//===== pinout + +// [P4.7] radio SLP_TR_CNTL +#define PORT_PIN_RADIO_SLP_TR_CNTL_HIGH() +#define PORT_PIN_RADIO_SLP_TR_CNTL_LOW() +// radio reset line +// on cc2538, the /RST line is not connected to the uC +#define PORT_PIN_RADIO_RESET_HIGH() // nothing +#define PORT_PIN_RADIO_RESET_LOW() // nothing + +//===== IEEE802154E timing + +#define SLOTDURATION 10 // in miliseconds + +#if SLOTDURATION==10 + // time-slot related + #define PORT_TsSlotDuration 328 // counter counts one extra count, see datasheet + // execution speed related + #define PORT_maxTxDataPrepare 10 // 305us (measured 82us) + #define PORT_maxRxAckPrepare 10 // 305us (measured 83us) + #define PORT_maxRxDataPrepare 4 // 122us (measured 22us) + #define PORT_maxTxAckPrepare 10 // 122us (measured 94us) + // radio speed related + #ifdef L2_SECURITY_ACTIVE + #define PORT_delayTx 14 // 366us (measured xxxus) + #else + #define PORT_delayTx 12 // 366us (measured xxxus) + #endif + #define PORT_delayRx 0 // 0us (can not measure) + // radio watchdog +#endif + +#if SLOTDURATION==15 + // time-slot related + #define PORT_TsSlotDuration 492 // counter counts one extra count, see datasheet + // execution speed related + #define PORT_maxTxDataPrepare 66 // 2014us (measured 746us) + #define PORT_maxRxAckPrepare 10 // 305us (measured 83us) + #define PORT_maxRxDataPrepare 33 // 1007us (measured 84us) + #define PORT_maxTxAckPrepare 22 // 305us (measured 219us) + // radio speed related + #define PORT_delayTx 12 // 214us (measured 219us) + #define PORT_delayRx 0 // 0us (can not measure) + // radio watchdog +#endif + +//===== adaptive_sync accuracy + +#define SYNC_ACCURACY 1 // ticks + +//===== per-board number of sensors + +#define NUMSENSORS 7 + +//=========================== typedef ======================================== + +//=========================== variables ======================================= + +static const uint8_t rreg_uriquery[] = "h=ucb"; +static const uint8_t infoBoardname[] = "CC2538"; +static const uint8_t infouCName[] = "CC2538"; +static const uint8_t infoRadioName[] = "CC2538 SoC"; + +//=========================== prototypes ====================================== + +//=========================== public ========================================== + +//=========================== private ========================================= + +#endif diff --git a/bsp/boards/mimsy2-cc2538/cc2538rf.h b/bsp/boards/mimsy2-cc2538/cc2538rf.h index 82b05c2bb1..387a9fe0fc 100644 --- a/bsp/boards/mimsy2-cc2538/cc2538rf.h +++ b/bsp/boards/mimsy2-cc2538/cc2538rf.h @@ -1,93 +1,93 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "radio" bsp module. - */ - -#ifndef CC2538RF_H_ -#define CC2538RF_H_ - -#include -#include - -/*--------------------------------------------------------------------------- - * RF Config - *---------------------------------------------------------------------------*/ -/* Constants */ -#define CC2538_RF_CCA_THRES_USER_GUIDE 0xF8 -#define CC2538_RF_TX_POWER_RECOMMENDED 0xD5 /* TODO: Check value */ -#define CC2538_RF_CHANNEL_MIN 11 //poipoi -- in fact is sending on 0x17 check that. -#define CC2538_RF_CHANNEL_MAX 26 -#define CC2538_RF_CHANNEL_SPACING 5 -#define CC2538_RF_MAX_PACKET_LEN 127 -#define CC2538_RF_MIN_PACKET_LEN 4 -#define CC2538_RF_CCA_CLEAR 1 -#define CC2538_RF_CCA_BUSY 0 -/*---------------------------------------------------------------------------*/ -#ifdef CC2538_RF_CONF_TX_POWER -#define CC2538_RF_TX_POWER CC2538_RF_CONF_TX_POWER -#else -#define CC2538_RF_TX_POWER CC2538_RF_TX_POWER_RECOMMENDED -#endif /* CC2538_RF_CONF_TX_POWER */ - - -#ifdef CC2538_RF_CONF_CHANNEL -#define CC2538_RF_CHANNEL CC2538_RF_CONF_CHANNEL -#else -#define CC2538_RF_CHANNEL CC2538_RF_CHANNEL_MIN -#endif /* CC2538_RF_CONF_CHANNEL */ - -#ifdef CC2538_RF_CONF_AUTOACK -#define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK -#else -#define CC2538_RF_AUTOACK 1 -#endif /* CC2538_RF_CONF_AUTOACK */ -/*--------------------------------------------------------------------------- - * Command Strobe Processor - *---------------------------------------------------------------------------*/ -/* OPCODES */ -#define CC2538_RF_CSP_OP_ISRXON 0xE3 -#define CC2538_RF_CSP_OP_ISTXON 0xE9 -#define CC2538_RF_CSP_OP_ISTXONCCA 0xEA -#define CC2538_RF_CSP_OP_ISRFOFF 0xEF -#define CC2538_RF_CSP_OP_ISFLUSHRX 0xED -#define CC2538_RF_CSP_OP_ISFLUSHTX 0xEE - -/** - * \brief Send an RX ON command strobe to the CSP - */ -#define CC2538_RF_CSP_ISRXON() \ - do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRXON; } while(0) - -/** - * \brief Send a TX ON command strobe to the CSP - */ -#define CC2538_RF_CSP_ISTXON() \ - do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISTXON; } while(0) - -/** - * \brief Send a RF OFF command strobe to the CSP - */ -#define CC2538_RF_CSP_ISRFOFF() \ - do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRFOFF; } while(0) - -/** - * \brief Flush the RX FIFO - */ -#define CC2538_RF_CSP_ISFLUSHRX() do { \ - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ -} while(0) - -/** - * \brief Flush the TX FIFO - */ -#define CC2538_RF_CSP_ISFLUSHTX() do { \ - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ -} while(0) -/*---------------------------------------------------------------------------*/ - - -#endif /* CC2538RF_H_ */ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "radio" bsp module. + */ + +#ifndef CC2538RF_H_ +#define CC2538RF_H_ + +#include +#include + +/*--------------------------------------------------------------------------- + * RF Config + *---------------------------------------------------------------------------*/ +/* Constants */ +#define CC2538_RF_CCA_THRES_USER_GUIDE 0xF8 +#define CC2538_RF_TX_POWER_RECOMMENDED 0xD5 /* TODO: Check value */ +#define CC2538_RF_CHANNEL_MIN 11 //poipoi -- in fact is sending on 0x17 check that. +#define CC2538_RF_CHANNEL_MAX 26 +#define CC2538_RF_CHANNEL_SPACING 5 +#define CC2538_RF_MAX_PACKET_LEN 127 +#define CC2538_RF_MIN_PACKET_LEN 4 +#define CC2538_RF_CCA_CLEAR 1 +#define CC2538_RF_CCA_BUSY 0 +/*---------------------------------------------------------------------------*/ +#ifdef CC2538_RF_CONF_TX_POWER +#define CC2538_RF_TX_POWER CC2538_RF_CONF_TX_POWER +#else +#define CC2538_RF_TX_POWER CC2538_RF_TX_POWER_RECOMMENDED +#endif /* CC2538_RF_CONF_TX_POWER */ + + +#ifdef CC2538_RF_CONF_CHANNEL +#define CC2538_RF_CHANNEL CC2538_RF_CONF_CHANNEL +#else +#define CC2538_RF_CHANNEL CC2538_RF_CHANNEL_MIN +#endif /* CC2538_RF_CONF_CHANNEL */ + +#ifdef CC2538_RF_CONF_AUTOACK +#define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK +#else +#define CC2538_RF_AUTOACK 1 +#endif /* CC2538_RF_CONF_AUTOACK */ +/*--------------------------------------------------------------------------- + * Command Strobe Processor + *---------------------------------------------------------------------------*/ +/* OPCODES */ +#define CC2538_RF_CSP_OP_ISRXON 0xE3 +#define CC2538_RF_CSP_OP_ISTXON 0xE9 +#define CC2538_RF_CSP_OP_ISTXONCCA 0xEA +#define CC2538_RF_CSP_OP_ISRFOFF 0xEF +#define CC2538_RF_CSP_OP_ISFLUSHRX 0xED +#define CC2538_RF_CSP_OP_ISFLUSHTX 0xEE + +/** + * \brief Send an RX ON command strobe to the CSP + */ +#define CC2538_RF_CSP_ISRXON() \ + do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRXON; } while(0) + +/** + * \brief Send a TX ON command strobe to the CSP + */ +#define CC2538_RF_CSP_ISTXON() \ + do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISTXON; } while(0) + +/** + * \brief Send a RF OFF command strobe to the CSP + */ +#define CC2538_RF_CSP_ISRFOFF() \ + do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRFOFF; } while(0) + +/** + * \brief Flush the RX FIFO + */ +#define CC2538_RF_CSP_ISFLUSHRX() do { \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ +} while(0) + +/** + * \brief Flush the TX FIFO + */ +#define CC2538_RF_CSP_ISFLUSHTX() do { \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ +} while(0) +/*---------------------------------------------------------------------------*/ + + +#endif /* CC2538RF_H_ */ diff --git a/bsp/boards/mimsy2-cc2538/cc2538sf23.lds b/bsp/boards/mimsy2-cc2538/cc2538sf23.lds index 57226ddde2..fe490d053c 100644 --- a/bsp/boards/mimsy2-cc2538/cc2538sf23.lds +++ b/bsp/boards/mimsy2-cc2538/cc2538sf23.lds @@ -1,62 +1,62 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific linker script configuration file. - */ - -/** - * Indicate to the linker the entry point. - */ -ENTRY(ResetISR) - -/** - * RAM is 16 KB retention and 16 KB no retention - * NON-RETENTION RAM starts at 0x20000000 with length 0x00004000 - * RETENTION RAM starts at 0x20004000 with length 0x00004000 - */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 0x0003FFD4 - FLASH_CCA (RX) : ORIGIN = 0x0023FFD4, LENGTH = 12 - SRAM (RWX) : ORIGIN = 0x20004000, LENGTH = 0x00004000 -} - -SECTIONS -{ - .text : - { - _text = .; - KEEP(*(.vectors)) - *(.text*) - *(.rodata*) - _etext = .; - } > FLASH=0 - - .data : - AT (ADDR (.text) + SIZEOF (.text)) - { - _data = .; - *(vtable) - *(.data*) - _edata = .; - } > SRAM - - .ARM.exidx : - { - *(.ARM.exidx*) - } > FLASH - - .bss : - { - _bss = .; - *(.bss*) - *(COMMON) - _ebss = .; - } > SRAM - - .flashcca : - { - KEEP(*(.flashcca)) - } > FLASH_CCA -} +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific linker script configuration file. + */ + +/** + * Indicate to the linker the entry point. + */ +ENTRY(ResetISR) + +/** + * RAM is 16 KB retention and 16 KB no retention + * NON-RETENTION RAM starts at 0x20000000 with length 0x00004000 + * RETENTION RAM starts at 0x20004000 with length 0x00004000 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 0x0003FFD4 + FLASH_CCA (RX) : ORIGIN = 0x0023FFD4, LENGTH = 12 + SRAM (RWX) : ORIGIN = 0x20004000, LENGTH = 0x00004000 +} + +SECTIONS +{ + .text : + { + _text = .; + KEEP(*(.vectors)) + *(.text*) + *(.rodata*) + _etext = .; + } > FLASH=0 + + .data : + AT (ADDR (.text) + SIZEOF (.text)) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > SRAM + + .ARM.exidx : + { + *(.ARM.exidx*) + } > FLASH + + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > SRAM + + .flashcca : + { + KEEP(*(.flashcca)) + } > FLASH_CCA +} diff --git a/bsp/boards/mimsy2-cc2538/cc2538sf53.lds b/bsp/boards/mimsy2-cc2538/cc2538sf53.lds index d38e7f2a67..0bb0ffce25 100644 --- a/bsp/boards/mimsy2-cc2538/cc2538sf53.lds +++ b/bsp/boards/mimsy2-cc2538/cc2538sf53.lds @@ -1,62 +1,62 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific linker script configuration file. - */ - -/** - * Indicate to the linker the entry point. - */ -ENTRY(ResetISR) - -/** - * RAM is 16 KB retention and 16 KB no retention - * NON-RETENTION RAM starts at 0x20000000 with length 0x00004000 - * RETENTION RAM starts at 0x20004000 with length 0x00004000 - */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 0x0007FFD4 - FLASH_CCA (RX) : ORIGIN = 0x0027FFD4, LENGTH = 12 - SRAM (RWX) : ORIGIN = 0x20004000, LENGTH = 0x00004000 -} - -SECTIONS -{ - .text : - { - _text = .; - KEEP(*(.vectors)) - *(.text*) - *(.rodata*) - _etext = .; - } > FLASH=0 - - .data : - AT (ADDR (.text) + SIZEOF (.text)) - { - _data = .; - *(vtable) - *(.data*) - _edata = .; - } > SRAM - - .ARM.exidx : - { - *(.ARM.exidx*) - } > SRAM - - .bss : - { - _bss = .; - *(.bss*) - *(COMMON) - _ebss = .; - } > SRAM - - .flashcca : - { - KEEP(*(.flashcca)) - } > FLASH_CCA -} +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific linker script configuration file. + */ + +/** + * Indicate to the linker the entry point. + */ +ENTRY(ResetISR) + +/** + * RAM is 16 KB retention and 16 KB no retention + * NON-RETENTION RAM starts at 0x20000000 with length 0x00004000 + * RETENTION RAM starts at 0x20004000 with length 0x00004000 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 0x0007FFD4 + FLASH_CCA (RX) : ORIGIN = 0x0027FFD4, LENGTH = 12 + SRAM (RWX) : ORIGIN = 0x20004000, LENGTH = 0x00004000 +} + +SECTIONS +{ + .text : + { + _text = .; + KEEP(*(.vectors)) + *(.text*) + *(.rodata*) + _etext = .; + } > FLASH=0 + + .data : + AT (ADDR (.text) + SIZEOF (.text)) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > SRAM + + .ARM.exidx : + { + *(.ARM.exidx*) + } > FLASH + + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > SRAM + + .flashcca : + { + KEEP(*(.flashcca)) + } > FLASH_CCA +} diff --git a/bsp/boards/mimsy2-cc2538/debugpins.c b/bsp/boards/mimsy2-cc2538/debugpins.c index 2ef9e544e0..3245ed81ed 100644 --- a/bsp/boards/mimsy2-cc2538/debugpins.c +++ b/bsp/boards/mimsy2-cc2538/debugpins.c @@ -1,135 +1,128 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "debugpins" bsp module. - */ - -#include -#include - -#include - -#include "board.h" -#include "debugpins.h" - -//=========================== defines ========================================= -// Board dbPINS defines -#define BSP_PINA_BASE GPIO_A_BASE -#define BSP_PIND_BASE GPIO_D_BASE -#define BSP_PINC_BASE GPIO_C_BASE - -#define BSP_PINA_4 GPIO_PIN_4 //!< PA4 -- frame -RF1.5 -#define BSP_PINA_5 GPIO_PIN_5 //!< PA5 -- isr -RF1.11 - -#define BSP_PIND_3 GPIO_PIN_3 //!< PD3 -- slot -RF1.6 -#define BSP_PIND_2 GPIO_PIN_2 //!< PD2 -- fsm -RF1.8 -#define BSP_PIND_1 GPIO_PIN_1 //!< PD1 -- task -RF1.10 -#define BSP_PIND_0 GPIO_PIN_0 //!< PD0 -- radio -RF1-12 - -#define BSP_PINC_5 GPIO_PIN_5 //!< PD3 -- slot -RF1.6 -#define BSP_PINC_3 GPIO_PIN_3 //!< PD2 -- fsm -RF1.8 -#define BSP_PINC_2 GPIO_PIN_2 //!< PD1 -- task -RF1.10 -#define BSP_PINC_1 GPIO_PIN_1 //!< PD0 -- radio -RF1-12 - -//=========================== variables ======================================= - -//=========================== prototypes ====================================== - -void bspDBpinToggle(uint32_t base,uint8_t ui8Pin); - -//=========================== public ========================================== - -void debugpins_init() { - GPIOPinTypeGPIOOutput(BSP_PINA_BASE, BSP_PINA_4 | BSP_PINA_5); - GPIOPinTypeGPIOOutput(BSP_PINC_BASE, BSP_PINC_3 | BSP_PINC_2 | BSP_PINC_1 | BSP_PINC_5); - - GPIOPinWrite(BSP_PINA_BASE, (BSP_PINA_4 | BSP_PINA_5), 0x00); - GPIOPinWrite(BSP_PINC_BASE, (BSP_PINC_3 | BSP_PINC_2 | BSP_PINC_1 | BSP_PINC_5), 0); -} - -// PA4 -void debugpins_frame_toggle() { - bspDBpinToggle(BSP_PINA_BASE, BSP_PINA_4); -} -void debugpins_frame_clr() { - GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_4, 0); -} -void debugpins_frame_set() { - GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_4, BSP_PINA_4); -} - -// PD3 -void debugpins_slot_toggle() { - bspDBpinToggle(BSP_PINC_BASE, BSP_PINC_3); -} -void debugpins_slot_clr() { - GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_3, 0); -} -void debugpins_slot_set() { - GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_3, BSP_PINC_3); -} - -// PD2 -void debugpins_fsm_toggle() { - bspDBpinToggle(BSP_PINC_BASE, BSP_PINC_2); -} -void debugpins_fsm_clr() { - GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_2, 0); -} -void debugpins_fsm_set() { - GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_2, BSP_PINC_2); -} - -// PD1 -void debugpins_task_toggle() { - bspDBpinToggle(BSP_PINC_BASE,BSP_PINC_1); -} -void debugpins_task_clr() { - GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_1, 0); -} -void debugpins_task_set() { - GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_1, BSP_PINC_1); -} - -// PA5 -void debugpins_isr_toggle() { - bspDBpinToggle(BSP_PINA_BASE, BSP_PINA_5); -} -void debugpins_isr_clr() { - GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_5, 0); -} -void debugpins_isr_set() { - GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_5, BSP_PINA_5); -} - -// PD0 -void debugpins_radio_toggle() { - bspDBpinToggle(BSP_PINC_BASE, BSP_PINC_5); -} -void debugpins_radio_clr() { - GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_5, 0); -} -void debugpins_radio_set() { - GPIOPinWrite(BSP_PINC_BASE, BSP_PINC_5, BSP_PINC_5); -} - -//------------ private ------------// - -void bspDBpinToggle(uint32_t base, uint8_t ui8Pin) -{ - // - // Get current pin values of selected bits - // - uint32_t ui32Toggle = GPIOPinRead(base, ui8Pin); - - // - // Invert selected bits - // - ui32Toggle = (~ui32Toggle) & ui8Pin; - - // - // Set GPIO - // - GPIOPinWrite(base, ui8Pin, ui32Toggle); -} +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "debugpins" bsp module. + */ + +#include +#include + +#include + +#include "board.h" +#include "debugpins.h" + +//=========================== defines ========================================= +// Board dbPINS defines +#define BSP_PINA_BASE GPIO_A_BASE +#define BSP_PIND_BASE GPIO_D_BASE + +#define BSP_PINA_4 GPIO_PIN_4 //!< PA4 -- frame -RF1.5 +#define BSP_PINA_5 GPIO_PIN_5 //!< PA5 -- isr -RF1.11 + +#define BSP_PIND_3 GPIO_PIN_3 //!< PD3 -- slot -RF1.6 +#define BSP_PIND_2 GPIO_PIN_2 //!< PD2 -- fsm -RF1.8 +#define BSP_PIND_1 GPIO_PIN_1 //!< PD1 -- task -RF1.10 +#define BSP_PINA_2 GPIO_PIN_2 //!< PA2 -- radio -RF1-12 +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +void bspDBpinToggle(uint32_t base,uint8_t ui8Pin); + +//=========================== public ========================================== + +void debugpins_init(void) { + GPIOPinTypeGPIOOutput(BSP_PINA_BASE, BSP_PINA_2 | BSP_PINA_4 | BSP_PINA_5); + GPIOPinTypeGPIOOutput(BSP_PIND_BASE, BSP_PIND_3 | BSP_PIND_2 | BSP_PIND_1); + + GPIOPinWrite(BSP_PINA_BASE, (BSP_PINA_2 | BSP_PINA_4 | BSP_PINA_5), 0x00); + GPIOPinWrite(BSP_PIND_BASE, (BSP_PIND_3 | BSP_PIND_2 | BSP_PIND_1), 0); +} + +// PA4 +void debugpins_frame_toggle(void) { + bspDBpinToggle(BSP_PINA_BASE, BSP_PINA_4); +} +void debugpins_frame_clr(void) { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_4, 0); +} +void debugpins_frame_set(void) { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_4, BSP_PINA_4); +} + +// PD3 +void debugpins_slot_toggle(void) { + bspDBpinToggle(BSP_PIND_BASE, BSP_PIND_3); +} +void debugpins_slot_clr(void) { + GPIOPinWrite(BSP_PIND_BASE, BSP_PIND_3, 0); +} +void debugpins_slot_set(void) { + GPIOPinWrite(BSP_PIND_BASE, BSP_PIND_3, BSP_PIND_3); +} + +// PD2 +void debugpins_fsm_toggle(void) { + bspDBpinToggle(BSP_PIND_BASE, BSP_PIND_2); +} +void debugpins_fsm_clr(void) { + GPIOPinWrite(BSP_PIND_BASE, BSP_PIND_2, 0); +} +void debugpins_fsm_set(void) { + GPIOPinWrite(BSP_PIND_BASE, BSP_PIND_2, BSP_PIND_2); +} + +// PD1 +void debugpins_task_toggle(void) { + bspDBpinToggle(BSP_PIND_BASE,BSP_PIND_1); +} +void debugpins_task_clr(void) { + GPIOPinWrite(BSP_PIND_BASE, BSP_PIND_1, 0); +} +void debugpins_task_set(void) { + GPIOPinWrite(BSP_PIND_BASE, BSP_PIND_1, BSP_PIND_1); +} + +// PA5 +void debugpins_isr_toggle(void) { + bspDBpinToggle(BSP_PINA_BASE, BSP_PINA_5); +} +void debugpins_isr_clr(void) { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_5, 0); +} +void debugpins_isr_set(void) { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_5, BSP_PINA_5); +} + +// PD0 +void debugpins_radio_toggle(void) { + bspDBpinToggle(BSP_PINA_BASE, BSP_PINA_2); +} +void debugpins_radio_clr(void) { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_2, 0); +} +void debugpins_radio_set(void) { + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_2, BSP_PINA_2); +} + +//------------ private ------------// + +void bspDBpinToggle(uint32_t base, uint8_t ui8Pin) +{ + // + // Get current pin values of selected bits + // + uint32_t ui32Toggle = GPIOPinRead(base, ui8Pin); + + // + // Invert selected bits + // + ui32Toggle = (~ui32Toggle) & ui8Pin; + + // + // Set GPIO + // + GPIOPinWrite(base, ui8Pin, ui32Toggle); +} diff --git a/bsp/boards/mimsy2-cc2538/eui64.c b/bsp/boards/mimsy2-cc2538/eui64.c index 04c8ca580f..a40ed1c32a 100644 --- a/bsp/boards/mimsy2-cc2538/eui64.c +++ b/bsp/boards/mimsy2-cc2538/eui64.c @@ -1,40 +1,40 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "eui64" bsp module. - */ - -#include - -#include "eui64.h" - -//=========================== defines ========================================= - -#define BSP_EUI64_ADDRESS_HI_H ( 0x0028002F ) -#define BSP_EUI64_ADDRESS_HI_L ( 0x0028002C ) -#define BSP_EUI64_ADDRESS_LO_H ( 0x0028002B ) -#define BSP_EUI64_ADDRESS_LO_L ( 0x00280028 ) - -//=========================== variables ======================================= - -//=========================== prototypes ====================================== - -//=========================== public ========================================== - -void eui64_get(uint8_t* addressToWrite) { - uint8_t* eui64_flash; - - eui64_flash = (uint8_t*)BSP_EUI64_ADDRESS_LO_H; - while(eui64_flash >= (uint8_t*)BSP_EUI64_ADDRESS_LO_L) { - *addressToWrite++ = *eui64_flash--; - } - - eui64_flash = (uint8_t*)BSP_EUI64_ADDRESS_HI_H; - while(eui64_flash >= (uint8_t*)BSP_EUI64_ADDRESS_HI_L) { - *addressToWrite++ = *eui64_flash--; - } -} - -//=========================== private ========================================= - +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "eui64" bsp module. + */ + +#include + +#include "eui64.h" + +//=========================== defines ========================================= + +#define BSP_EUI64_ADDRESS_HI_H ( 0x0028002F ) +#define BSP_EUI64_ADDRESS_HI_L ( 0x0028002C ) +#define BSP_EUI64_ADDRESS_LO_H ( 0x0028002B ) +#define BSP_EUI64_ADDRESS_LO_L ( 0x00280028 ) + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +//=========================== public ========================================== + +void eui64_get(uint8_t* addressToWrite) { + uint8_t* eui64_flash; + + eui64_flash = (uint8_t*)BSP_EUI64_ADDRESS_LO_H; + while(eui64_flash >= (uint8_t*)BSP_EUI64_ADDRESS_LO_L) { + *addressToWrite++ = *eui64_flash--; + } + + eui64_flash = (uint8_t*)BSP_EUI64_ADDRESS_HI_H; + while(eui64_flash >= (uint8_t*)BSP_EUI64_ADDRESS_HI_L) { + *addressToWrite++ = *eui64_flash--; + } +} + +//=========================== private ========================================= + diff --git a/bsp/boards/mimsy2-cc2538/i2c.c b/bsp/boards/mimsy2-cc2538/i2c.c index b202cfe332..d1e9b8d311 100644 --- a/bsp/boards/mimsy2-cc2538/i2c.c +++ b/bsp/boards/mimsy2-cc2538/i2c.c @@ -1,203 +1,196 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description:CC2538-specific definition of the "i2c" bsp module. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -//=========================== define ========================================== - -#define I2C_PERIPHERAL ( SYS_CTRL_PERIPH_I2C ) -#define I2C_BASE ( GPIO_D_BASE ) -#define I2C_SCL ( GPIO_PIN_4 ) -#define I2C_SDA ( GPIO_PIN_5 ) -#define I2C_BAUDRATE ( 400000 ) -#define I2C_MAX_DELAY_US ( 1000000 ) - - -//=========================== variables ======================================= - - -//=========================== prototypes ====================================== - -extern uint32_t board_timer_get(void); -extern bool board_timer_expired(uint32_t future); - -//=========================== public ========================================== - -void i2c_init(void) { - bool status; - - // Enable peripheral except in deep sleep modes (e.g. LPM1, LPM2, LPM3) - SysCtrlPeripheralEnable(I2C_PERIPHERAL); - SysCtrlPeripheralSleepEnable(I2C_PERIPHERAL); - SysCtrlPeripheralDeepSleepDisable(I2C_PERIPHERAL); - - // Reset peripheral previous to configuring it - SysCtrlPeripheralReset(I2C_PERIPHERAL); - - // Configure the SCL pin - GPIOPinTypeI2C(I2C_BASE, I2C_SCL); - IOCPadConfigSet(I2C_BASE, I2C_SCL,IOC_OVERRIDE_PUE); // enables pins as outputs, necessary for this code to work correctly - - IOCPinConfigPeriphInput(I2C_BASE, I2C_SCL, IOC_I2CMSSCL); - IOCPinConfigPeriphOutput(I2C_BASE, I2C_SCL, IOC_MUX_OUT_SEL_I2C_CMSSCL); - - // Configure the SDA pin - GPIOPinTypeI2C(I2C_BASE, I2C_SDA); - IOCPadConfigSet(I2C_BASE, I2C_SDA,IOC_OVERRIDE_PUE); // enables pins as outputs, necessary for this code to work correctly - IOCPinConfigPeriphInput(I2C_BASE, I2C_SDA, IOC_I2CMSSDA); - IOCPinConfigPeriphOutput(I2C_BASE, I2C_SDA, IOC_MUX_OUT_SEL_I2C_CMSSDA); - - // Configure the I2C clock - status = (I2C_BAUDRATE == 400000 ? true : false); - I2CMasterInitExpClk(SysCtrlClockGet(), status); - - // Enable the I2C module as master - I2CMasterEnable(); -} - -bool i2c_read_byte(uint8_t address, uint8_t* byte) { - uint32_t future = I2C_MAX_DELAY_US; - - // Receive operation - I2CMasterSlaveAddrSet(address, true); - - // Single receive operation - I2CMasterControl(I2C_MASTER_CMD_SINGLE_RECEIVE); - - // Calculate timeout - future += board_timer_get(); - - // Wait until complete or timeout - while (I2CMasterBusy()) { - // Update timeout status and return if expired - if (board_timer_expired(future)) return false; - } - - // Read data from I2C - *byte = I2CMasterDataGet(); - - // Return status - return true; -} - - -uint32_t i2c_read_bytes(uint8_t address, uint8_t* buffer, uint32_t length) { - uint32_t future = I2C_MAX_DELAY_US; - - // Receive operation - I2CMasterSlaveAddrSet(address, true); - - // Multiple receive operation - I2CMasterControl(I2C_MASTER_CMD_BURST_RECEIVE_START); - - // Calculate timeout - future += board_timer_get(); - - // Iterate overall all bytes - while (length) { - // Wait until complete or timeout - while (I2CMasterBusy()) { - // Update timeout status and return if expired - if (board_timer_expired(future)) return length; - } - - // Read data from I2C - *buffer++ = I2CMasterDataGet(); - - - // Check if it's the last byte - if (length == 1) I2CMasterControl(I2C_MASTER_CMD_BURST_RECEIVE_FINISH); - else I2CMasterControl(I2C_MASTER_CMD_BURST_RECEIVE_CONT); - length--; - } - - // Return bytes read - - return length; -} - -bool i2c_write_byte(uint8_t address, uint8_t byte) { - uint32_t future = I2C_MAX_DELAY_US; - - // Transmit operation - I2CMasterSlaveAddrSet(address, false); - - // Write byte to I2C buffer - I2CMasterDataPut(byte); - - // Single transmit operation - I2CMasterControl(I2C_MASTER_CMD_SINGLE_SEND); - - // Calculate timeout - future += board_timer_get(); - - // Wait until complete or timeout - while (I2CMasterBusy()) { - // Check timeout status and return if expired - if (board_timer_expired(future)) return false; - } - - return true; -} - -uint32_t i2c_write_bytes(uint8_t address, uint8_t* buffer, uint32_t length) { - uint32_t future = I2C_MAX_DELAY_US; - - // Transmit operation - I2CMasterSlaveAddrSet(address, false); - - // Write byte to I2C buffer - I2CMasterDataPut(*buffer++); - length--; - - // Multiple transmit operation - I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_START); - - // Calculate timeout - future += board_timer_get(); - - // Wait until complete or timeout - while (I2CMasterBusy()) { - // Check timeout status and return if expired - if (board_timer_expired(future)) return length; - } - - // Iterate overall all bytes - while (length) { - // Write byte to I2C buffer - I2CMasterDataPut(*buffer++); - - // Check if it's the last byte - if (length == 1) I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_FINISH); - else I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_CONT); - - // Wait until complete or timeout - while (I2CMasterBusy()) { - // Check timeout status and return if expired - if (board_timer_expired(future)) return length; - } - - // Update the length - length--; - } - - // Return bytes written - return length; -} - -//=========================== private ========================================= - +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description:CC2538-specific definition of the "i2c" bsp module. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +//=========================== define ========================================== + +#define I2C_PERIPHERAL ( SYS_CTRL_PERIPH_I2C ) +#define I2C_BASE ( GPIO_B_BASE ) +#define I2C_SCL ( GPIO_PIN_3 ) +#define I2C_SDA ( GPIO_PIN_4 ) +#define I2C_BAUDRATE ( 100000 ) +#define I2C_MAX_DELAY_US ( 100000 ) + +//=========================== variables ======================================= + + +//=========================== prototypes ====================================== + +extern uint32_t board_timer_get(void); +extern bool board_timer_expired(uint32_t future); + +//=========================== public ========================================== + +void i2c_init(void) { + bool status; + + // Enable peripheral except in deep sleep modes (e.g. LPM1, LPM2, LPM3) + SysCtrlPeripheralEnable(I2C_PERIPHERAL); + SysCtrlPeripheralSleepEnable(I2C_PERIPHERAL); + SysCtrlPeripheralDeepSleepDisable(I2C_PERIPHERAL); + + // Reset peripheral previous to configuring it + SysCtrlPeripheralReset(I2C_PERIPHERAL); + + // Configure the SCL pin + GPIOPinTypeI2C(I2C_BASE, I2C_SCL); + IOCPinConfigPeriphInput(I2C_BASE, I2C_SCL, IOC_I2CMSSCL); + IOCPinConfigPeriphOutput(I2C_BASE, I2C_SCL, IOC_MUX_OUT_SEL_I2C_CMSSCL); + + // Configure the SDA pin + GPIOPinTypeI2C(I2C_BASE, I2C_SDA); + IOCPinConfigPeriphInput(I2C_BASE, I2C_SDA, IOC_I2CMSSDA); + IOCPinConfigPeriphOutput(I2C_BASE, I2C_SDA, IOC_MUX_OUT_SEL_I2C_CMSSDA); + + // Configure the I2C clock + status = (I2C_BAUDRATE == 400000 ? true : false); + I2CMasterInitExpClk(SysCtrlClockGet(), status); + + // Enable the I2C module as master + I2CMasterEnable(); +} + +bool i2c_read_byte(uint8_t address, uint8_t* byte) { + uint32_t future = I2C_MAX_DELAY_US; + + // Receive operation + I2CMasterSlaveAddrSet(address, true); + + // Single receive operation + I2CMasterControl(I2C_MASTER_CMD_SINGLE_RECEIVE); + + // Calculate timeout + future += board_timer_get(); + + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Update timeout status and return if expired + if (board_timer_expired(future)) return false; + } + + // Read data from I2C + *byte = I2CMasterDataGet(); + + // Return status + return true; +} + +uint32_t i2c_read_bytes(uint8_t address, uint8_t* buffer, uint32_t length) { + uint32_t future = I2C_MAX_DELAY_US; + + // Receive operation + I2CMasterSlaveAddrSet(address, true); + + // Multiple receive operation + I2CMasterControl(I2C_MASTER_CMD_BURST_RECEIVE_START); + + // Calculate timeout + future += board_timer_get(); + + // Iterate overall all bytes + while (length) { + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Update timeout status and return if expired + if (board_timer_expired(future)) return length; + } + + // Read data from I2C + *buffer++ = I2CMasterDataGet(); + length--; + + // Check if it's the last byte + if (length == 1) I2CMasterControl(I2C_MASTER_CMD_BURST_RECEIVE_FINISH); + else I2CMasterControl(I2C_MASTER_CMD_BURST_RECEIVE_CONT); + } + + // Return bytes read + return length; +} + +bool i2c_write_byte(uint8_t address, uint8_t byte) { + uint32_t future = I2C_MAX_DELAY_US; + + // Transmit operation + I2CMasterSlaveAddrSet(address, false); + + // Write byte to I2C buffer + I2CMasterDataPut(byte); + + // Single transmit operation + I2CMasterControl(I2C_MASTER_CMD_SINGLE_SEND); + + // Calculate timeout + future += board_timer_get(); + + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Check timeout status and return if expired + if (board_timer_expired(future)) return false; + } + + return true; +} + +uint32_t i2c_write_bytes(uint8_t address, uint8_t* buffer, uint32_t length) { + uint32_t future = I2C_MAX_DELAY_US; + + // Transmit operation + I2CMasterSlaveAddrSet(address, false); + + // Write byte to I2C buffer + I2CMasterDataPut(*buffer++); + length--; + + // Multiple transmit operation + I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_START); + + // Calculate timeout + future += board_timer_get(); + + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Check timeout status and return if expired + if (board_timer_expired(future)) return length; + } + + // Iterate overall all bytes + while (length) { + // Write byte to I2C buffer + I2CMasterDataPut(*buffer++); + + // Check if it's the last byte + if (length == 1) I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_FINISH); + else I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_CONT); + + // Wait until complete or timeout + while (I2CMasterBusy()) { + // Check timeout status and return if expired + if (board_timer_expired(future)) return length; + } + + // Update the length + length--; + } + + // Return bytes written + return length; +} + +//=========================== private ========================================= + diff --git a/bsp/boards/mimsy2-cc2538/leds.c b/bsp/boards/mimsy2-cc2538/leds.c index 19dc87520b..f364b847d6 100644 --- a/bsp/boards/mimsy2-cc2538/leds.c +++ b/bsp/boards/mimsy2-cc2538/leds.c @@ -1,213 +1,209 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "leds" bsp module. - */ - -#include - -#include -#include - -#include - -#include "board.h" -#include "leds.h" - -//=========================== defines ========================================= - -// Board LED defines -#define BSP_LED_BASE GPIO_C_BASE -#define BSP_LED_1 GPIO_PIN_4 //!< PC4 -- red -#define BSP_LED_2 GPIO_PIN_5 //!< PC5 -- orange -#define BSP_LED_3 GPIO_PIN_6 //!< PC6 -- yellow -#define BSP_LED_4 GPIO_PIN_7 //!< PC7 -- green - -#define BSP_LED_ALL (BSP_LED_1 | \ - BSP_LED_2 | \ - BSP_LED_3 | \ - BSP_LED_4) //!< Bitmask of all LEDs - -//=========================== variables ======================================= - -//=========================== prototypes ====================================== - -void bspLedSet(uint8_t ui8Leds); -void bspLedClear(uint8_t ui8Leds); -void bspLedToggle(uint8_t ui8Leds); - -//=========================== public ========================================== - -void leds_init() { - GPIOPinTypeGPIOOutput(BSP_LED_BASE, BSP_LED_ALL); - GPIOPinWrite(BSP_LED_BASE, BSP_LED_ALL, 0); -} - -// red -void leds_error_on() { - bspLedSet(BSP_LED_1); -} -void leds_error_off() { - bspLedClear(BSP_LED_1); -} -void leds_error_toggle() { - bspLedToggle(BSP_LED_1); -} -uint8_t leds_error_isOn() { - uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_1); - return (uint8_t)(ui32Toggle & BSP_LED_1)>>4; -} - -// orange -void leds_sync_on() { - bspLedSet(BSP_LED_2); -} -void leds_sync_off() { - bspLedClear(BSP_LED_2); -} -void leds_sync_toggle() { - bspLedToggle(BSP_LED_2); -} -uint8_t leds_sync_isOn() { - uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_2); - return (uint8_t)(ui32Toggle & BSP_LED_2)>>5; -} - -// green -void leds_radio_on() { - bspLedSet(BSP_LED_4); -} -void leds_radio_off() { - bspLedClear(BSP_LED_4); -} -void leds_radio_toggle() { - bspLedToggle(BSP_LED_4); -} -uint8_t leds_radio_isOn() { - uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_4); - return (uint8_t)(ui32Toggle & BSP_LED_4)>>7; -} - -// yellow -void leds_debug_on() { - bspLedSet(BSP_LED_3); -} -void leds_debug_off() { - bspLedClear(BSP_LED_3); -} -void leds_debug_toggle() { - bspLedToggle(BSP_LED_3); -} -uint8_t leds_debug_isOn() { - uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_3); - return (uint8_t)(ui32Toggle & BSP_LED_3)>>6; -} - -// all -void leds_all_on() { - bspLedSet(BSP_LED_ALL); -} -void leds_all_off() { - bspLedClear(BSP_LED_ALL); -} -void leds_all_toggle() { - bspLedToggle(BSP_LED_ALL); -} - -void leds_error_blink() { - uint8_t i; - volatile uint16_t delay; - - // turn all LEDs off - bspLedClear(BSP_LED_ALL); - - // blink error LED for ~10s - for (i=0;i<80;i++) { - bspLedToggle(BSP_LED_1); - for (delay=0xffff;delay>0;delay--); - for (delay=0xffff;delay>0;delay--); - } -} - -void leds_circular_shift() { - uint8_t i; - volatile uint16_t delay; - - // turn all LEDs off - bspLedClear(BSP_LED_ALL); - - // incrementally turn LED on - for (i=0;i<10;i++) { - bspLedSet(BSP_LED_1); - for (delay=0xffff;delay>0;delay--); - bspLedClear(BSP_LED_1); - bspLedSet(BSP_LED_2); - for (delay=0xffff;delay>0;delay--); - bspLedClear(BSP_LED_2); - bspLedSet(BSP_LED_3); - for (delay=0xffff;delay>0;delay--); - bspLedClear(BSP_LED_3); - bspLedSet(BSP_LED_4); - for (delay=0xffff;delay>0;delay--); - bspLedClear(BSP_LED_ALL); - } -} - -void leds_increment() { - uint8_t i; - volatile uint16_t delay; - - // turn all LEDs off - bspLedClear(BSP_LED_ALL); - - // incrementally turn LED on - for (i=0;i<10;i++) { - bspLedSet(BSP_LED_1); - for (delay=0xffff;delay>0;delay--); - bspLedSet(BSP_LED_2); - for (delay=0xffff;delay>0;delay--); - bspLedSet(BSP_LED_3); - for (delay=0xffff;delay>0;delay--); - bspLedSet(BSP_LED_4); - for (delay=0xffff;delay>0;delay--); - bspLedClear(BSP_LED_ALL); - } -} - -//=========================== private ========================================= - -port_INLINE void bspLedSet(uint8_t ui8Leds) -{ - // - // Turn on specified LEDs - // - GPIOPinWrite(BSP_LED_BASE, ui8Leds, ui8Leds); -} - -port_INLINE void bspLedClear(uint8_t ui8Leds) -{ - // - // Turn off specified LEDs - // - GPIOPinWrite(BSP_LED_BASE, ui8Leds, 0); -} - -port_INLINE void bspLedToggle(uint8_t ui8Leds) -{ - // - // Get current pin values of selected bits - // - uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, ui8Leds); - - // - // Invert selected bits - // - ui32Toggle = (~ui32Toggle) & ui8Leds; - - // - // Set GPIO - // - GPIOPinWrite(BSP_LED_BASE, ui8Leds, ui32Toggle); -} - +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "leds" bsp module. + */ + +#include + +#include +#include + +#include + +#include "board.h" +#include "leds.h" + +//=========================== defines ========================================= + +// Board LED defines +#define BSP_LED_BASE GPIO_C_BASE +#define BSP_LED_1 GPIO_PIN_4 //!< PC4 -- red +#define BSP_LED_2 GPIO_PIN_5 //!< PC5 -- orange +#define BSP_LED_3 GPIO_PIN_6 //!< PC6 -- yellow +#define BSP_LED_4 GPIO_PIN_7 //!< PC7 -- green + +#define BSP_LED_ALL (BSP_LED_1 | \ + BSP_LED_2 | \ + BSP_LED_3 | \ + BSP_LED_4) //!< Bitmask of all LEDs + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +void bspLedSet(uint8_t ui8Leds); +void bspLedClear(uint8_t ui8Leds); +void bspLedToggle(uint8_t ui8Leds); + +//=========================== public ========================================== + +void leds_init(void) { + GPIOPinTypeGPIOOutput(BSP_LED_BASE, BSP_LED_ALL); + GPIOPinWrite(BSP_LED_BASE, BSP_LED_ALL, 0); +} + +// red +void leds_error_on(void) { + bspLedSet(BSP_LED_1); +} +void leds_error_off(void) { + bspLedClear(BSP_LED_1); +} +void leds_error_toggle(void) { + bspLedToggle(BSP_LED_1); +} +uint8_t leds_error_isOn(void) { + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_1); + return (uint8_t)(ui32Toggle & BSP_LED_1)>>4; +} + +// orange +void leds_sync_on(void) { + bspLedSet(BSP_LED_2); +} +void leds_sync_off(void) { + bspLedClear(BSP_LED_2); +} +void leds_sync_toggle(void) { + bspLedToggle(BSP_LED_2); +} +uint8_t leds_sync_isOn(void) { + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_2); + return (uint8_t)(ui32Toggle & BSP_LED_2)>>5; +} + +// green +void leds_radio_on(void) { + bspLedSet(BSP_LED_4); +} +void leds_radio_off(void) { + bspLedClear(BSP_LED_4); +} +void leds_radio_toggle(void) { + bspLedToggle(BSP_LED_4); +} +uint8_t leds_radio_isOn(void) { + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_4); + return (uint8_t)(ui32Toggle & BSP_LED_4)>>7; +} + +// yellow +void leds_debug_on(void) { + bspLedSet(BSP_LED_3); +} +void leds_debug_off(void) { + bspLedClear(BSP_LED_3); +} +void leds_debug_toggle(void) { + bspLedToggle(BSP_LED_3); +} +uint8_t leds_debug_isOn(void) { + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_3); + return (uint8_t)(ui32Toggle & BSP_LED_3)>>6; +} + +// all +void leds_all_on(void) { + bspLedSet(BSP_LED_ALL); +} +void leds_all_off(void) { + bspLedClear(BSP_LED_ALL); +} +void leds_all_toggle(void) { + bspLedToggle(BSP_LED_ALL); +} + +void leds_error_blink(void) { + uint8_t i; + volatile uint16_t delay; + + // turn all LEDs off + bspLedClear(BSP_LED_ALL); + + // blink error LED for ~10s + for (i=0;i<80;i++) { + bspLedToggle(BSP_LED_1); + for (delay=0xffff;delay>0;delay--); + for (delay=0xffff;delay>0;delay--); + } +} + +void leds_circular_shift(void) { + uint8_t i; + volatile uint16_t delay; + + // turn all LEDs off + bspLedClear(BSP_LED_ALL); + + // incrementally turn LED on + for (i=0;i<10;i++) { + bspLedSet(BSP_LED_1); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_1); + bspLedSet(BSP_LED_2); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_2); + bspLedSet(BSP_LED_3); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_3); + bspLedSet(BSP_LED_4); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_ALL); + } +} + +void leds_increment(void) { + uint8_t i; + volatile uint16_t delay; + + // turn all LEDs off + bspLedClear(BSP_LED_ALL); + + // incrementally turn LED on + for (i=0;i<10;i++) { + bspLedSet(BSP_LED_1); + for (delay=0xffff;delay>0;delay--); + bspLedSet(BSP_LED_2); + for (delay=0xffff;delay>0;delay--); + bspLedSet(BSP_LED_3); + for (delay=0xffff;delay>0;delay--); + bspLedSet(BSP_LED_4); + for (delay=0xffff;delay>0;delay--); + bspLedClear(BSP_LED_ALL); + } +} + +//=========================== private ========================================= + +port_INLINE void bspLedSet(uint8_t ui8Leds){ + // + // Turn on specified LEDs + // + GPIOPinWrite(BSP_LED_BASE, ui8Leds, ui8Leds); +} + +port_INLINE void bspLedClear(uint8_t ui8Leds){ + // + // Turn off specified LEDs + // + GPIOPinWrite(BSP_LED_BASE, ui8Leds, 0); +} + +port_INLINE void bspLedToggle(uint8_t ui8Leds){ + // + // Get current pin values of selected bits + // + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, ui8Leds); + + // + // Invert selected bits + // + ui32Toggle = (~ui32Toggle) & ui8Leds; + + // + // Set GPIO + // + GPIOPinWrite(BSP_LED_BASE, ui8Leds, ui32Toggle); +} \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/pwm.c b/bsp/boards/mimsy2-cc2538/pwm.c new file mode 100644 index 0000000000..01e13ce54f --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/pwm.c @@ -0,0 +1,62 @@ +/** +\brief A PWM module. + +\author Tengfei Chang April 2017 +*/ + +#include "board_info.h" +#include "gptimer.h" +#include +#include + +#include +#include +#include + +// ========================== define ========================================== + +// ========================== variable ======================================== + +typedef struct { + bool isStarted; +} pwm_vars_t; + +pwm_vars_t pwm_vars; + + +// ========================== private ========================================= + +// ========================== protocol ========================================= + +/** +\brief Initialization pwm. +*/ +void pwm_init(void){ + + // Configure GPIOPortB.3 as the Timer0_InputCapturePin.1 + IOCPinConfigPeriphOutput(GPIO_B_BASE, GPIO_PIN_3, IOC_MUX_OUT_SEL_GPT3_ICP1); + + TimerConfigure(GPTIMER3_BASE, (GPTIMER_CFG_SPLIT_PAIR | GPTIMER_CFG_A_PWM)); + TimerControlLevel(GPTIMER3_BASE, GPTIMER_A, false); + + // configure GPTimer to be 38khz (infrared standard modulation frequency) + +// // set the frequency (32,000,000/842=38khz) +// TimerLoadSet(GPTIMER3_BASE, GPTIMER_A, 842); +// // set 50% duty cycle +// TimerMatchSet(GPTIMER3_BASE, GPTIMER_A, 421); + + // measured frequency: 32.719khz (from infrared of remote controller) + TimerLoadSet(GPTIMER3_BASE, GPTIMER_A, 978); + TimerMatchSet(GPTIMER3_BASE, GPTIMER_A, 489); +} + +void pwm_enable(void){ + TimerEnable(GPTIMER3_BASE, GPTIMER_A); +} + +void pwm_disable(void){ + TimerDisable(GPTIMER3_BASE, GPTIMER_A); +} + +// ========================== private ========================================= \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/pwm.h b/bsp/boards/mimsy2-cc2538/pwm.h new file mode 100644 index 0000000000..c8f156ad7c --- /dev/null +++ b/bsp/boards/mimsy2-cc2538/pwm.h @@ -0,0 +1,31 @@ +#ifndef __PWM_H +#define __PWM_H + +/** +\addtogroup BSP +\{ +\addtogroup pwm +\{ + +\brief A pwm module. + +\author Tengfei Chang , April 2017. +*/ +#include "stdint.h" +#include "board.h" + +// ========================== define ========================================== + +// ========================== variable ======================================== + +// ========================== private ========================================= + +// ========================== protocol ========================================= + +/** +\brief Initialization sctimer. +*/ +void pwm_init(void); +void pwm_enable(void); +void pwm_disable(void); +#endif \ No newline at end of file diff --git a/bsp/boards/mimsy2-cc2538/radio.c b/bsp/boards/mimsy2-cc2538/radio.c index 31ef466df1..d8f82dd8a0 100644 --- a/bsp/boards/mimsy2-cc2538/radio.c +++ b/bsp/boards/mimsy2-cc2538/radio.c @@ -1,531 +1,531 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "radio" bsp module. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "board.h" -#include "cc2538rf.h" -#include "debugpins.h" -#include "leds.h" -#include "radio.h" -#include "sctimer.h" - -//=========================== defines ========================================= - -/* Bit Masks for the last byte in the RX FIFO */ -#define CRC_BIT_MASK 0x80 -#define LQI_BIT_MASK 0x7F - -/* RSSI Offset */ -#define RSSI_OFFSET 73 -#define CHECKSUM_LEN 2 - -//=========================== variables ======================================= - -typedef struct { - radio_capture_cbt startFrame_cb; - radio_capture_cbt endFrame_cb; - radio_state_t state; -} radio_vars_t; - -radio_vars_t radio_vars; - -//=========================== prototypes ====================================== - -void enable_radio_interrupts(void); -void disable_radio_interrupts(void); - -void radio_on(void); -void radio_off(void); - -void radio_error_isr(void); -void radio_isr_internal(void); - -//=========================== public ========================================== - -//===== admin - -void radio_init() { - - // clear variables - memset(&radio_vars,0,sizeof(radio_vars_t)); - - // change state - radio_vars.state = RADIOSTATE_STOPPED; - //flush fifos - CC2538_RF_CSP_ISFLUSHRX(); - CC2538_RF_CSP_ISFLUSHTX(); - - radio_off(); - - //disable radio interrupts - disable_radio_interrupts(); - - /* - This CORR_THR value should be changed to 0x14 before attempting RX. Testing has shown that - too many false frames are received if the reset value is used. Make it more likely to detect - sync by removing the requirement that both symbols in the SFD must have a correlation value - above the correlation threshold, and make sync word detection less likely by raising the - correlation threshold. - */ - HWREG(RFCORE_XREG_MDMCTRL1) = 0x14; - /* tuning adjustments for optimal radio performance; details available in datasheet */ - - HWREG(RFCORE_XREG_RXCTRL) = 0x3F; - /* Adjust current in synthesizer; details available in datasheet. */ - HWREG(RFCORE_XREG_FSCTRL) = 0x55; - - /* Makes sync word detection less likely by requiring two zero symbols before the sync word. - * details available in datasheet. - */ - HWREG(RFCORE_XREG_MDMCTRL0) = 0x85; - - /* Adjust current in VCO; details available in datasheet. */ - HWREG(RFCORE_XREG_FSCAL1) = 0x01; - /* Adjust target value for AGC control loop; details available in datasheet. */ - HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; - - /* Tune ADC performance, details available in datasheet. */ - HWREG(RFCORE_XREG_ADCTEST0) = 0x10; - HWREG(RFCORE_XREG_ADCTEST1) = 0x0E; - HWREG(RFCORE_XREG_ADCTEST2) = 0x03; - - //update CCA register to -81db as indicated by manual.. won't be used.. - HWREG(RFCORE_XREG_CCACTRL0) = 0xF8; - /* - * Changes from default values - * See User Guide, section "Register Settings Update" - */ - HWREG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */ - HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */ - HWREG(ANA_REGS_O_IVCTRL) = 0x0B; /** Bias currents */ - - /* disable the CSPT register compare function */ - HWREG(RFCORE_XREG_CSPT) = 0xFFUL; - /* - * Defaults: - * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation; - * RX and TX modes with FIFOs - */ - HWREG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_AUTOCRC; - - //poipoi disable frame filtering by now.. sniffer mode. - HWREG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; - - /* Disable source address matching and autopend */ - HWREG(RFCORE_XREG_SRCMATCH) = 0; - - /* MAX FIFOP threshold */ - HWREG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN; - - HWREG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER; - HWREG(RFCORE_XREG_FREQCTRL) = CC2538_RF_CHANNEL_MIN; - - /* Enable RF interrupts see page 751 */ - // enable_radio_interrupts(); - - //register interrupt - IntRegister(INT_RFCORERTX, radio_isr_internal); - IntRegister(INT_RFCOREERR, radio_error_isr); - - IntEnable(INT_RFCORERTX); - - /* Enable all RF Error interrupts */ - HWREG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM_M; //all errors - IntEnable(INT_RFCOREERR); - //radio_on(); - - // change state - radio_vars.state = RADIOSTATE_RFOFF; -} - -void radio_setStartFrameCb(radio_capture_cbt cb) { - radio_vars.startFrame_cb = cb; -} - -void radio_setEndFrameCb(radio_capture_cbt cb) { - radio_vars.endFrame_cb = cb; -} - -//===== reset - -void radio_reset() { - /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ - while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - - //flush fifos - CC2538_RF_CSP_ISFLUSHRX(); - CC2538_RF_CSP_ISFLUSHTX(); - - /* Don't turn off if we are off as this will trigger a Strobe Error */ - if(HWREG(RFCORE_XREG_RXENABLE) != 0) { - CC2538_RF_CSP_ISRFOFF(); - } - radio_init(); -} - -//===== RF admin - -void radio_setFrequency(uint8_t frequency) { - - // change state - radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; - - radio_off(); - // configure the radio to the right frequecy - if((frequency < CC2538_RF_CHANNEL_MIN) || (frequency > CC2538_RF_CHANNEL_MAX)) { - while(1); - } - - /* Changes to FREQCTRL take effect after the next recalibration */ - HWREG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN - + (frequency - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING); - - //radio_on(); - - // change state - radio_vars.state = RADIOSTATE_FREQUENCY_SET; -} - -void radio_rfOn() { - //radio_on(); -} - -void radio_rfOff() { - - // change state - radio_vars.state = RADIOSTATE_TURNING_OFF; - radio_off(); - // wiggle debug pin - debugpins_radio_clr(); - leds_radio_off(); - //enable radio interrupts - disable_radio_interrupts(); - - // change state - radio_vars.state = RADIOSTATE_RFOFF; -} - -//===== TX - -void radio_loadPacket(uint8_t* packet, uint16_t len) { - uint8_t i=0; - - // change state - radio_vars.state = RADIOSTATE_LOADING_PACKET; - - // load packet in TXFIFO - /* - When we transmit in very quick bursts, make sure previous transmission - is not still in progress before re-writing to the TX FIFO - */ - while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - - CC2538_RF_CSP_ISFLUSHTX(); - - /* Send the phy length byte first */ - HWREG(RFCORE_SFR_RFDATA) = len; //crc len is included - - for(i = 0; i < len; i++) { - HWREG(RFCORE_SFR_RFDATA) = packet[i]; - } - - // change state - radio_vars.state = RADIOSTATE_PACKET_LOADED; -} - -void radio_txEnable() { - - // change state - radio_vars.state = RADIOSTATE_ENABLING_TX; - - // wiggle debug pin - debugpins_radio_set(); - leds_radio_on(); - - //do nothing -- radio is activated by the strobe on rx or tx - //radio_rfOn(); - - // change state - radio_vars.state = RADIOSTATE_TX_ENABLED; -} - -void radio_txNow() { - PORT_TIMER_WIDTH count; - - // change state - radio_vars.state = RADIOSTATE_TRANSMITTING; - - //enable radio interrupts - enable_radio_interrupts(); - - //make sure we are not transmitting already - while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - - // send packet by STON strobe see pag 669 - - CC2538_RF_CSP_ISTXON(); - //wait 192uS - count=0; - while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE))){ - count++; //debug - } -} - -//===== RX - -void radio_rxEnable() { - - // change state - radio_vars.state = RADIOSTATE_ENABLING_RX; - - //enable radio interrupts - - // do nothing as we do not want to receive anything yet. - // wiggle debug pin - debugpins_radio_set(); - leds_radio_on(); - - // change state - radio_vars.state = RADIOSTATE_LISTENING; -} - -void radio_rxNow() { - //empty buffer before receiving - //CC2538_RF_CSP_ISFLUSHRX(); - - //enable radio interrupts - CC2538_RF_CSP_ISFLUSHRX(); - enable_radio_interrupts(); - - CC2538_RF_CSP_ISRXON(); - // busy wait until radio really listening - while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_RX_ACTIVE))); -} - -void radio_getReceivedFrame(uint8_t* pBufRead, - uint8_t* pLenRead, - uint8_t maxBufLen, - int8_t* pRssi, - uint8_t* pLqi, - bool* pCrc) { - uint8_t crc_corr,i; - - uint8_t len=0; - - /* Check the length */ - len = HWREG(RFCORE_SFR_RFDATA); //first byte is len - - - /* Check for validity */ - if(len > CC2538_RF_MAX_PACKET_LEN) { - /* wrong len */ - CC2538_RF_CSP_ISFLUSHRX(); - return; - } - - - if(len <= CC2538_RF_MIN_PACKET_LEN) { - //too short - CC2538_RF_CSP_ISFLUSHRX(); - return; - } - - //check if this fits to the buffer - if(len > maxBufLen) { - CC2538_RF_CSP_ISFLUSHRX(); - return; - } - - // when reading the packet from the RX buffer, you get the following: - // - *[1B] length byte - // - [0-125B] packet (excluding CRC) - // - [1B] RSSI - // - *[2B] CRC - - //skip first byte is len - for(i = 0; i < len - 2; i++) { - pBufRead[i] = HWREG(RFCORE_SFR_RFDATA); - } - - *pRssi = ((int8_t)(HWREG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET); - crc_corr = HWREG(RFCORE_SFR_RFDATA); - *pCrc = crc_corr & CRC_BIT_MASK; - *pLenRead = len; - - //flush it - CC2538_RF_CSP_ISFLUSHRX(); -} - -//=========================== private ========================================= - -void enable_radio_interrupts(void){ - /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ - HWREG(RFCORE_XREG_RFIRQM0) |= ((0x06|0x02|0x01) << RFCORE_XREG_RFIRQM0_RFIRQM_S) & RFCORE_XREG_RFIRQM0_RFIRQM_M; - - /* Enable RF interrupts 1, TXDONE only */ - HWREG(RFCORE_XREG_RFIRQM1) |= ((0x02) << RFCORE_XREG_RFIRQM1_RFIRQM_S) & RFCORE_XREG_RFIRQM1_RFIRQM_M; -} - -void disable_radio_interrupts(void){ - /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ - HWREG(RFCORE_XREG_RFIRQM0) = 0; - /* Enable RF interrupts 1, TXDONE only */ - HWREG(RFCORE_XREG_RFIRQM1) = 0; -} - -void radio_on(void){ - // CC2538_RF_CSP_ISFLUSHRX(); - CC2538_RF_CSP_ISRXON(); -} - -void radio_off(void){ - /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ - while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - //CC2538_RF_CSP_ISFLUSHRX(); - - /* Don't turn off if we are off as this will trigger a Strobe Error */ - if(HWREG(RFCORE_XREG_RXENABLE) != 0) { - CC2538_RF_CSP_ISRFOFF(); - //clear fifo isr flag - HWREG(RFCORE_SFR_RFIRQF0) = ~(RFCORE_SFR_RFIRQF0_FIFOP|RFCORE_SFR_RFIRQF0_RXPKTDONE); - } -} - -//=========================== callbacks ======================================= - -//=========================== interrupt handlers ============================== - -/** -\brief Stub function for the CC2538. - -In MSP430 platforms the CPU status after servicing an interrupt can be managed -toggling some bits in a special register, e.g. CPUOFF, LPM1, etc, within the -interrupt context itself. By default, after servicing an interrupt the CPU will -be off so it makes sense to return a value and enable it if something has -happened that needs the scheduler to run (a packet has been received that needs -to be processed). Otherwise, the CPU is kept in sleep mode without even -reaching the main loop. - -In the CC2538, however, the default behaviour is the contrary. After servicing -an interrupt the CPU will be on by default and it is the responsability of the -main thread to put it back to sleep (which is already done). This means that -the scheduler will always be kicked in after servicing an interrupt. This -behaviour can be changed by modifying the SLEEPEXIT field in the SYSCTRL -regiser (see page 131 of the CC2538 manual). -*/ -kick_scheduler_t radio_isr() { - return DO_NOT_KICK_SCHEDULER; -} - -void radio_isr_internal(void) { - volatile PORT_TIMER_WIDTH capturedTime; - uint8_t irq_status0,irq_status1; - - debugpins_isr_set(); - - // capture the time - capturedTime = sctimer_readCounter(); - - // reading IRQ_STATUS - irq_status0 = HWREG(RFCORE_SFR_RFIRQF0); - irq_status1 = HWREG(RFCORE_SFR_RFIRQF1); - - IntPendClear(INT_RFCORERTX); - - //clear interrupt - HWREG(RFCORE_SFR_RFIRQF0) = 0; - HWREG(RFCORE_SFR_RFIRQF1) = 0; - - //STATUS0 Register - // start of frame event - if ((irq_status0 & RFCORE_SFR_RFIRQF0_SFD) == RFCORE_SFR_RFIRQF0_SFD) { - // change state - radio_vars.state = RADIOSTATE_RECEIVING; - if (radio_vars.startFrame_cb!=NULL) { - // call the callback - radio_vars.startFrame_cb(capturedTime); - debugpins_isr_clr(); - // kick the OS - return; - } else { - while(1); - } - } - - //or RXDONE is full -- we have a packet. - if (((irq_status0 & RFCORE_SFR_RFIRQF0_RXPKTDONE) == RFCORE_SFR_RFIRQF0_RXPKTDONE)) { - // change state - radio_vars.state = RADIOSTATE_TXRX_DONE; - if (radio_vars.endFrame_cb!=NULL) { - // call the callback - radio_vars.endFrame_cb(capturedTime); - debugpins_isr_clr(); - // kick the OS - return; - } else { - while(1); - } - } - - // or FIFOP is full -- we have a packet. - if (((irq_status0 & RFCORE_SFR_RFIRQF0_FIFOP) == RFCORE_SFR_RFIRQF0_FIFOP)) { - // change state - radio_vars.state = RADIOSTATE_TXRX_DONE; - if (radio_vars.endFrame_cb!=NULL) { - // call the callback - radio_vars.endFrame_cb(capturedTime); - debugpins_isr_clr(); - // kick the OS - return; - } else { - while(1); - } - } - - //STATUS1 Register - // end of frame event --either end of tx . - if (((irq_status1 & RFCORE_SFR_RFIRQF1_TXDONE) == RFCORE_SFR_RFIRQF1_TXDONE)) { - // change state - radio_vars.state = RADIOSTATE_TXRX_DONE; - if (radio_vars.endFrame_cb!=NULL) { - // call the callback - radio_vars.endFrame_cb(capturedTime); - debugpins_isr_clr(); - // kick the OS - return; - } else { - while(1); - } - } - debugpins_isr_clr(); - - return; -} - -void radio_error_isr(void){ - uint8_t rferrm; - - rferrm = (uint8_t)HWREG(RFCORE_XREG_RFERRM); - - if ((HWREG(RFCORE_XREG_RFERRM) & (((0x02)< +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "board.h" +#include "cc2538rf.h" +#include "debugpins.h" +#include "leds.h" +#include "radio.h" +#include "sctimer.h" + +//=========================== defines ========================================= + +/* Bit Masks for the last byte in the RX FIFO */ +#define CRC_BIT_MASK 0x80 +#define LQI_BIT_MASK 0x7F + +/* RSSI Offset */ +#define RSSI_OFFSET 73 +#define CHECKSUM_LEN 2 + +//=========================== variables ======================================= + +typedef struct { + radio_capture_cbt startFrame_cb; + radio_capture_cbt endFrame_cb; + radio_state_t state; +} radio_vars_t; + +radio_vars_t radio_vars; + +//=========================== prototypes ====================================== + +void enable_radio_interrupts(void); +void disable_radio_interrupts(void); + +void radio_on(void); +void radio_off(void); + +void radio_error_isr(void); +void radio_isr_internal(void); + +//=========================== public ========================================== + +//===== admin + +void radio_init(void) { + + // clear variables + memset(&radio_vars,0,sizeof(radio_vars_t)); + + // change state + radio_vars.state = RADIOSTATE_STOPPED; + //flush fifos + CC2538_RF_CSP_ISFLUSHRX(); + CC2538_RF_CSP_ISFLUSHTX(); + + radio_off(); + + //disable radio interrupts + disable_radio_interrupts(); + + /* + This CORR_THR value should be changed to 0x14 before attempting RX. Testing has shown that + too many false frames are received if the reset value is used. Make it more likely to detect + sync by removing the requirement that both symbols in the SFD must have a correlation value + above the correlation threshold, and make sync word detection less likely by raising the + correlation threshold. + */ + HWREG(RFCORE_XREG_MDMCTRL1) = 0x14; + /* tuning adjustments for optimal radio performance; details available in datasheet */ + + HWREG(RFCORE_XREG_RXCTRL) = 0x3F; + /* Adjust current in synthesizer; details available in datasheet. */ + HWREG(RFCORE_XREG_FSCTRL) = 0x55; + + /* Makes sync word detection less likely by requiring two zero symbols before the sync word. + * details available in datasheet. + */ + HWREG(RFCORE_XREG_MDMCTRL0) = 0x85; + + /* Adjust current in VCO; details available in datasheet. */ + HWREG(RFCORE_XREG_FSCAL1) = 0x01; + /* Adjust target value for AGC control loop; details available in datasheet. */ + HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; + + /* Tune ADC performance, details available in datasheet. */ + HWREG(RFCORE_XREG_ADCTEST0) = 0x10; + HWREG(RFCORE_XREG_ADCTEST1) = 0x0E; + HWREG(RFCORE_XREG_ADCTEST2) = 0x03; + + //update CCA register to -81db as indicated by manual.. won't be used.. + HWREG(RFCORE_XREG_CCACTRL0) = 0xF8; + /* + * Changes from default values + * See User Guide, section "Register Settings Update" + */ + HWREG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */ + HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */ + HWREG(ANA_REGS_O_IVCTRL) = 0x0B; /** Bias currents */ + + /* disable the CSPT register compare function */ + HWREG(RFCORE_XREG_CSPT) = 0xFFUL; + /* + * Defaults: + * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation; + * RX and TX modes with FIFOs + */ + HWREG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_AUTOCRC; + + //poipoi disable frame filtering by now.. sniffer mode. + HWREG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; + + /* Disable source address matching and autopend */ + HWREG(RFCORE_XREG_SRCMATCH) = 0; + + /* MAX FIFOP threshold */ + HWREG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN; + + HWREG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER; + HWREG(RFCORE_XREG_FREQCTRL) = CC2538_RF_CHANNEL_MIN; + + /* Enable RF interrupts see page 751 */ + // enable_radio_interrupts(); + + //register interrupt + IntRegister(INT_RFCORERTX, radio_isr_internal); + IntRegister(INT_RFCOREERR, radio_error_isr); + + IntEnable(INT_RFCORERTX); + + /* Enable all RF Error interrupts */ + HWREG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM_M; //all errors + IntEnable(INT_RFCOREERR); + //radio_on(); + + // change state + radio_vars.state = RADIOSTATE_RFOFF; +} + +void radio_setStartFrameCb(radio_capture_cbt cb) { + radio_vars.startFrame_cb = cb; +} + +void radio_setEndFrameCb(radio_capture_cbt cb) { + radio_vars.endFrame_cb = cb; +} + +//===== reset + +void radio_reset(void) { + /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + //flush fifos + CC2538_RF_CSP_ISFLUSHRX(); + CC2538_RF_CSP_ISFLUSHTX(); + + /* Don't turn off if we are off as this will trigger a Strobe Error */ + if(HWREG(RFCORE_XREG_RXENABLE) != 0) { + CC2538_RF_CSP_ISRFOFF(); + } + radio_init(); +} + +//===== RF admin + +void radio_setFrequency(uint8_t frequency) { + + // change state + radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; + + radio_off(); + // configure the radio to the right frequecy + if((frequency < CC2538_RF_CHANNEL_MIN) || (frequency > CC2538_RF_CHANNEL_MAX)) { + while(1); + } + + /* Changes to FREQCTRL take effect after the next recalibration */ + HWREG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN + + (frequency - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING); + + //radio_on(); + + // change state + radio_vars.state = RADIOSTATE_FREQUENCY_SET; +} + +void radio_rfOn(void) { + //radio_on(); +} + +void radio_rfOff(void) { + + // change state + radio_vars.state = RADIOSTATE_TURNING_OFF; + radio_off(); + // wiggle debug pin + debugpins_radio_clr(); + leds_radio_off(); + //enable radio interrupts + disable_radio_interrupts(); + + // change state + radio_vars.state = RADIOSTATE_RFOFF; +} + +//===== TX + +void radio_loadPacket(uint8_t* packet, uint16_t len) { + uint8_t i=0; + + // change state + radio_vars.state = RADIOSTATE_LOADING_PACKET; + + // load packet in TXFIFO + /* + When we transmit in very quick bursts, make sure previous transmission + is not still in progress before re-writing to the TX FIFO + */ + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + CC2538_RF_CSP_ISFLUSHTX(); + + /* Send the phy length byte first */ + HWREG(RFCORE_SFR_RFDATA) = len; //crc len is included + + for(i = 0; i < len; i++) { + HWREG(RFCORE_SFR_RFDATA) = packet[i]; + } + + // change state + radio_vars.state = RADIOSTATE_PACKET_LOADED; +} + +void radio_txEnable(void) { + + // change state + radio_vars.state = RADIOSTATE_ENABLING_TX; + + // wiggle debug pin + debugpins_radio_set(); + leds_radio_on(); + + //do nothing -- radio is activated by the strobe on rx or tx + //radio_rfOn(); + + // change state + radio_vars.state = RADIOSTATE_TX_ENABLED; +} + +void radio_txNow(void) { + PORT_TIMER_WIDTH count; + + // change state + radio_vars.state = RADIOSTATE_TRANSMITTING; + + //enable radio interrupts + enable_radio_interrupts(); + + //make sure we are not transmitting already + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + // send packet by STON strobe see pag 669 + + CC2538_RF_CSP_ISTXON(); + //wait 192uS + count=0; + while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE))){ + count++; //debug + } +} + +//===== RX + +void radio_rxEnable(void) { + + // change state + radio_vars.state = RADIOSTATE_ENABLING_RX; + + //enable radio interrupts + + // do nothing as we do not want to receive anything yet. + // wiggle debug pin + debugpins_radio_set(); + leds_radio_on(); + + // change state + radio_vars.state = RADIOSTATE_LISTENING; +} + +void radio_rxNow(void) { + //empty buffer before receiving + //CC2538_RF_CSP_ISFLUSHRX(); + + //enable radio interrupts + CC2538_RF_CSP_ISFLUSHRX(); + enable_radio_interrupts(); + + CC2538_RF_CSP_ISRXON(); + // busy wait until radio really listening + while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_RX_ACTIVE))); +} + +void radio_getReceivedFrame(uint8_t* pBufRead, + uint8_t* pLenRead, + uint8_t maxBufLen, + int8_t* pRssi, + uint8_t* pLqi, + bool* pCrc) { + uint8_t crc_corr,i; + + uint8_t len=0; + + /* Check the length */ + len = HWREG(RFCORE_SFR_RFDATA); //first byte is len + + + /* Check for validity */ + if(len > CC2538_RF_MAX_PACKET_LEN) { + /* wrong len */ + CC2538_RF_CSP_ISFLUSHRX(); + return; + } + + + if(len <= CC2538_RF_MIN_PACKET_LEN) { + //too short + CC2538_RF_CSP_ISFLUSHRX(); + return; + } + + //check if this fits to the buffer + if(len > maxBufLen) { + CC2538_RF_CSP_ISFLUSHRX(); + return; + } + + // when reading the packet from the RX buffer, you get the following: + // - *[1B] length byte + // - [0-125B] packet (excluding CRC) + // - [1B] RSSI + // - *[2B] CRC + + //skip first byte is len + for(i = 0; i < len - 2; i++) { + pBufRead[i] = HWREG(RFCORE_SFR_RFDATA); + } + + *pRssi = ((int8_t)(HWREG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET); + crc_corr = HWREG(RFCORE_SFR_RFDATA); + *pCrc = crc_corr & CRC_BIT_MASK; + *pLenRead = len; + + //flush it + CC2538_RF_CSP_ISFLUSHRX(); +} + +//=========================== private ========================================= + +void enable_radio_interrupts(void){ + /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ + HWREG(RFCORE_XREG_RFIRQM0) |= ((0x06|0x02|0x01) << RFCORE_XREG_RFIRQM0_RFIRQM_S) & RFCORE_XREG_RFIRQM0_RFIRQM_M; + + /* Enable RF interrupts 1, TXDONE only */ + HWREG(RFCORE_XREG_RFIRQM1) |= ((0x02) << RFCORE_XREG_RFIRQM1_RFIRQM_S) & RFCORE_XREG_RFIRQM1_RFIRQM_M; +} + +void disable_radio_interrupts(void){ + /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ + HWREG(RFCORE_XREG_RFIRQM0) = 0; + /* Enable RF interrupts 1, TXDONE only */ + HWREG(RFCORE_XREG_RFIRQM1) = 0; +} + +void radio_on(void){ + // CC2538_RF_CSP_ISFLUSHRX(); + CC2538_RF_CSP_ISRXON(); +} + +void radio_off(void){ + /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + //CC2538_RF_CSP_ISFLUSHRX(); + + /* Don't turn off if we are off as this will trigger a Strobe Error */ + if(HWREG(RFCORE_XREG_RXENABLE) != 0) { + CC2538_RF_CSP_ISRFOFF(); + //clear fifo isr flag + HWREG(RFCORE_SFR_RFIRQF0) = ~(RFCORE_SFR_RFIRQF0_FIFOP|RFCORE_SFR_RFIRQF0_RXPKTDONE); + } +} + +//=========================== callbacks ======================================= + +//=========================== interrupt handlers ============================== + +/** +\brief Stub function for the CC2538. + +In MSP430 platforms the CPU status after servicing an interrupt can be managed +toggling some bits in a special register, e.g. CPUOFF, LPM1, etc, within the +interrupt context itself. By default, after servicing an interrupt the CPU will +be off so it makes sense to return a value and enable it if something has +happened that needs the scheduler to run (a packet has been received that needs +to be processed). Otherwise, the CPU is kept in sleep mode without even +reaching the main loop. + +In the CC2538, however, the default behaviour is the contrary. After servicing +an interrupt the CPU will be on by default and it is the responsability of the +main thread to put it back to sleep (which is already done). This means that +the scheduler will always be kicked in after servicing an interrupt. This +behaviour can be changed by modifying the SLEEPEXIT field in the SYSCTRL +regiser (see page 131 of the CC2538 manual). +*/ +kick_scheduler_t radio_isr(void) { + return DO_NOT_KICK_SCHEDULER; +} + +void radio_isr_internal(void) { + volatile PORT_TIMER_WIDTH capturedTime; + uint8_t irq_status0,irq_status1; + + debugpins_isr_set(); + + // capture the time + capturedTime = sctimer_readCounter(); + + // reading IRQ_STATUS + irq_status0 = HWREG(RFCORE_SFR_RFIRQF0); + irq_status1 = HWREG(RFCORE_SFR_RFIRQF1); + + IntPendClear(INT_RFCORERTX); + + //clear interrupt + HWREG(RFCORE_SFR_RFIRQF0) = 0; + HWREG(RFCORE_SFR_RFIRQF1) = 0; + + //STATUS0 Register + // start of frame event + if ((irq_status0 & RFCORE_SFR_RFIRQF0_SFD) == RFCORE_SFR_RFIRQF0_SFD) { + // change state + radio_vars.state = RADIOSTATE_RECEIVING; + if (radio_vars.startFrame_cb!=NULL) { + // call the callback + radio_vars.startFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + + //or RXDONE is full -- we have a packet. + if (((irq_status0 & RFCORE_SFR_RFIRQF0_RXPKTDONE) == RFCORE_SFR_RFIRQF0_RXPKTDONE)) { + // change state + radio_vars.state = RADIOSTATE_TXRX_DONE; + if (radio_vars.endFrame_cb!=NULL) { + // call the callback + radio_vars.endFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + + // or FIFOP is full -- we have a packet. + if (((irq_status0 & RFCORE_SFR_RFIRQF0_FIFOP) == RFCORE_SFR_RFIRQF0_FIFOP)) { + // change state + radio_vars.state = RADIOSTATE_TXRX_DONE; + if (radio_vars.endFrame_cb!=NULL) { + // call the callback + radio_vars.endFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + + //STATUS1 Register + // end of frame event --either end of tx . + if (((irq_status1 & RFCORE_SFR_RFIRQF1_TXDONE) == RFCORE_SFR_RFIRQF1_TXDONE)) { + // change state + radio_vars.state = RADIOSTATE_TXRX_DONE; + if (radio_vars.endFrame_cb!=NULL) { + // call the callback + radio_vars.endFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + debugpins_isr_clr(); + + return; +} + +void radio_error_isr(void){ + uint8_t rferrm; + + rferrm = (uint8_t)HWREG(RFCORE_XREG_RFERRM); + + if ((HWREG(RFCORE_XREG_RFERRM) & (((0x02)< - -#include - -#define FLASH_START_ADDR 0x00200000 -#define BOOTLOADER_BACKDOOR_ENABLE 0xF6FFFFFF // ENABLED: PORT A, PIN 6, LOW -#define BOOTLOADER_BACKDOOR_DISABLE 0xEFFFFFFF // DISABLED -#define SYS_CTRL_EMUOVR 0x400D20B4 -#define SYS_CTRL_I_MAP 0x400D2098 - -//***************************************************************************** -// -// Macro for hardware access, both direct and via the bit-band region. -// -//***************************************************************************** -#ifndef HWREG -#define HWREG(x) \ - (*((volatile unsigned long *)(x))) -#endif - -extern int main (void); - -void ResetISR(void); -void NmiSR(void); -void FaultISR(void); -void IntDefaultHandler(void); - -//***************************************************************************** -// -// Reserve space for the system stack. -// -//***************************************************************************** -static uint32_t pui32Stack[512]; - -//***************************************************************************** -// -// Customer Configuration Area in Lock Page -// Holds Application entry point (bytes 2012 - 2015) and -// Image Valid (bytes 2008 - 2011) and -// Bootloader backdoor (byte 2007) and -// Reserved (byte 2006 - 2004) -// -//***************************************************************************** -typedef struct -{ - uint32_t ui32BootldrCfg; - uint32_t ui32ImageValid; - uint32_t ui32ImageVectorAddr; -} -lockPageCCA_t; - -__attribute__ ((section(".flashcca"), used)) -const lockPageCCA_t __cca = -{ - BOOTLOADER_BACKDOOR_ENABLE, // Bootloader backdoor enabled - 0, // Image valid bytes - FLASH_START_ADDR // Vector table located at flash start address -}; - -__attribute__ ((section(".vectors"), used)) -void (* const gVectors[])(void) = -{ - (void (*)(void))((uint32_t)pui32Stack + sizeof(pui32Stack)), // Stack pointer - ResetISR, // Reset handler - NmiSR, // The NMI handler - FaultISR, // The hard fault handler - IntDefaultHandler, // 4 The MPU fault handler - IntDefaultHandler, // 5 The bus fault handler - IntDefaultHandler, // 6 The usage fault handler - 0, // 7 Reserved - 0, // 8 Reserved - 0, // 9 Reserved - 0, // 10 Reserved - IntDefaultHandler, // 11 SVCall handler - IntDefaultHandler, // 12 Debug monitor handler - 0, // 13 Reserved - IntDefaultHandler, // 14 The PendSV handler - IntDefaultHandler, // 15 The SysTick handler - IntDefaultHandler, // 16 GPIO Port A - IntDefaultHandler, // 17 GPIO Port B - IntDefaultHandler, // 18 GPIO Port C - IntDefaultHandler, // 19 GPIO Port D - 0, // 20 none - IntDefaultHandler, // 21 UART0 Rx and Tx - IntDefaultHandler, // 22 UART1 Rx and Tx - IntDefaultHandler, // 23 SSI0 Rx and Tx - IntDefaultHandler, // 24 I2C Master and Slave - 0, // 25 Reserved - 0, // 26 Reserved - 0, // 27 Reserved - 0, // 28 Reserved - 0, // 29 Reserved - IntDefaultHandler, // 30 ADC Sequence 0 - 0, // 31 Reserved - 0, // 32 Reserved - 0, // 33 Reserved - IntDefaultHandler, // 34 Watchdog timer, timer 0 - IntDefaultHandler, // 35 Timer 0 subtimer A - IntDefaultHandler, // 36 Timer 0 subtimer B - IntDefaultHandler, // 37 Timer 1 subtimer A - IntDefaultHandler, // 38 Timer 1 subtimer B - IntDefaultHandler, // 39 Timer 2 subtimer A - IntDefaultHandler, // 40 Timer 2 subtimer B - IntDefaultHandler, // 41 Analog Comparator 0 - IntDefaultHandler, // 42 RFCore Rx/Tx - IntDefaultHandler, // 43 RFCore Error - IntDefaultHandler, // 44 IcePick - IntDefaultHandler, // 45 FLASH Control - IntDefaultHandler, // 46 AES - IntDefaultHandler, // 47 PKA - IntDefaultHandler, // 48 Sleep Timer - IntDefaultHandler, // 49 MacTimer - IntDefaultHandler, // 50 SSI1 Rx and Tx - IntDefaultHandler, // 51 Timer 3 subtimer A - IntDefaultHandler, // 52 Timer 3 subtimer B - 0, // 53 Reserved - 0, // 54 Reserved - 0, // 55 Reserved - 0, // 56 Reserved - 0, // 57 Reserved - 0, // 58 Reserved - 0, // 59 Reserved - IntDefaultHandler, // 60 USB 2538 - 0, // 61 Reserved - IntDefaultHandler, // 62 uDMA - IntDefaultHandler, // 63 uDMA Error -#ifndef CC2538_USE_ALTERNATE_INTERRUPT_MAP - 0, // 64 64-155 are not in use - 0, // 65 - 0, // 66 - 0, // 67 - 0, // 68 - 0, // 69 - 0, // 70 - 0, // 71 - 0, // 72 - 0, // 73 - 0, // 74 - 0, // 75 - 0, // 76 - 0, // 77 - 0, // 78 - 0, // 79 - 0, // 80 - 0, // 81 - 0, // 82 - 0, // 83 - 0, // 84 - 0, // 85 - 0, // 86 - 0, // 87 - 0, // 88 - 0, // 89 - 0, // 90 - 0, // 91 - 0, // 92 - 0, // 93 - 0, // 94 - 0, // 95 - 0, // 96 - 0, // 97 - 0, // 98 - 0, // 99 - 0, // 100 - 0, // 101 - 0, // 102 - 0, // 103 - 0, // 104 - 0, // 105 - 0, // 106 - 0, // 107 - 0, // 108 - 0, // 109 - 0, // 110 - 0, // 111 - 0, // 112 - 0, // 113 - 0, // 114 - 0, // 115 - 0, // 116 - 0, // 117 - 0, // 118 - 0, // 119 - 0, // 120 - 0, // 121 - 0, // 122 - 0, // 123 - 0, // 124 - 0, // 125 - 0, // 126 - 0, // 127 - 0, // 128 - 0, // 129 - 0, // 130 - 0, // 131 - 0, // 132 - 0, // 133 - 0, // 134 - 0, // 135 - 0, // 136 - 0, // 137 - 0, // 138 - 0, // 139 - 0, // 140 - 0, // 141 - 0, // 142 - 0, // 143 - 0, // 144 - 0, // 145 - 0, // 146 - 0, // 147 - 0, // 148 - 0, // 149 - 0, // 150 - 0, // 151 - 0, // 152 - 0, // 153 - 0, // 154 - 0, // 155 - IntDefaultHandler, // 156 USB - IntDefaultHandler, // 157 RFCORE RX/TX - IntDefaultHandler, // 158 RFCORE Error - IntDefaultHandler, // 159 AES - IntDefaultHandler, // 160 PKA - IntDefaultHandler, // 161 SMTimer - IntDefaultHandler, // 162 MACTimer -#endif -}; - -//***************************************************************************** -// -// The following are constructs created by the linker, indicating where the -// the "data" and "bss" segments reside in memory. The initializers for the -// for the "data" segment resides immediately following the "text" segment. -// -//***************************************************************************** -extern uint32_t _etext; -extern uint32_t _data; -extern uint32_t _edata; -extern uint32_t _bss; -extern uint32_t _ebss; - -// -// And here are the weak interrupt handlers. -// -void -NmiSR (void) -{ - ResetISR(); - while(1) - { - } -} - - -void -FaultISR (void) -{ - while(1) - { - } -} - - -void -IntDefaultHandler (void) -{ - while(1) - { - } -} - -void -ResetISR (void) -{ - uint32_t *pui32Src, *pui32Dest; - - // - // Workaround for PM debug issue - // - HWREG(SYS_CTRL_EMUOVR) = 0xFF; - - - /* Workaround for J-Link debug issue */ - HWREG(NVIC_VTABLE) = (uint32_t)gVectors; - - // - // Copy the data segment initializers from flash to SRAM. - // - pui32Src = &_etext; - for(pui32Dest = &_data; pui32Dest < &_edata; ) - { - *pui32Dest++ = *pui32Src++; - } - - // - // Zero fill the bss segment. - // - __asm(" ldr r0, =_bss\n" - " ldr r1, =_ebss\n" - " mov r2, #0\n" - " .thumb_func\n" - "zero_loop:\n" - " cmp r0, r1\n" - " it lt\n" - " strlt r2, [r0], #4\n" - " blt zero_loop"); - -#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP - // - // Enable alternate interrupt mapping - // - HWREG(SYS_CTRL_I_MAP) |= 1; -#endif - // - // Call the application's entry point. - // - main(); - - // - // End here if return from main() - // - while(1) - { - } -} - +//***************************************************************************** +//! @file startup_gcc.c +//! @brief Startup code for CC2538 for use with GCC. +//! +//! Revised $Date: 2013-04-11 20:13:13 +0200 (Thu, 11 Apr 2013) $ +//! Revision $Revision: 9714 $ +// +// Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//****************************************************************************/ + +#include + +#include + +#define FLASH_START_ADDR 0x00200000 +#define BOOTLOADER_BACKDOOR_ENABLE 0xF6FFFFFF // ENABLED: PORT A, PIN 6, LOW +#define BOOTLOADER_BACKDOOR_DISABLE 0xEFFFFFFF // DISABLED +#define SYS_CTRL_EMUOVR 0x400D20B4 +#define SYS_CTRL_I_MAP 0x400D2098 + +//***************************************************************************** +// +// Macro for hardware access, both direct and via the bit-band region. +// +//***************************************************************************** +#ifndef HWREG +#define HWREG(x) \ + (*((volatile unsigned long *)(x))) +#endif + +extern int main (void); + +void ResetISR(void); +void NmiSR(void); +void FaultISR(void); +void IntDefaultHandler(void); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +static uint32_t pui32Stack[512]; + +//***************************************************************************** +// +// Customer Configuration Area in Lock Page +// Holds Application entry point (bytes 2012 - 2015) and +// Image Valid (bytes 2008 - 2011) and +// Bootloader backdoor (byte 2007) and +// Reserved (byte 2006 - 2004) +// +//***************************************************************************** +typedef struct +{ + uint32_t ui32BootldrCfg; + uint32_t ui32ImageValid; + uint32_t ui32ImageVectorAddr; +} +lockPageCCA_t; + +__attribute__ ((section(".flashcca"), used)) +const lockPageCCA_t __cca = +{ + BOOTLOADER_BACKDOOR_ENABLE, // Bootloader backdoor enabled + 0, // Image valid bytes + FLASH_START_ADDR // Vector table located at flash start address +}; + +__attribute__ ((section(".vectors"), used)) +void (* const gVectors[])(void) = +{ + (void (*)(void))((uint32_t)pui32Stack + sizeof(pui32Stack)), // Stack pointer + ResetISR, // Reset handler + NmiSR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // 4 The MPU fault handler + IntDefaultHandler, // 5 The bus fault handler + IntDefaultHandler, // 6 The usage fault handler + 0, // 7 Reserved + 0, // 8 Reserved + 0, // 9 Reserved + 0, // 10 Reserved + IntDefaultHandler, // 11 SVCall handler + IntDefaultHandler, // 12 Debug monitor handler + 0, // 13 Reserved + IntDefaultHandler, // 14 The PendSV handler + IntDefaultHandler, // 15 The SysTick handler + IntDefaultHandler, // 16 GPIO Port A + IntDefaultHandler, // 17 GPIO Port B + IntDefaultHandler, // 18 GPIO Port C + IntDefaultHandler, // 19 GPIO Port D + 0, // 20 none + IntDefaultHandler, // 21 UART0 Rx and Tx + IntDefaultHandler, // 22 UART1 Rx and Tx + IntDefaultHandler, // 23 SSI0 Rx and Tx + IntDefaultHandler, // 24 I2C Master and Slave + 0, // 25 Reserved + 0, // 26 Reserved + 0, // 27 Reserved + 0, // 28 Reserved + 0, // 29 Reserved + IntDefaultHandler, // 30 ADC Sequence 0 + 0, // 31 Reserved + 0, // 32 Reserved + 0, // 33 Reserved + IntDefaultHandler, // 34 Watchdog timer, timer 0 + IntDefaultHandler, // 35 Timer 0 subtimer A + IntDefaultHandler, // 36 Timer 0 subtimer B + IntDefaultHandler, // 37 Timer 1 subtimer A + IntDefaultHandler, // 38 Timer 1 subtimer B + IntDefaultHandler, // 39 Timer 2 subtimer A + IntDefaultHandler, // 40 Timer 2 subtimer B + IntDefaultHandler, // 41 Analog Comparator 0 + IntDefaultHandler, // 42 RFCore Rx/Tx + IntDefaultHandler, // 43 RFCore Error + IntDefaultHandler, // 44 IcePick + IntDefaultHandler, // 45 FLASH Control + IntDefaultHandler, // 46 AES + IntDefaultHandler, // 47 PKA + IntDefaultHandler, // 48 Sleep Timer + IntDefaultHandler, // 49 MacTimer + IntDefaultHandler, // 50 SSI1 Rx and Tx + IntDefaultHandler, // 51 Timer 3 subtimer A + IntDefaultHandler, // 52 Timer 3 subtimer B + 0, // 53 Reserved + 0, // 54 Reserved + 0, // 55 Reserved + 0, // 56 Reserved + 0, // 57 Reserved + 0, // 58 Reserved + 0, // 59 Reserved + IntDefaultHandler, // 60 USB 2538 + 0, // 61 Reserved + IntDefaultHandler, // 62 uDMA + IntDefaultHandler, // 63 uDMA Error +#ifndef CC2538_USE_ALTERNATE_INTERRUPT_MAP + 0, // 64 64-155 are not in use + 0, // 65 + 0, // 66 + 0, // 67 + 0, // 68 + 0, // 69 + 0, // 70 + 0, // 71 + 0, // 72 + 0, // 73 + 0, // 74 + 0, // 75 + 0, // 76 + 0, // 77 + 0, // 78 + 0, // 79 + 0, // 80 + 0, // 81 + 0, // 82 + 0, // 83 + 0, // 84 + 0, // 85 + 0, // 86 + 0, // 87 + 0, // 88 + 0, // 89 + 0, // 90 + 0, // 91 + 0, // 92 + 0, // 93 + 0, // 94 + 0, // 95 + 0, // 96 + 0, // 97 + 0, // 98 + 0, // 99 + 0, // 100 + 0, // 101 + 0, // 102 + 0, // 103 + 0, // 104 + 0, // 105 + 0, // 106 + 0, // 107 + 0, // 108 + 0, // 109 + 0, // 110 + 0, // 111 + 0, // 112 + 0, // 113 + 0, // 114 + 0, // 115 + 0, // 116 + 0, // 117 + 0, // 118 + 0, // 119 + 0, // 120 + 0, // 121 + 0, // 122 + 0, // 123 + 0, // 124 + 0, // 125 + 0, // 126 + 0, // 127 + 0, // 128 + 0, // 129 + 0, // 130 + 0, // 131 + 0, // 132 + 0, // 133 + 0, // 134 + 0, // 135 + 0, // 136 + 0, // 137 + 0, // 138 + 0, // 139 + 0, // 140 + 0, // 141 + 0, // 142 + 0, // 143 + 0, // 144 + 0, // 145 + 0, // 146 + 0, // 147 + 0, // 148 + 0, // 149 + 0, // 150 + 0, // 151 + 0, // 152 + 0, // 153 + 0, // 154 + 0, // 155 + IntDefaultHandler, // 156 USB + IntDefaultHandler, // 157 RFCORE RX/TX + IntDefaultHandler, // 158 RFCORE Error + IntDefaultHandler, // 159 AES + IntDefaultHandler, // 160 PKA + IntDefaultHandler, // 161 SMTimer + IntDefaultHandler, // 162 MACTimer +#endif +}; + +//***************************************************************************** +// +// The following are constructs created by the linker, indicating where the +// the "data" and "bss" segments reside in memory. The initializers for the +// for the "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern uint32_t _etext; +extern uint32_t _data; +extern uint32_t _edata; +extern uint32_t _bss; +extern uint32_t _ebss; + +// +// And here are the weak interrupt handlers. +// +void +NmiSR (void) +{ + ResetISR(); + while(1) + { + } +} + + +void +FaultISR (void) +{ + while(1) + { + } +} + + +void +IntDefaultHandler (void) +{ + while(1) + { + } +} + +void +ResetISR (void) +{ + uint32_t *pui32Src, *pui32Dest; + + // + // Workaround for PM debug issue + // + HWREG(SYS_CTRL_EMUOVR) = 0xFF; + + + /* Workaround for J-Link debug issue */ + HWREG(NVIC_VTABLE) = (uint32_t)gVectors; + + // + // Copy the data segment initializers from flash to SRAM. + // + pui32Src = &_etext; + for(pui32Dest = &_data; pui32Dest < &_edata; ) + { + *pui32Dest++ = *pui32Src++; + } + + // + // Zero fill the bss segment. + // + __asm(" ldr r0, =_bss\n" + " ldr r1, =_ebss\n" + " mov r2, #0\n" + " .thumb_func\n" + "zero_loop:\n" + " cmp r0, r1\n" + " it lt\n" + " strlt r2, [r0], #4\n" + " blt zero_loop"); + +#ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP + // + // Enable alternate interrupt mapping + // + HWREG(SYS_CTRL_I_MAP) |= 1; +#endif + // + // Call the application's entry point. + // + main(); + + // + // End here if return from main() + // + while(1) + { + } +} + diff --git a/bsp/boards/mimsy2-cc2538/uart.c b/bsp/boards/mimsy2-cc2538/uart.c index d25f036a69..6f5ceaf76e 100644 --- a/bsp/boards/mimsy2-cc2538/uart.c +++ b/bsp/boards/mimsy2-cc2538/uart.c @@ -1,162 +1,162 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "uart" bsp module. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -#include "board.h" -#include "debugpins.h" -#include "uart.h" - -//=========================== defines ========================================= - -#define PIN_UART_RXD GPIO_PIN_0 // PA0 is UART RX -#define PIN_UART_TXD GPIO_PIN_1 // PA1 is UART TX - -//=========================== variables ======================================= - -typedef struct { - uart_tx_cbt txCb; - uart_rx_cbt rxCb; -} uart_vars_t; - -uart_vars_t uart_vars; - -//=========================== prototypes ====================================== - -static void uart_isr_private(void); - -//=========================== public ========================================== - -void uart_init() { - // reset local variables - memset(&uart_vars,0,sizeof(uart_vars_t)); - - // Disable UART function - UARTDisable(UART0_BASE); - - // Disable all UART module interrupts - UARTIntDisable(UART0_BASE, 0x1FFF); - - // Set IO clock as UART clock source - UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); - - // Map UART signals to the correct GPIO pins and configure them as - // hardware controlled. GPIO-A pin 0 and 1 - IOCPinConfigPeriphOutput(GPIO_A_BASE, PIN_UART_TXD, IOC_MUX_OUT_SEL_UART0_TXD); - GPIOPinTypeUARTOutput(GPIO_A_BASE, PIN_UART_TXD); - IOCPinConfigPeriphInput(GPIO_A_BASE, PIN_UART_RXD, IOC_UARTRXD_UART0); - GPIOPinTypeUARTInput(GPIO_A_BASE, PIN_UART_RXD); - - // Configure the UART for 115,200, 8-N-1 operation. - // This function uses SysCtrlClockGet() to get the system clock - // frequency. This could be also be a variable or hard coded value - // instead of a function call. - UARTConfigSetExpClk(UART0_BASE, SysCtrlIOClockGet(), 115200, - (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | - UART_CONFIG_PAR_NONE)); - - // Enable UART hardware - UARTEnable(UART0_BASE); - - // Disable FIFO as we only one 1byte buffer - UARTFIFODisable(UART0_BASE); - - // Raise interrupt at end of tx (not by fifo) - UARTTxIntModeSet(UART0_BASE, UART_TXINT_MODE_EOT); - - // Register isr in the nvic and enable isr at the nvic - UARTIntRegister(UART0_BASE, uart_isr_private); - - // Enable the UART0 interrupt - IntEnable(INT_UART0); -} - -void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb) { - uart_vars.txCb = txCb; - uart_vars.rxCb = rxCb; -} - -void uart_enableInterrupts(){ - UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_TX | UART_INT_RT); -} - -void uart_disableInterrupts(){ - UARTIntDisable(UART0_BASE, UART_INT_RX | UART_INT_TX | UART_INT_RT); -} - -void uart_clearRxInterrupts(){ - UARTIntClear(UART0_BASE, UART_INT_RX | UART_INT_RT); -} - -void uart_clearTxInterrupts(){ - UARTIntClear(UART0_BASE, UART_INT_TX); -} - -void uart_writeByte(uint8_t byteToWrite){ - UARTCharPut(UART0_BASE, byteToWrite); -} - -uint8_t uart_readByte(){ - int32_t i32Char; - i32Char = UARTCharGet(UART0_BASE); - return (uint8_t)(i32Char & 0xFF); -} - -//=========================== interrupt handlers ============================== - -static void uart_isr_private(void){ - uint32_t reg; - debugpins_isr_set(); - - // Read interrupt source - reg = UARTIntStatus(UART0_BASE, true); - - // Clear UART interrupt in the NVIC - IntPendClear(INT_UART0); - - // Process TX interrupt - if(reg & UART_INT_TX){ - uart_tx_isr(); - } - - // Process RX interrupt - if((reg & (UART_INT_RX)) || (reg & (UART_INT_RT))) { - uart_rx_isr(); - } - - debugpins_isr_clr(); -} - -kick_scheduler_t uart_tx_isr() { - uart_clearTxInterrupts(); // TODO: do not clear, but disable when done - if (uart_vars.txCb != NULL) { - uart_vars.txCb(); - } - return DO_NOT_KICK_SCHEDULER; -} - -kick_scheduler_t uart_rx_isr() { - uart_clearRxInterrupts(); // TODO: do not clear, but disable when done - if (uart_vars.rxCb != NULL) { - uart_vars.rxCb(); - } - return DO_NOT_KICK_SCHEDULER; -} +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "uart" bsp module. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include "board.h" +#include "debugpins.h" +#include "uart.h" + +//=========================== defines ========================================= + +#define PIN_UART_RXD GPIO_PIN_0 // PA0 is UART RX +#define PIN_UART_TXD GPIO_PIN_1 // PA1 is UART TX + +//=========================== variables ======================================= + +typedef struct { + uart_tx_cbt txCb; + uart_rx_cbt rxCb; +} uart_vars_t; + +uart_vars_t uart_vars; + +//=========================== prototypes ====================================== + +static void uart_isr_private(void); + +//=========================== public ========================================== + +void uart_init(void) { + // reset local variables + memset(&uart_vars,0,sizeof(uart_vars_t)); + + // Disable UART function + UARTDisable(UART0_BASE); + + // Disable all UART module interrupts + UARTIntDisable(UART0_BASE, 0x1FFF); + + // Set IO clock as UART clock source + UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); + + // Map UART signals to the correct GPIO pins and configure them as + // hardware controlled. GPIO-A pin 0 and 1 + IOCPinConfigPeriphOutput(GPIO_A_BASE, PIN_UART_TXD, IOC_MUX_OUT_SEL_UART0_TXD); + GPIOPinTypeUARTOutput(GPIO_A_BASE, PIN_UART_TXD); + IOCPinConfigPeriphInput(GPIO_A_BASE, PIN_UART_RXD, IOC_UARTRXD_UART0); + GPIOPinTypeUARTInput(GPIO_A_BASE, PIN_UART_RXD); + + // Configure the UART for 115,200, 8-N-1 operation. + // This function uses SysCtrlClockGet() to get the system clock + // frequency. This could be also be a variable or hard coded value + // instead of a function call. + UARTConfigSetExpClk(UART0_BASE, SysCtrlIOClockGet(), 115200, + (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | + UART_CONFIG_PAR_NONE)); + + // Enable UART hardware + UARTEnable(UART0_BASE); + + // Disable FIFO as we only one 1byte buffer + UARTFIFODisable(UART0_BASE); + + // Raise interrupt at end of tx (not by fifo) + UARTTxIntModeSet(UART0_BASE, UART_TXINT_MODE_EOT); + + // Register isr in the nvic and enable isr at the nvic + UARTIntRegister(UART0_BASE, uart_isr_private); + + // Enable the UART0 interrupt + IntEnable(INT_UART0); +} + +void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb) { + uart_vars.txCb = txCb; + uart_vars.rxCb = rxCb; +} + +void uart_enableInterrupts(void) { + UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_TX | UART_INT_RT); +} + +void uart_disableInterrupts(void) { + UARTIntDisable(UART0_BASE, UART_INT_RX | UART_INT_TX | UART_INT_RT); +} + +void uart_clearRxInterrupts(void) { + UARTIntClear(UART0_BASE, UART_INT_RX | UART_INT_RT); +} + +void uart_clearTxInterrupts(void) { + UARTIntClear(UART0_BASE, UART_INT_TX); +} + +void uart_writeByte(uint8_t byteToWrite){ + UARTCharPut(UART0_BASE, byteToWrite); +} + +uint8_t uart_readByte(void) { + int32_t i32Char; + i32Char = UARTCharGet(UART0_BASE); + return (uint8_t)(i32Char & 0xFF); +} + +//=========================== interrupt handlers ============================== + +static void uart_isr_private(void){ + uint32_t reg; + debugpins_isr_set(); + + // Read interrupt source + reg = UARTIntStatus(UART0_BASE, true); + + // Clear UART interrupt in the NVIC + IntPendClear(INT_UART0); + + // Process TX interrupt + if(reg & UART_INT_TX){ + uart_tx_isr(); + } + + // Process RX interrupt + if((reg & (UART_INT_RX)) || (reg & (UART_INT_RT))) { + uart_rx_isr(); + } + + debugpins_isr_clr(); +} + +kick_scheduler_t uart_tx_isr(void) { + uart_clearTxInterrupts(); // TODO: do not clear, but disable when done + if (uart_vars.txCb != NULL) { + uart_vars.txCb(); + } + return DO_NOT_KICK_SCHEDULER; +} + +kick_scheduler_t uart_rx_isr(void) { + uart_clearRxInterrupts(); // TODO: do not clear, but disable when done + if (uart_vars.rxCb != NULL) { + uart_vars.rxCb(); + } + return DO_NOT_KICK_SCHEDULER; +} diff --git a/projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.c b/projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.c new file mode 100644 index 0000000000..4e94ac9ea1 --- /dev/null +++ b/projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.c @@ -0,0 +1,155 @@ +/** +\brief This program shows the use of the "sctimer" bsp module. + +Since the bsp modules for different platforms have the same declaration, you +can use this project with any platform. + +Load this program onto your board, and start running. It will enable the sctimer. +The sctimer is periodic, of period SCTIMER_PERIOD ticks. Each time it elapses: + - the frame debugpin toggles + - the error LED toggles + +\author Tengfei Chang , April 2017. +*/ + +#include "stdint.h" +#include "string.h" +#include "board.h" +#include "debugpins.h" +#include "leds.h" +#include "sctimer.h" +#include "pwm.h" + +//=========================== defines ========================================= + +#define SCTIMER_PERIOD 65535 // @32kHz = 2s + +// turnoff timing +typedef enum { + TURNOFF_STATE_START = 0, // turn on at 0ms + TURNOFF_STATE_1 = 490, // turn off at 15ms + TURNOFF_STATE_2 = 599, // turn off for 18ms + TURNOFF_STATE_3 = 926, // turn on for 28ms + TURNOFF_STATE_4 = 981, // turn off for 30ms + TURNOFF_STATE_END = 1035, // turn on for 31.5ms +} turnoff_timing_t; + +// turnon timing +typedef enum { + TURNON_STATE_START = 0, // turn on at 0ms + TURNON_STATE_1 = 490, // turn off at 15ms + TURNON_STATE_2 = 599, // turn off for 18ms + TURNON_STATE_3 = 754, // turn on for 23ms + TURNON_STATE_4 = 819, // turn off for 25ms + TURNON_STATE_END = 918, // turn on for 28ms +} turnon_timing_t; + +typedef enum { + APP_STATE_START = 0x00, + APP_STATE_1 = 0x01, + APP_STATE_2 = 0x02, + APP_STATE_3 = 0x03, + APP_STATE_4 = 0x04, + APP_STATE_END = 0x05, +} app_state_t; + +//=========================== variables ======================================= + +typedef struct { + uint32_t startOfSlot; // the start time of a turnon/turnoff action + app_state_t state; // state of turnon or turnoff timing + uint8_t tunnOnOrOff; // 1: turn on, 0: turn off +} app_vars_t; + +app_vars_t app_vars; + +//=========================== prototypes ====================================== + +void cb_compare(void); + +//=========================== main ============================================ + +/** +\brief The program starts executing here. +*/ +int mote_main(void) { + + memset(&app_vars,0,sizeof(app_vars_t)); + + // initialize board. + board_init(); + + sctimer_set_callback(cb_compare); + sctimer_setCompare(sctimer_readCounter()+SCTIMER_PERIOD); + + while (1) { + board_sleep(); + } +} + +//=========================== callbacks ======================================= + +void cb_compare(void) { + + // toggle pin + debugpins_frame_toggle(); + + // toggle error led + leds_error_toggle(); + + switch(app_vars.state){ + case APP_STATE_START: + pwm_enable(); + app_vars.startOfSlot = sctimer_readCounter(); + if (app_vars.tunnOnOrOff){ + sctimer_setCompare(app_vars.startOfSlot+TURNON_STATE_1); + } else { + sctimer_setCompare(app_vars.startOfSlot+TURNOFF_STATE_1); + } + break; + case APP_STATE_1: + pwm_disable(); + if (app_vars.tunnOnOrOff){ + sctimer_setCompare(app_vars.startOfSlot+TURNON_STATE_2); + } else { + sctimer_setCompare(app_vars.startOfSlot+TURNOFF_STATE_2); + } + break; + case APP_STATE_2: + pwm_enable(); + if (app_vars.tunnOnOrOff){ + sctimer_setCompare(app_vars.startOfSlot+TURNON_STATE_3); + } else { + sctimer_setCompare(app_vars.startOfSlot+TURNOFF_STATE_3); + } + break; + case APP_STATE_3: + pwm_disable(); + if (app_vars.tunnOnOrOff){ + sctimer_setCompare(app_vars.startOfSlot+TURNON_STATE_4); + } else { + sctimer_setCompare(app_vars.startOfSlot+TURNOFF_STATE_4); + } + break; + case APP_STATE_4: + pwm_enable(); + if (app_vars.tunnOnOrOff){ + sctimer_setCompare(app_vars.startOfSlot+TURNON_STATE_END); + } else { + sctimer_setCompare(app_vars.startOfSlot+TURNOFF_STATE_END); + } + break; + case APP_STATE_END: + pwm_disable(); + sctimer_setCompare(app_vars.startOfSlot+SCTIMER_PERIOD); + break; + } + + if (app_vars.state==APP_STATE_END){ + app_vars.state = APP_STATE_START; + // change turning action + app_vars.tunnOnOrOff = (app_vars.tunnOnOrOff+1) & 0x01; + } else { + app_vars.state++; + } +} diff --git a/projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.ewd b/projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.ewd new file mode 100644 index 0000000000..2b4c1d6207 --- /dev/null +++ b/projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.ewd @@ -0,0 +1,2641 @@ + + + + 2 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 1 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 25 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 0 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + + diff --git a/projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.ewp b/projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.ewp new file mode 100644 index 0000000000..bd9a1c79a3 --- /dev/null +++ b/projects/mimsy2-cc2538/01bsp_infrared/01bsp_infrared.ewp @@ -0,0 +1,2232 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 22 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + bsp + + boards + + openmote-cc2538 + + headers + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ana_regs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_cctest.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_flash_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ints.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_memmap.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_nvic.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_ffsm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_sfr.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_xreg.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_smwdthrosc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_soc_adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_types.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_uart.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udmachctl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_usb.h + + + + source + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\bl_commands.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ecc_curveinfo.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\rom.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.h + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board_info.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cc2538rf.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cryptoengine.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\debugpins.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\eui64.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\i2c.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\leds.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\pwm.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\pwm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\radio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sctimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sensors.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\startup_iar.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\uart.c + + + + $PROJ_DIR$\..\..\..\bsp\boards\board.h + + + $PROJ_DIR$\..\..\..\bsp\boards\cryptoengine.h + + + $PROJ_DIR$\..\..\..\bsp\boards\debugpins.h + + + $PROJ_DIR$\..\..\..\bsp\boards\eui64.h + + + $PROJ_DIR$\..\..\..\bsp\boards\i2c.h + + + $PROJ_DIR$\..\..\..\bsp\boards\leds.h + + + $PROJ_DIR$\..\..\..\bsp\boards\radio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\sctimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\sensors.h + + + $PROJ_DIR$\..\..\..\bsp\boards\spi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\toolchain_defs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\uart.h + + + + chips + + adxl346 + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.c + + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.h + + + + max44009 + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.c + + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.h + + + + sht21 + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.c + + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.h + + + + + + inc + + $PROJ_DIR$\..\..\..\inc\opendefs.h + + + + projects + + $PROJ_DIR$\01bsp_infrared.c + + + + + diff --git a/projects/mimsy2-cc2538/01bsp_sctimer/01bsp_sctimer.ewd b/projects/mimsy2-cc2538/01bsp_sctimer/01bsp_sctimer.ewd new file mode 100644 index 0000000000..892f582d1d --- /dev/null +++ b/projects/mimsy2-cc2538/01bsp_sctimer/01bsp_sctimer.ewd @@ -0,0 +1,2641 @@ + + + + 2 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 1 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 25 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 0 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + + diff --git a/projects/mimsy2-cc2538/01bsp_sctimer/01bsp_sctimer.ewp b/projects/mimsy2-cc2538/01bsp_sctimer/01bsp_sctimer.ewp new file mode 100644 index 0000000000..074b3ff11d --- /dev/null +++ b/projects/mimsy2-cc2538/01bsp_sctimer/01bsp_sctimer.ewp @@ -0,0 +1,2256 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 22 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + bsp + + boards + + openmote-cc2538 + + headers + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ana_regs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_cctest.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_flash_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ints.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_memmap.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_nvic.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_ffsm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_sfr.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_xreg.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_smwdthrosc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_soc_adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_types.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_uart.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udmachctl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_usb.h + + + + source + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\bl_commands.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ecc_curveinfo.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\rom.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.h + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board_info.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\bsp_timer.c + + Debug + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cc2538rf.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cryptoengine.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\debugpins.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\eui64.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\i2c.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\leds.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\radio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\radiotimer.c + + Debug + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sctimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sensors.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\startup_iar.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\uart.c + + + + $PROJ_DIR$\..\..\..\bsp\boards\board.h + + + $PROJ_DIR$\..\..\..\bsp\boards\bsp_timer.h + + Debug + + + + $PROJ_DIR$\..\..\..\bsp\boards\crypto_engine.h + + + $PROJ_DIR$\..\..\..\bsp\boards\debugpins.h + + + $PROJ_DIR$\..\..\..\bsp\boards\eui64.h + + + $PROJ_DIR$\..\..\..\bsp\boards\i2c.h + + + $PROJ_DIR$\..\..\..\bsp\boards\leds.h + + + $PROJ_DIR$\..\..\..\bsp\boards\radio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\radiotimer.h + + Debug + + + + $PROJ_DIR$\..\..\..\bsp\boards\sctimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\sensors.h + + + $PROJ_DIR$\..\..\..\bsp\boards\spi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\toolchain_defs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\uart.h + + + + chips + + adxl346 + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.c + + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.h + + + + max44009 + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.c + + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.h + + + + sht21 + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.c + + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.h + + + + + + inc + + $PROJ_DIR$\..\..\..\inc\opendefs.h + + + + projects + + common + + 0bsp_sctimer + + $PROJ_DIR$\..\..\common\01bsp_sctimer\01bsp_sctimer.c + + + + + + + diff --git a/projects/mimsy2-cc2538/02drv_opentimers/02drv_opentimers.ewd b/projects/mimsy2-cc2538/02drv_opentimers/02drv_opentimers.ewd new file mode 100644 index 0000000000..8f68883187 --- /dev/null +++ b/projects/mimsy2-cc2538/02drv_opentimers/02drv_opentimers.ewd @@ -0,0 +1,2641 @@ + + + + 2 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 1 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 25 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 0 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + + diff --git a/projects/mimsy2-cc2538/02drv_opentimers/02drv_opentimers.ewp b/projects/mimsy2-cc2538/02drv_opentimers/02drv_opentimers.ewp new file mode 100644 index 0000000000..0bd2be83a8 --- /dev/null +++ b/projects/mimsy2-cc2538/02drv_opentimers/02drv_opentimers.ewp @@ -0,0 +1,2291 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 22 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + bsp + + boards + + openmote-cc2538 + + headers + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ana_regs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_cctest.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_flash_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ints.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_memmap.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_nvic.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_ffsm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_sfr.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_xreg.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_smwdthrosc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_soc_adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_types.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_uart.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udmachctl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_usb.h + + + + source + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\bl_commands.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ecc_curveinfo.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\rom.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.h + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board_info.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\bsp_timer.c + + Debug + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cc2538rf.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cryptoengine.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\debugpins.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\eui64.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\i2c.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\leds.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\radio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\radiotimer.c + + Debug + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sctimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sensors.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\startup_iar.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\uart.c + + + + $PROJ_DIR$\..\..\..\bsp\boards\board.h + + + $PROJ_DIR$\..\..\..\bsp\boards\bsp_timer.h + + Debug + + + + $PROJ_DIR$\..\..\..\bsp\boards\crypto_engine.h + + + $PROJ_DIR$\..\..\..\bsp\boards\debugpins.h + + + $PROJ_DIR$\..\..\..\bsp\boards\eui64.h + + + $PROJ_DIR$\..\..\..\bsp\boards\i2c.h + + + $PROJ_DIR$\..\..\..\bsp\boards\leds.h + + + $PROJ_DIR$\..\..\..\bsp\boards\radio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\radiotimer.h + + Debug + + + + $PROJ_DIR$\..\..\..\bsp\boards\sctimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\sensors.h + + + $PROJ_DIR$\..\..\..\bsp\boards\spi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\toolchain_defs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\uart.h + + + + chips + + adxl346 + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.c + + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.h + + + + max44009 + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.c + + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.h + + + + sht21 + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.c + + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.h + + + + + + drivers + + common + + $PROJ_DIR$\..\..\..\drivers\common\openhdlc.c + + + $PROJ_DIR$\..\..\..\drivers\common\openhdlc.h + + + $PROJ_DIR$\..\..\..\drivers\common\opensensors.c + + + $PROJ_DIR$\..\..\..\drivers\common\opensensors.h + + + $PROJ_DIR$\..\..\..\drivers\common\openserial.c + + Debug + + + + $PROJ_DIR$\..\..\..\drivers\common\openserial.h + + Debug + + + + $PROJ_DIR$\..\..\..\drivers\common\opentimers.c + + + $PROJ_DIR$\..\..\..\drivers\common\opentimers.h + + + + + inc + + $PROJ_DIR$\..\..\..\inc\opendefs.h + + + + projects + + common + + 02drv_opentimers + + $PROJ_DIR$\..\..\common\02drv_opentimers\02drv_opentimers.c + + + + + + + diff --git a/projects/mimsy2-cc2538/03oos_macpong/03oos_macpong.ewd b/projects/mimsy2-cc2538/03oos_macpong/03oos_macpong.ewd new file mode 100644 index 0000000000..8f68883187 --- /dev/null +++ b/projects/mimsy2-cc2538/03oos_macpong/03oos_macpong.ewd @@ -0,0 +1,2641 @@ + + + + 2 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 1 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 25 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 0 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + + diff --git a/projects/mimsy2-cc2538/03oos_macpong/03oos_macpong.ewp b/projects/mimsy2-cc2538/03oos_macpong/03oos_macpong.ewp new file mode 100644 index 0000000000..05943c7d3d --- /dev/null +++ b/projects/mimsy2-cc2538/03oos_macpong/03oos_macpong.ewp @@ -0,0 +1,2395 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 22 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + application + + $PROJ_DIR$\..\..\common\03oos_macpong\03oos_macpong.c + + + $PROJ_DIR$\..\..\common\03oos_macpong\03oos_macpong.h + + + + bsp + + boards + + openmote-CC2538 + + headers + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ana_regs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_cctest.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_flash_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ints.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_memmap.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_nvic.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_ffsm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_sfr.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_xreg.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_smwdthrosc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_soc_adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_types.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_uart.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udmachctl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_usb.h + + + + source + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\bl_commands.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ecc_curveinfo.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\rom.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.h + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board_info.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cc2538rf.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cryptoengine.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\debugpins.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\eui64.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\i2c.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\leds.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\radio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sctimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sensors.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\startup_gcc.c + + Debug + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\startup_iar.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\uart.c + + + + $PROJ_DIR$\..\..\..\bsp\boards\board.h + + + $PROJ_DIR$\..\..\..\bsp\boards\bsp_timer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\debugpins.h + + + $PROJ_DIR$\..\..\..\bsp\boards\eui64.h + + + $PROJ_DIR$\..\..\..\bsp\boards\i2c.h + + + $PROJ_DIR$\..\..\..\bsp\boards\leds.h + + + $PROJ_DIR$\..\..\..\bsp\boards\radio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\radiotimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\sctimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\sensors.h + + + $PROJ_DIR$\..\..\..\bsp\boards\spi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\toolchain_defs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\uart.h + + + + chips + + adxl346 + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.c + + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.h + + + + max44009 + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.c + + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.h + + + + sht21 + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.c + + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.h + + + + + + drivers + + common + + $PROJ_DIR$\..\..\..\drivers\common\openhdlc.c + + + $PROJ_DIR$\..\..\..\drivers\common\openhdlc.h + + + $PROJ_DIR$\..\..\..\drivers\common\opensensors.c + + + $PROJ_DIR$\..\..\..\drivers\common\opensensors.h + + + $PROJ_DIR$\..\..\..\drivers\common\openserial.c + + + $PROJ_DIR$\..\..\..\drivers\common\openserial.h + + + $PROJ_DIR$\..\..\..\drivers\common\opentimers.c + + + $PROJ_DIR$\..\..\..\drivers\common\opentimers.h + + + + + inc + + $PROJ_DIR$\..\..\..\inc\opendefs.h + + + + kernel + + $PROJ_DIR$\..\..\..\kernel\openos\scheduler.c + + + $PROJ_DIR$\..\..\..\kernel\scheduler.h + + + + openstack + + 02a-MAClow + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\adaptive_sync.c + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\adaptive_sync.h + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154.c + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154.h + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154_security.c + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154_security.h + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154E.c + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154E.h + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\topology.c + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\topology.h + + + + 02b-MAChigh + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\neighbors.c + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\neighbors.h + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\processIE.h + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\schedule.c + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\schedule.h + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\msf.c + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\msf.h + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\sixtop.c + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\sixtop.h + + + + cross-layers + + $PROJ_DIR$\..\..\..\openstack\cross-layers\idmanager.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\idmanager.h + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openqueue.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openqueue.h + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openrandom.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openrandom.h + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\packetfunctions.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\packetfunctions.h + + + + $PROJ_DIR$\..\..\..\openstack\openstack.c + + + $PROJ_DIR$\..\..\..\openstack\openstack.h + + + + + diff --git a/projects/mimsy2-cc2538/03oos_openwsn/03oos_openwsn.ewd b/projects/mimsy2-cc2538/03oos_openwsn/03oos_openwsn.ewd new file mode 100644 index 0000000000..9069722465 --- /dev/null +++ b/projects/mimsy2-cc2538/03oos_openwsn/03oos_openwsn.ewd @@ -0,0 +1,2641 @@ + + + + 2 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 1 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 25 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 0 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + + diff --git a/projects/mimsy2-cc2538/03oos_openwsn/03oos_openwsn.ewp b/projects/mimsy2-cc2538/03oos_openwsn/03oos_openwsn.ewp new file mode 100644 index 0000000000..c890268889 --- /dev/null +++ b/projects/mimsy2-cc2538/03oos_openwsn/03oos_openwsn.ewp @@ -0,0 +1,2640 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 22 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + application + + $PROJ_DIR$\..\..\common\03oos_openwsn\03oos_openwsn.c + + + $PROJ_DIR$\..\..\common\03oos_openwsn\03oos_openwsn.h + + + + bsp + + boards + + openmote-CC2538 + + headers + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ana_regs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_cctest.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_flash_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ints.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_memmap.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_nvic.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_ffsm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_sfr.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_xreg.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_smwdthrosc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_soc_adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_types.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_uart.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udmachctl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_usb.h + + + + source + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\bl_commands.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ecc_curveinfo.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\rom.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.h + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board_info.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cc2538rf.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cryptoengine.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\debugpins.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\eui64.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\i2c.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\leds.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\pwm.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\pwm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\radio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sctimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sensors.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\startup_iar.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\uart.c + + + + $PROJ_DIR$\..\..\..\bsp\boards\board.h + + + $PROJ_DIR$\..\..\..\bsp\boards\cryptoengine.h + + + $PROJ_DIR$\..\..\..\bsp\boards\debugpins.h + + + $PROJ_DIR$\..\..\..\bsp\boards\eui64.h + + + $PROJ_DIR$\..\..\..\bsp\boards\i2c.h + + + $PROJ_DIR$\..\..\..\bsp\boards\leds.h + + + $PROJ_DIR$\..\..\..\bsp\boards\radio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\sctimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\spi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\toolchain_defs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\uart.h + + + + chips + + adxl346 + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.c + + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.h + + + + max44009 + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.c + + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.h + + + + sht21 + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.c + + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.h + + + + + + drivers + + common + + $PROJ_DIR$\..\..\..\drivers\common\openhdlc.c + + + $PROJ_DIR$\..\..\..\drivers\common\openhdlc.h + + + $PROJ_DIR$\..\..\..\drivers\common\opensensors.c + + + $PROJ_DIR$\..\..\..\drivers\common\opensensors.h + + + $PROJ_DIR$\..\..\..\drivers\common\openserial.c + + + $PROJ_DIR$\..\..\..\drivers\common\openserial.h + + + $PROJ_DIR$\..\..\..\drivers\common\opentimers.c + + + $PROJ_DIR$\..\..\..\drivers\common\opentimers.h + + + + + inc + + $PROJ_DIR$\..\..\..\inc\opendefs.h + + + + kernel + + $PROJ_DIR$\..\..\..\kernel\openos\scheduler.c + + + $PROJ_DIR$\..\..\..\kernel\scheduler.h + + + + openapps + + c6t + + $PROJ_DIR$\..\..\..\openapps\c6t\c6t.c + + + $PROJ_DIR$\..\..\..\openapps\c6t\c6t.h + + + + cexample + + $PROJ_DIR$\..\..\..\openapps\cexample\cexample.c + + + $PROJ_DIR$\..\..\..\openapps\cexample\cexample.h + + + + cinfo + + $PROJ_DIR$\..\..\..\openapps\cinfo\cinfo.c + + + $PROJ_DIR$\..\..\..\openapps\cinfo\cinfo.h + + + + cinfrared + + $PROJ_DIR$\..\..\..\openapps\cinfrared\cinfrared.c + + + $PROJ_DIR$\..\..\..\openapps\cinfrared\cinfrared.h + + + + cjoin + + $PROJ_DIR$\..\..\..\openapps\cjoin\cbor.c + + + $PROJ_DIR$\..\..\..\openapps\cjoin\cbor.h + + + $PROJ_DIR$\..\..\..\openapps\cjoin\cjoin.c + + + $PROJ_DIR$\..\..\..\openapps\cjoin\cjoin.h + + + + cleds + + $PROJ_DIR$\..\..\..\openapps\cleds\cleds.c + + + $PROJ_DIR$\..\..\..\openapps\cleds\cleds.h + + + + csensors + + $PROJ_DIR$\..\..\..\openapps\csensors\csensors.c + + + $PROJ_DIR$\..\..\..\openapps\csensors\csensors.h + + + + cstorm + + $PROJ_DIR$\..\..\..\openapps\cstorm\cstorm.c + + + $PROJ_DIR$\..\..\..\openapps\cstorm\cstorm.h + + + + cwellknow + + $PROJ_DIR$\..\..\..\openapps\cwellknown\cwellknown.c + + + $PROJ_DIR$\..\..\..\openapps\cwellknown\cwellknown.h + + + + opencoap + + $PROJ_DIR$\..\..\..\openapps\opencoap\cborencoder.c + + + $PROJ_DIR$\..\..\..\openapps\opencoap\cborencoder.h + + + $PROJ_DIR$\..\..\..\openapps\opencoap\hkdf.c + + + $PROJ_DIR$\..\..\..\openapps\opencoap\hmac.c + + + $PROJ_DIR$\..\..\..\openapps\opencoap\opencoap.c + + + $PROJ_DIR$\..\..\..\openapps\opencoap\opencoap.h + + + $PROJ_DIR$\..\..\..\openapps\opencoap\openoscoap.c + + + $PROJ_DIR$\..\..\..\openapps\opencoap\openoscoap.h + + + $PROJ_DIR$\..\..\..\openapps\opencoap\sha-private.h + + + $PROJ_DIR$\..\..\..\openapps\opencoap\sha.h + + + $PROJ_DIR$\..\..\..\openapps\opencoap\sha224-256.c + + + $PROJ_DIR$\..\..\..\openapps\opencoap\usha.c + + + + rrt + + $PROJ_DIR$\..\..\..\openapps\rrt\rrt.c + + + $PROJ_DIR$\..\..\..\openapps\rrt\rrt.h + + + + uecho + + $PROJ_DIR$\..\..\..\openapps\uecho\uecho.c + + + $PROJ_DIR$\..\..\..\openapps\uecho\uecho.h + + + + uexpiration + + $PROJ_DIR$\..\..\..\openapps\uexpiration\uexpiration.c + + + $PROJ_DIR$\..\..\..\openapps\uexpiration\uexpiration.h + + + + uexpiration_monitor + + $PROJ_DIR$\..\..\..\openapps\uexpiration_monitor\uexpiration_monitor.c + + + $PROJ_DIR$\..\..\..\openapps\uexpiration_monitor\uexpiration_monitor.h + + + + uinject + + $PROJ_DIR$\..\..\..\openapps\uinject\uinject.c + + + $PROJ_DIR$\..\..\..\openapps\uinject\uinject.h + + + + userialbridge + + $PROJ_DIR$\..\..\..\openapps\userialbridge\userialbridge.c + + + $PROJ_DIR$\..\..\..\openapps\userialbridge\userialbridge.h + + + + $PROJ_DIR$\..\..\..\openapps\openapps.c + + + $PROJ_DIR$\..\..\..\openapps\openapps.h + + + + openstack + + 02a-MAClow + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\adaptive_sync.c + + Debug + + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\adaptive_sync.h + + Debug + + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154.c + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154.h + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154_security.c + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154_security.h + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154E.c + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\IEEE802154E.h + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\topology.c + + + $PROJ_DIR$\..\..\..\openstack\02a-MAClow\topology.h + + + + 02b-MAChigh + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\msf.c + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\msf.h + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\neighbors.c + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\neighbors.h + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\schedule.c + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\schedule.h + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\sixtop.c + + + $PROJ_DIR$\..\..\..\openstack\02b-MAChigh\sixtop.h + + + + 03a-IPHC + + $PROJ_DIR$\..\..\..\openstack\03a-IPHC\iphc.c + + + $PROJ_DIR$\..\..\..\openstack\03a-IPHC\iphc.h + + + $PROJ_DIR$\..\..\..\openstack\03a-IPHC\openbridge.c + + + $PROJ_DIR$\..\..\..\openstack\03a-IPHC\openbridge.h + + + + 03b-IPv6 + + $PROJ_DIR$\..\..\..\openstack\03b-IPv6\forwarding.c + + + $PROJ_DIR$\..\..\..\openstack\03b-IPv6\forwarding.h + + + $PROJ_DIR$\..\..\..\openstack\03b-IPv6\icmpv6.c + + + $PROJ_DIR$\..\..\..\openstack\03b-IPv6\icmpv6.h + + + $PROJ_DIR$\..\..\..\openstack\03b-IPv6\icmpv6echo.c + + + $PROJ_DIR$\..\..\..\openstack\03b-IPv6\icmpv6echo.h + + + $PROJ_DIR$\..\..\..\openstack\03b-IPv6\icmpv6rpl.c + + + $PROJ_DIR$\..\..\..\openstack\03b-IPv6\icmpv6rpl.h + + + + 04-TRAN + + $PROJ_DIR$\..\..\..\openstack\04-TRAN\openudp.c + + + $PROJ_DIR$\..\..\..\openstack\04-TRAN\openudp.h + + + + cross-layers + + $PROJ_DIR$\..\..\..\openstack\cross-layers\idmanager.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\idmanager.h + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openqueue.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openqueue.h + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openrandom.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openrandom.h + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\packetfunctions.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\packetfunctions.h + + + + $PROJ_DIR$\..\..\..\openstack\openstack.c + + + $PROJ_DIR$\..\..\..\openstack\openstack.h + + + + + diff --git a/projects/mimsy2-cc2538/03oos_sniffer/03oos_sniffer.ewd b/projects/mimsy2-cc2538/03oos_sniffer/03oos_sniffer.ewd new file mode 100644 index 0000000000..8f68883187 --- /dev/null +++ b/projects/mimsy2-cc2538/03oos_sniffer/03oos_sniffer.ewd @@ -0,0 +1,2641 @@ + + + + 2 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 1 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 25 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + + CMSISDAP_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 0 + + + + + + + + + IJET_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 15 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + XDS100_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + + diff --git a/projects/mimsy2-cc2538/03oos_sniffer/03oos_sniffer.ewp b/projects/mimsy2-cc2538/03oos_sniffer/03oos_sniffer.ewp new file mode 100644 index 0000000000..209ec6d39e --- /dev/null +++ b/projects/mimsy2-cc2538/03oos_sniffer/03oos_sniffer.ewp @@ -0,0 +1,2309 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 22 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + application + + $PROJ_DIR$\..\..\common\03oos_sniffer\03oos_sniffer.c + + + $PROJ_DIR$\..\..\common\03oos_sniffer\03oos_sniffer.h + + + + bsp + + boards + + openmote-CC2538 + + headers + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ana_regs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_cctest.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_flash_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_i2cs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ints.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_memmap.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_nvic.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_ffsm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_sfr.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_rfcore_xreg.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_smwdthrosc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_soc_adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_types.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_uart.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_udmachctl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\headers\hw_usb.h + + + + source + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\adc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\aes.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\bl_commands.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ccm.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\cpu.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\debug.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ecc_curveinfo.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\flash.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gpio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\gptimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\i2c_lib.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\interrupt.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ioc.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\pka.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\rom.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sha256.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sleepmode.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\ssi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\sys_ctrl.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\systick.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\uarthal.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\udma.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\source\watchdog.h + + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\adc_sensor.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board.c + + + $PROJ_DIR$\..\..\..\bsp\boards\board.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\board_info.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cc2538rf.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\cryptoengine.c + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\debugpins.c + + + $PROJ_DIR$\..\..\..\bsp\boards\debugpins.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\eui64.c + + + $PROJ_DIR$\..\..\..\bsp\boards\eui64.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\i2c.c + + + $PROJ_DIR$\..\..\..\bsp\boards\i2c.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\leds.c + + + $PROJ_DIR$\..\..\..\bsp\boards\leds.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\radio.c + + + $PROJ_DIR$\..\..\..\bsp\boards\radio.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sctimer.c + + + $PROJ_DIR$\..\..\..\bsp\boards\sctimer.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\sensors.c + + + $PROJ_DIR$\..\..\..\bsp\boards\sensors.h + + + $PROJ_DIR$\..\..\..\bsp\boards\spi.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\startup_iar.c + + + $PROJ_DIR$\..\..\..\bsp\boards\toolchain_defs.h + + + $PROJ_DIR$\..\..\..\bsp\boards\openmote-cc2538\uart.c + + + $PROJ_DIR$\..\..\..\bsp\boards\uart.h + + + + + chips + + adxl346 + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.c + + + $PROJ_DIR$\..\..\..\bsp\chips\adxl346\adxl346.h + + + + max44009 + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.c + + + $PROJ_DIR$\..\..\..\bsp\chips\max44009\max44009.h + + + + sht21 + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.c + + + $PROJ_DIR$\..\..\..\bsp\chips\sht21\sht21.h + + + + + + drivers + + common + + $PROJ_DIR$\..\..\..\drivers\common\openhdlc.c + + + $PROJ_DIR$\..\..\..\drivers\common\openhdlc.h + + + $PROJ_DIR$\..\..\..\drivers\common\opensensors.c + + + $PROJ_DIR$\..\..\..\drivers\common\opensensors.h + + + $PROJ_DIR$\..\..\..\drivers\common\openserial.c + + + $PROJ_DIR$\..\..\..\drivers\common\openserial.h + + + $PROJ_DIR$\..\..\..\drivers\common\opentimers.c + + + $PROJ_DIR$\..\..\..\drivers\common\opentimers.h + + + + + inc + + $PROJ_DIR$\..\..\..\inc\opendefs.h + + + + kernel + + $PROJ_DIR$\..\..\..\kernel\openos\scheduler.c + + + $PROJ_DIR$\..\..\..\kernel\scheduler.h + + + + openstack + + cross-layers + + $PROJ_DIR$\..\..\..\openstack\cross-layers\idmanager.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\idmanager.h + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openrandom.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\openrandom.h + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\packetfunctions.c + + + $PROJ_DIR$\..\..\..\openstack\cross-layers\packetfunctions.h + + + + + + diff --git a/projects/mimsy2-cc2538/Eclipse-format/.cproject b/projects/mimsy2-cc2538/Eclipse-format/.cproject new file mode 100644 index 0000000000..f0ea7b2a18 --- /dev/null +++ b/projects/mimsy2-cc2538/Eclipse-format/.cproject @@ -0,0 +1,454 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_bsp_timer + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_debugpins + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_leds + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_radio + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_radiotimer + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_uart + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + oos_macpong + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + oos_openwsn + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_bsp_timer + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_debugpins + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_leds + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_radio + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_radiotimer + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_uart + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c oos_macpong + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c oos_openwsn + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_radio_rx + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_radio_tx + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_radio_rx + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_radio_tx + + true + + true + + true + + + + + + + + diff --git a/projects/mimsy2-cc2538/Eclipse-format/.project b/projects/mimsy2-cc2538/Eclipse-format/.project new file mode 100644 index 0000000000..052a0bd22e --- /dev/null +++ b/projects/mimsy2-cc2538/Eclipse-format/.project @@ -0,0 +1,133 @@ + + + OpenWSN + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + OpenMote-CC2538 + 2 + PARENT-3-PROJECT_LOC/bsp/boards/OpenMote-CC2538 + + + drivers_common + 2 + PARENT-3-PROJECT_LOC/drivers/common + + + inc + 2 + PARENT-3-PROJECT_LOC/inc + + + kernel + 2 + PARENT-3-PROJECT_LOC/kernel + + + openapps + 2 + PARENT-3-PROJECT_LOC/openapps + + + openstack + 2 + PARENT-3-PROJECT_LOC/openstack + + + projects + 2 + PARENT-3-PROJECT_LOC/projects/common + + + OpenMote-CC2538/board.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/board.h + + + OpenMote-CC2538/bsp_timer.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/bsp_timer.h + + + OpenMote-CC2538/debugpins.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/debugpins.h + + + OpenMote-CC2538/eui64.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/eui64.h + + + OpenMote-CC2538/i2c.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/i2c.h + + + OpenMote-CC2538/leds.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/leds.h + + + OpenMote-CC2538/radio.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/radio.h + + + OpenMote-CC2538/radiotimer.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/radiotimer.h + + + OpenMote-CC2538/sensors.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/sensors.h + + + OpenMote-CC2538/toolchain_defs.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/toolchain_defs.h + + + OpenMote-CC2538/uart.h + 1 + PARENT-3-PROJECT_LOC/bsp/boards/uart.h + + + drivers_OpenMote-CC2538/adxl346 + 2 + PARENT-3-PROJECT_LOC/bsp/chips/adxl346 + + + drivers_OpenMote-CC2538/max44009 + 2 + PARENT-3-PROJECT_LOC/bsp/chips/max44009 + + + drivers_OpenMote-CC2538/sht21 + 2 + PARENT-3-PROJECT_LOC/bsp/chips/sht21 + + + diff --git a/projects/mimsy2-cc2538/Eclipse-format/.settings/language.settings.xml b/projects/mimsy2-cc2538/Eclipse-format/.settings/language.settings.xml new file mode 100644 index 0000000000..bbbb4252ef --- /dev/null +++ b/projects/mimsy2-cc2538/Eclipse-format/.settings/language.settings.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/mimsy2-cc2538/Eclipse-format/OpenWSN Debug.launch b/projects/mimsy2-cc2538/Eclipse-format/OpenWSN Debug.launch new file mode 100644 index 0000000000..27c2c01ecd --- /dev/null +++ b/projects/mimsy2-cc2538/Eclipse-format/OpenWSN Debug.launch @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/mimsy2-cc2538/Eclipse-format/README.txt b/projects/mimsy2-cc2538/Eclipse-format/README.txt new file mode 100644 index 0000000000..6747252da3 --- /dev/null +++ b/projects/mimsy2-cc2538/Eclipse-format/README.txt @@ -0,0 +1,50 @@ +OpenMote-CC2538 Eclipse project: howto +-------------------------------------- + + +Software required: +--------------------- + +- GNU ARM Gcc toolchain - https://launchpad.net/gcc-arm-embedded +- Eclipse CDT Kepler - http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/keplersr2 +- SEGGER jlink software - https://www.segger.com/jlink-software.html + + +Eclipse J-Link Debugging plug-in intallation: +--------------------------------- + +- Run Eclipse +- Choose your favourite workspace +- Close the initial Welcome screen +- Go to Help -> Install New Software +- Add into "Work with:" the following repository: "GNU ARM Eclipse Plug-ins - http://gnuarmeclipse.sourceforge.net/updates" +- Under "GNU ARM C/C++ Cross Development Tools" select GNU ARM C/C++ J-Link Debugging +- Press Finish and go ahead accepting the installation + + +Configuring the Eclipse environment: +----------------------------------- + +- Go to Window -> Preferences -> C/C++ -> Build -> Environment and add a new environment variable SCONS, whose value is "scons" for UNIX/Linux/MACOS users or "scons.bat" for Windows users +- Go to Window -> Preferences -> Run/Debug -> String Substitution and set the jlink_path variable to the path of the SEGGER J-Link installation folder +- For Windows users, it is suggested to embed the J-Link Server into Eclipse: go to Window -> Preferences -> Run/Debug -> String Substitution and set jlink_gdbserver to JLinkGDBServerCL + + +Importing OpenMote-CC2538 project: +--------------------------------- + +- Go into ${openwsn-fw}/projects/OpenMote-CC2538 and create a copy of the Eclipse-format folder +- Rename the folder to your favourite name, e.g., OPENWSNECLIPSE +- Into Eclipse, right-click in the Project Explorer and click Import... +- Select General -> Existing Projects into Workspace and press Next +- Select root directory and Browse to ${openwsn-fw}/projects/OpenMote-CC2538/OPENWSNECLIPSE and press Finish + + +Building and Debugging: +---------------------- + +- On the right window go to the "Make Target" tab and compile a target, e.g., oos_openwsn +- You can check that building is ok into the bottom window on the Console tab +- Go to Run -> Debug Configurations -> GDB SEGGER J-Link Debugging and go into the sub-configuration "OpenWSN Debug" +- In the Main tab go to C/C++ Application and press "Search Project": you will see the executable you want to flash to the mote, select it and press Debug +- You can now flash the code on your mote and debug the code \ No newline at end of file diff --git a/projects/mimsy2-cc2538/SConscript b/projects/mimsy2-cc2538/SConscript new file mode 100644 index 0000000000..3e25e12d83 --- /dev/null +++ b/projects/mimsy2-cc2538/SConscript @@ -0,0 +1,5 @@ +import os + +Import('env') + +env.ProjectFinder() diff --git a/projects/mimsy2-cc2538/SConscript.env b/projects/mimsy2-cc2538/SConscript.env new file mode 100644 index 0000000000..d27a43ebef --- /dev/null +++ b/projects/mimsy2-cc2538/SConscript.env @@ -0,0 +1,27 @@ +import os + +Import('env') + +# create build environment +buildEnv = env.Clone() + +# inherit environment from user (PATH, etc) +buildEnv['ENV'] = os.environ + +# choose bsp. Normally this would be the same as the board name, +# however, there are cases where one might want to make separate build +# configuration for the same board. +buildEnv['BSP'] = buildEnv['board'] + +bsp_dir = os.path.join('#','bsp','boards',buildEnv['board']) + +# include board/bsp-specific directories +buildEnv.Append( + CPPPATH = [ + bsp_dir, + os.path.join(bsp_dir,'inc'), + os.path.join(bsp_dir,'source'), + ] +) + +Return('buildEnv') diff --git a/projects/mimsy2-cc2538/cc2538_gdb.gdb b/projects/mimsy2-cc2538/cc2538_gdb.gdb new file mode 100644 index 0000000000..6eb8be13c6 --- /dev/null +++ b/projects/mimsy2-cc2538/cc2538_gdb.gdb @@ -0,0 +1,14 @@ +target remote localhost:2331 +monitor interface JTAG +monitor endian little +monitor speed auto +monitor flash device = CC2538SF53 +monitor flash breakpoints = 1 +monitor flash download = 1 +monitor reset +load +monitor reset +monitor halt +break main +continue + diff --git a/projects/mimsy2-cc2538/openmote_cc2538.eww b/projects/mimsy2-cc2538/openmote_cc2538.eww new file mode 100644 index 0000000000..dcd3eb992e --- /dev/null +++ b/projects/mimsy2-cc2538/openmote_cc2538.eww @@ -0,0 +1,49 @@ + + + + + $WS_DIR$\01bsp_infrared\01bsp_infrared.ewp + + + $WS_DIR$\01bsp_sctimer\01bsp_sctimer.ewp + + + $WS_DIR$\02drv_opentimers\02drv_opentimers.ewp + + + $WS_DIR$\03oos_macpong\03oos_macpong.ewp + + + $WS_DIR$\03oos_openwsn\03oos_openwsn.ewp + + + $WS_DIR$\03oos_sniffer\03oos_sniffer.ewp + + + + all_debug + + 01bsp_sctimer + Debug + + + 02drv_opentimers + Debug + + + 03oos_macpong + Debug + + + 03oos_openwsn + Debug + + + 03oos_sniffer + Debug + + + + + + diff --git a/projects/openmote-cc2538/Eclipse-format/.cproject b/projects/openmote-cc2538/Eclipse-format/.cproject index cdd5646501..f0ea7b2a18 100644 --- a/projects/openmote-cc2538/Eclipse-format/.cproject +++ b/projects/openmote-cc2538/Eclipse-format/.cproject @@ -1,228 +1,454 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - bsp_bsp_timer - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - bsp_debugpins - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - bsp_leds - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - bsp_radio - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - bsp_radiotimer - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - bsp_uart - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - oos_macpong - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - oos_openwsn - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c bsp_bsp_timer - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c bsp_debugpins - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c bsp_leds - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c bsp_radio - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c bsp_radiotimer - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c bsp_uart - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c oos_macpong - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c oos_openwsn - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - bsp_radio_rx - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - bsp_radio_tx - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c bsp_radio_rx - true - true - true - - - ${SCONS} - board=OpenMote-CC2538 toolchain=armgcc - -c bsp_radio_tx - true - true - true - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_bsp_timer + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_debugpins + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_leds + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_radio + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_radiotimer + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_uart + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + oos_macpong + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + oos_openwsn + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_bsp_timer + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_debugpins + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_leds + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_radio + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_radiotimer + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_uart + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c oos_macpong + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c oos_openwsn + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_radio_rx + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + bsp_radio_tx + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_radio_rx + + true + + true + + true + + + + + + ${SCONS} + + board=OpenMote-CC2538 toolchain=armgcc + + -c bsp_radio_tx + + true + + true + + true + + + + + + + diff --git a/projects/openmote-cc2538/Eclipse-format/.settings/language.settings.xml b/projects/openmote-cc2538/Eclipse-format/.settings/language.settings.xml new file mode 100644 index 0000000000..bbbb4252ef --- /dev/null +++ b/projects/openmote-cc2538/Eclipse-format/.settings/language.settings.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/openmote-cc2538/Eclipse-format/OpenWSN Debug.launch b/projects/openmote-cc2538/Eclipse-format/OpenWSN Debug.launch index 27c2c01ecd..248034637b 100644 --- a/projects/openmote-cc2538/Eclipse-format/OpenWSN Debug.launch +++ b/projects/openmote-cc2538/Eclipse-format/OpenWSN Debug.launch @@ -1,82 +1,83 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +