diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/cc13xx-cc26xx-conf.h b/arch/cpu/simplelink-cc13xx-cc26xx/cc13xx-cc26xx-conf.h index 87fa922b9..49013070e 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/cc13xx-cc26xx-conf.h +++ b/arch/cpu/simplelink-cc13xx-cc26xx/cc13xx-cc26xx-conf.h @@ -133,6 +133,32 @@ #define RF_MODE RF_CONF_MODE #endif /* RF_CONF_MODE */ +/* Sub-1 GHz path front-end mode configuration */ +#ifdef RF_SUB_1_GHZ_CONF_FRONT_END_MODE +#define RF_SUB_1_GHZ_FRONT_END_MODE RF_SUB_1_GHZ_CONF_FRONT_END_MODE +#else +#define RF_SUB_1_GHZ_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#endif + +#ifdef RF_SUB_1_GHZ_CONF_BIAS_MODE +#define RF_SUB_1_GHZ_BIAS_MODE RF_SUB_1_GHZ_CONF_BIAS_MODE +#else +#define RF_SUB_1_GHZ_BIAS_MODE RF_BIAS_MODE_INTERNAL +#endif + +/* 2.4 GHz path front-end mode configuration */ +#ifdef RF_2_4_GHZ_CONF_FRONT_END_MODE +#define RF_2_4_GHZ_FRONT_END_MODE RF_2_4_GHZ_CONF_FRONT_END_MODE +#else +#define RF_2_4_GHZ_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#endif + +#ifdef RF_2_4_GHZ_CONF_BIAS_MODE +#define RF_2_4_GHZ_BIAS_MODE RF_2_4_GHZ_CONF_BIAS_MODE +#else +#define RF_2_4_GHZ_BIAS_MODE RF_BIAS_MODE_INTERNAL +#endif + /* Number of RX buffers. */ #ifndef RF_CONF_RX_BUF_CNT #define RF_CONF_RX_BUF_CNT 4 diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/dev/gpio-hal-arch.c b/arch/cpu/simplelink-cc13xx-cc26xx/dev/gpio-hal-arch.c index e219faa93..f07a1f693 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/dev/gpio-hal-arch.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/dev/gpio-hal-arch.c @@ -96,7 +96,7 @@ to_hal_cfg(PIN_Config pin_cfg, gpio_hal_pin_cfg_t *cfg) /* Input config */ if(pin_cfg & PIN_BM_INPUT_MODE) { /* Hysteresis config */ - if((pin_cfg & PIN_BM_HYSTERESIS) == PIN_HYSTERESIS) { + if((pin_cfg & PIN_BM_HYSTERESIS) == PIN_BM_HYSTERESIS) { *cfg |= GPIO_HAL_PIN_CFG_HYSTERESIS; } diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ble-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ble-settings.c index 7fc79ae2d..f9902f826 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ble-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ble-settings.c @@ -56,12 +56,18 @@ /* TI-RTOS RF Mode Object */ RF_Mode rf_ble_mode = { - .rfMode = RF_MODE_BLE, + .rfMode = RF_MODE_MULTIPLE, .cpePatchFxn = &rf_patch_cpe_ble, .mcePatchFxn = 0, .rfePatchFxn = &rf_patch_rfe_ble, }; /*---------------------------------------------------------------------------*/ +/* + * CMD_RADIO_SETUP must be configured with default TX power value + * in the .txPower field. + */ +#define DEFAULT_TX_POWER 0x5F3C /* 5 dBm */ +/*---------------------------------------------------------------------------*/ /* Overrides for CMD_RADIO_SETUP */ uint32_t rf_ble_overrides[] CC_ALIGN(4) = { @@ -109,46 +115,14 @@ rfc_CMD_RADIO_SETUP_t rf_ble_cmd_radio_setup = .condition.nSkip = 0x0, .mode = 0x00, .loDivider = 0x00, - .config.frontEndMode = 0x0, - .config.biasMode = 0x0, + .config.frontEndMode = 0x0, /* set by driver */ + .config.biasMode = 0x0, /* set by driver */ .config.analogCfgMode = 0x0, .config.bNoFsPowerUp = 0x0, - .txPower = 0x3D3F, + .txPower = DEFAULT_TX_POWER, .pRegOverride = rf_ble_overrides, }; /*---------------------------------------------------------------------------*/ -/* Structure for CMD_BLE_ADV_NC.pParams */ -rfc_bleAdvPar_t rf_ble_adv_par = -{ - .pRxQ = 0, - .rxConfig.bAutoFlushIgnored = 0x0, - .rxConfig.bAutoFlushCrcErr = 0x0, - .rxConfig.bAutoFlushEmpty = 0x0, - .rxConfig.bIncludeLenByte = 0x0, - .rxConfig.bIncludeCrc = 0x0, - .rxConfig.bAppendRssi = 0x0, - .rxConfig.bAppendStatus = 0x0, - .rxConfig.bAppendTimestamp = 0x0, - .advConfig.advFilterPolicy = 0x0, - .advConfig.deviceAddrType = 0x0, - .advConfig.peerAddrType = 0x0, - .advConfig.bStrictLenFilter = 0x0, - .advConfig.rpaMode = 0x0, - .advLen = 0x18, - .scanRspLen = 0x00, - .pAdvData = 0, - .pScanRspData = 0, - .pDeviceAddress = 0, - .pWhiteList = 0, - .__dummy0 = 0x0000, - .__dummy1 = 0x00, - .endTrigger.triggerType = TRIG_NEVER, - .endTrigger.bEnaCmd = 0x0, - .endTrigger.triggerNo = 0x0, - .endTrigger.pastTrig = 0x0, - .endTime = 0x00000000, -}; -/*---------------------------------------------------------------------------*/ /* CMD_BLE_ADV_NC: BLE Non-Connectable Advertiser Command */ rfc_CMD_BLE_ADV_NC_t rf_ble_cmd_ble_adv_nc = { @@ -159,13 +133,13 @@ rfc_CMD_BLE_ADV_NC_t rf_ble_cmd_ble_adv_nc = .startTrigger.triggerType = TRIG_NOW, .startTrigger.bEnaCmd = 0x0, .startTrigger.triggerNo = 0x0, - .startTrigger.pastTrig = 0x0, - .condition.rule = COND_NEVER, + .startTrigger.pastTrig = 0x1, + .condition.rule = 0x0, /* set by driver */ .condition.nSkip = 0x0, - .channel = 0x8C, - .whitening.init = 0x51, + .channel = 0x00, /* set by driver */ + .whitening.init = 0x00, /* set by driver */ .whitening.bOverride = 0x1, - .pParams = &rf_ble_adv_par, - .pOutput = 0, + .pParams = 0x00000000, /* set by driver */ + .pOutput = 0x00000000, /* set by driver */ }; /*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ble-settings.h b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ble-settings.h index 81fbf67ba..4d94edca8 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ble-settings.h +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ble-settings.h @@ -43,7 +43,6 @@ extern RF_Mode rf_ble_mode; /*---------------------------------------------------------------------------*/ /* RF Core API commands */ extern rfc_CMD_RADIO_SETUP_t rf_ble_cmd_radio_setup; -extern rfc_bleAdvPar_t rf_ble_adv_par; extern rfc_CMD_BLE_ADV_NC_t rf_ble_cmd_ble_adv_nc; /*---------------------------------------------------------------------------*/ /* RF Core API Overrides */ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.c index 2a383e6c6..1537f693c 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.c @@ -57,7 +57,7 @@ /* TI-RTOS RF Mode Object */ RF_Mode rf_ieee_mode = { - .rfMode = RF_MODE_IEEE_15_4, + .rfMode = RF_MODE_MULTIPLE, .cpePatchFxn = 0, .mcePatchFxn = 0, .rfePatchFxn = 0, @@ -110,8 +110,8 @@ rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup = .condition.rule = COND_NEVER, .condition.nSkip = 0x0, .mode = 0x01, - .config.frontEndMode = 0x0, - .config.biasMode = 0x0, + .config.frontEndMode = 0x0, /* set by driver */ + .config.biasMode = 0x0, /* set by driver */ .config.analogCfgMode = 0x0, .config.bNoFsPowerUp = 0x0, .txPower = DEFAULT_TX_POWER, /* 5 dBm default */ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/prop-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/prop-settings.c index 64dbe591f..3d57fc3a3 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/prop-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x0/prop-settings.c @@ -68,7 +68,7 @@ /* TI-RTOS RF Mode Object */ RF_Mode rf_prop_mode = { - .rfMode = RF_MODE_PROPRIETARY_SUB_1, + .rfMode = RF_MODE_MULTIPLE, .cpePatchFxn = &rf_patch_cpe_genfsk, .mcePatchFxn = 0, .rfePatchFxn = &rf_patch_rfe_genfsk, diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ble-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ble-settings.c index b9e32a04d..b43ce21a6 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ble-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ble-settings.c @@ -47,7 +47,7 @@ #include DeviceFamily_constructPath(driverlib/rf_mailbox.h) #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h) #include DeviceFamily_constructPath(driverlib/rf_ble_cmd.h) -#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_bt5.h) +#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_multi_protocol.h) #include DeviceFamily_constructPath(rf_patches/rf_patch_rfe_bt5.h) #include DeviceFamily_constructPath(rf_patches/rf_patch_mce_bt5.h) @@ -59,11 +59,17 @@ RF_Mode rf_ble_mode = { .rfMode = RF_MODE_AUTO, - .cpePatchFxn = &rf_patch_cpe_bt5, + .cpePatchFxn = &rf_patch_cpe_multi_protocol, .mcePatchFxn = &rf_patch_mce_bt5, .rfePatchFxn = &rf_patch_rfe_bt5, }; /*---------------------------------------------------------------------------*/ +/* + * CMD_RADIO_SETUP must be configured with default TX power value + * in the .txPower field. + */ +#define DEFAULT_TX_POWER 0x941E /* 5 dBm */ +/*---------------------------------------------------------------------------*/ /* Overrides for CMD_BLE5_RADIO_SETUP */ uint32_t rf_ble_overrides_common[] CC_ALIGN(4) = { @@ -137,71 +143,39 @@ rfc_CMD_BLE5_RADIO_SETUP_t rf_ble_cmd_radio_setup = .defaultPhy.mainMode = 0x0, .defaultPhy.coding = 0x0, .loDivider = 0x00, - .config.frontEndMode = 0x0, - .config.biasMode = 0x0, + .config.frontEndMode = 0x0, /* set by driver */ + .config.biasMode = 0x0, /* set by driver */ .config.analogCfgMode = 0x0, .config.bNoFsPowerUp = 0x0, - .txPower = 0x941E, + .txPower = DEFAULT_TX_POWER, .pRegOverrideCommon = rf_ble_overrides_common, .pRegOverride1Mbps = rf_ble_overrides_1mbps, .pRegOverride2Mbps = rf_ble_overrides_2mbps, .pRegOverrideCoded = rf_ble_overrides_coded, }; /*---------------------------------------------------------------------------*/ -/* Structure for CMD_BLE5_ADV_NC.pParams */ -rfc_bleAdvPar_t rf_ble_adv_par = -{ - .pRxQ = 0, - .rxConfig.bAutoFlushIgnored = 0x0, - .rxConfig.bAutoFlushCrcErr = 0x0, - .rxConfig.bAutoFlushEmpty = 0x0, - .rxConfig.bIncludeLenByte = 0x0, - .rxConfig.bIncludeCrc = 0x0, - .rxConfig.bAppendRssi = 0x0, - .rxConfig.bAppendStatus = 0x0, - .rxConfig.bAppendTimestamp = 0x0, - .advConfig.advFilterPolicy = 0x0, - .advConfig.deviceAddrType = 0x0, - .advConfig.peerAddrType = 0x0, - .advConfig.bStrictLenFilter = 0x0, - .advConfig.rpaMode = 0x0, - .advLen = 0x18, - .scanRspLen = 0x00, - .pAdvData = 0, - .pScanRspData = 0, - .pDeviceAddress = 0, - .pWhiteList = 0, - .__dummy0 = 0x0000, - .__dummy1 = 0x00, - .endTrigger.triggerType = TRIG_NEVER, - .endTrigger.bEnaCmd = 0x0, - .endTrigger.triggerNo = 0x0, - .endTrigger.pastTrig = 0x0, - .endTime = 0x00000000, -}; -/*---------------------------------------------------------------------------*/ /* CMD_BLE5_ADV_NC: Bluetooth 5 Non-Connectable Advertiser Command */ rfc_CMD_BLE5_ADV_NC_t rf_ble_cmd_ble_adv_nc = { - .commandNo = 0x182D, - .status = 0x0000, - .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx + .commandNo = CMD_BLE5_ADV_NC, + .status = IDLE, + .pNextOp = 0, .startTime = 0x00000000, - .startTrigger.triggerType = 0x0, + .startTrigger.triggerType = TRIG_NOW, .startTrigger.bEnaCmd = 0x0, .startTrigger.triggerNo = 0x0, - .startTrigger.pastTrig = 0x0, - .condition.rule = 0x1, + .startTrigger.pastTrig = 0x1, + .condition.rule = 0x0, /* set by driver */ .condition.nSkip = 0x0, - .channel = 0x8C, - .whitening.init = 0x51, + .channel = 0x00, /* set by driver */ + .whitening.init = 0x00, /* set by driver */ .whitening.bOverride = 0x1, .phyMode.mainMode = 0x0, .phyMode.coding = 0x0, .rangeDelay = 0x00, .txPower = 0x0000, - .pParams = &rf_ble_adv_par, - .pOutput = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx + .pParams = 0x00000000, /* set by driver */ + .pOutput = 0x00000000, /* set by driver */ .tx20Power = 0x00000000, }; /*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ble-settings.h b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ble-settings.h index 2e6defa71..c5295c868 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ble-settings.h +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ble-settings.h @@ -43,7 +43,6 @@ extern RF_Mode rf_ble_mode; /*---------------------------------------------------------------------------*/ /* RF Core API commands */ extern rfc_CMD_BLE5_RADIO_SETUP_t rf_ble_cmd_radio_setup; -extern rfc_bleAdvPar_t rf_ble_adv_par; extern rfc_CMD_BLE5_ADV_NC_t rf_ble_cmd_ble_adv_nc; /*---------------------------------------------------------------------------*/ /* RF Core API Overrides */ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.c index 1f5e3d8d7..a81a83385 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.c @@ -51,7 +51,7 @@ #include DeviceFamily_constructPath(driverlib/rf_mailbox.h) #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h) #include DeviceFamily_constructPath(driverlib/rf_ieee_cmd.h) -#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_ieee_802_15_4.h) +#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_multi_protocol.h) #include DeviceFamily_constructPath(rf_patches/rf_patch_mce_ieee_802_15_4.h) #include @@ -62,7 +62,7 @@ RF_Mode rf_ieee_mode = { .rfMode = RF_MODE_AUTO, - .cpePatchFxn = &rf_patch_cpe_ieee_802_15_4, + .cpePatchFxn = &rf_patch_cpe_multi_protocol, .mcePatchFxn = &rf_patch_mce_ieee_802_15_4, .rfePatchFxn = 0, }; @@ -180,8 +180,8 @@ rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup = .condition.nSkip = 0x0, .mode = 0x01, .loDivider = 0x00, - .config.frontEndMode = 0x0, - .config.biasMode = 0x0, + .config.frontEndMode = 0x0, /* set by driver */ + .config.biasMode = 0x0, /* set by driver */ .config.analogCfgMode = 0x0, .config.bNoFsPowerUp = 0x0, .txPower = DEFAULT_TX_POWER, /* 5 dBm default */ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/prop-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/prop-settings.c index c63e6bef7..0f098c5e1 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/prop-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc13x2/prop-settings.c @@ -63,7 +63,7 @@ #include DeviceFamily_constructPath(driverlib/rf_mailbox.h) #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h) #include DeviceFamily_constructPath(driverlib/rf_prop_cmd.h) -#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_prop.h) +#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_multi_protocol.h) #include DeviceFamily_constructPath(rf_patches/rf_patch_rfe_genfsk.h) #include DeviceFamily_constructPath(rf_patches/rf_patch_mce_genfsk.h) @@ -75,7 +75,7 @@ RF_Mode rf_prop_mode = { .rfMode = RF_MODE_AUTO, - .cpePatchFxn = &rf_patch_cpe_prop, + .cpePatchFxn = &rf_patch_cpe_multi_protocol, .mcePatchFxn = &rf_patch_mce_genfsk, .rfePatchFxn = &rf_patch_rfe_genfsk, }; diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ble-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ble-settings.c index 7edc3e487..9c19021fd 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ble-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ble-settings.c @@ -55,12 +55,18 @@ /* TI-RTOS RF Mode Object */ RF_Mode rf_ble_mode = { - .rfMode = RF_MODE_BLE, + .rfMode = RF_MODE_MULTIPLE, .cpePatchFxn = &rf_patch_cpe_ble, .mcePatchFxn = 0, .rfePatchFxn = &rf_patch_rfe_ble, }; /*---------------------------------------------------------------------------*/ +/* + * CMD_RADIO_SETUP must be configured with default TX power value + * in the .txPower field. + */ +#define DEFAULT_TX_POWER 0x9330 /* 5 dBm */ +/*---------------------------------------------------------------------------*/ /* Overrides for CMD_RADIO_SETUP */ uint32_t rf_ble_overrides[] CC_ALIGN(4) = { @@ -105,46 +111,14 @@ rfc_CMD_RADIO_SETUP_t rf_ble_cmd_radio_setup = .condition.nSkip = 0x0, .mode = 0x00, .__dummy0 = 0x00, - .config.frontEndMode = 0x0, - .config.biasMode = 0x0, + .config.frontEndMode = 0x0, /* set by driver */ + .config.biasMode = 0x0, /* set by driver */ .config.analogCfgMode = 0x0, .config.bNoFsPowerUp = 0x0, - .txPower = 0x9330, + .txPower = DEFAULT_TX_POWER, .pRegOverride = rf_ble_overrides, }; /*---------------------------------------------------------------------------*/ -/* Structure for CMD_BLE_ADV_NC.pParams */ -rfc_bleAdvPar_t rf_ble_adv_par = -{ - .pRxQ = 0, - .rxConfig.bAutoFlushIgnored = 0x0, - .rxConfig.bAutoFlushCrcErr = 0x0, - .rxConfig.bAutoFlushEmpty = 0x0, - .rxConfig.bIncludeLenByte = 0x0, - .rxConfig.bIncludeCrc = 0x0, - .rxConfig.bAppendRssi = 0x0, - .rxConfig.bAppendStatus = 0x0, - .rxConfig.bAppendTimestamp = 0x0, - .advConfig.advFilterPolicy = 0x0, - .advConfig.deviceAddrType = 0x0, - .advConfig.peerAddrType = 0x0, - .advConfig.bStrictLenFilter = 0x0, - .advConfig.rpaMode = 0x0, - .advLen = 0x18, - .scanRspLen = 0x00, - .pAdvData = 0, - .pScanRspData = 0, - .pDeviceAddress = 0, - .pWhiteList = 0, - .__dummy0 = 0x0000, - .__dummy1 = 0x00, - .endTrigger.triggerType = TRIG_NEVER, - .endTrigger.bEnaCmd = 0x0, - .endTrigger.triggerNo = 0x0, - .endTrigger.pastTrig = 0x0, - .endTime = 0x00000000, -}; -/*---------------------------------------------------------------------------*/ /* CMD_BLE_ADV_NC: BLE Non-Connectable Advertiser Command */ rfc_CMD_BLE_ADV_NC_t rf_ble_cmd_ble_adv_nc = { @@ -155,13 +129,13 @@ rfc_CMD_BLE_ADV_NC_t rf_ble_cmd_ble_adv_nc = .startTrigger.triggerType = TRIG_NOW, .startTrigger.bEnaCmd = 0x0, .startTrigger.triggerNo = 0x0, - .startTrigger.pastTrig = 0x0, - .condition.rule = COND_NEVER, + .startTrigger.pastTrig = 0x1, + .condition.rule = 0x0, /* set by driver */ .condition.nSkip = 0x0, - .channel = 0x8C, - .whitening.init = 0x51, + .channel = 0x00, /* set by driver */ + .whitening.init = 0x00, /* set by driver */ .whitening.bOverride = 0x1, - .pParams = &rf_ble_adv_par, - .pOutput = 0, + .pParams = 0x00000000, /* set by driver */ + .pOutput = 0x00000000, /* set by driver */ }; /*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ble-settings.h b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ble-settings.h index c89304105..0679265d6 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ble-settings.h +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ble-settings.h @@ -43,7 +43,6 @@ extern RF_Mode rf_ble_mode; /*---------------------------------------------------------------------------*/ /* RF Core API commands */ extern rfc_CMD_RADIO_SETUP_t rf_ble_cmd_radio_setup; -extern rfc_bleAdvPar_t rf_ble_adv_par; extern rfc_CMD_BLE_ADV_NC_t rf_ble_cmd_ble_adv_nc; /*---------------------------------------------------------------------------*/ /* RF Core API Overrides */ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.c index e93561962..4d860109d 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.c @@ -53,7 +53,7 @@ /* TI-RTOS RF Mode Object */ RF_Mode rf_ieee_mode = { - .rfMode = RF_MODE_IEEE_15_4, + .rfMode = RF_MODE_MULTIPLE, .cpePatchFxn = &rf_patch_cpe_ieee, .mcePatchFxn = 0, .rfePatchFxn = 0, @@ -107,8 +107,8 @@ rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup = .condition.nSkip = 0x0, .mode = 0x01, .__dummy0 = 0x00, - .config.frontEndMode = 0x0, - .config.biasMode = 0x0, + .config.frontEndMode = 0x0, /* set by driver */ + .config.biasMode = 0x0, /* set by driver */ .config.analogCfgMode = 0x0, .config.bNoFsPowerUp = 0x0, .txPower = DEFAULT_TX_POWER, /* 5 dBm default */ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ble-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ble-settings.c index 8ee2b2684..21ed73201 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ble-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ble-settings.c @@ -46,7 +46,7 @@ #include DeviceFamily_constructPath(driverlib/rf_mailbox.h) #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h) #include DeviceFamily_constructPath(driverlib/rf_ble_cmd.h) -#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_bt5.h) +#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_multi_protocol.h) #include DeviceFamily_constructPath(rf_patches/rf_patch_rfe_bt5.h) #include DeviceFamily_constructPath(rf_patches/rf_patch_mce_bt5.h) @@ -58,11 +58,17 @@ RF_Mode rf_ble_mode = { .rfMode = RF_MODE_AUTO, - .cpePatchFxn = &rf_patch_cpe_bt5, + .cpePatchFxn = &rf_patch_cpe_multi_protocol, .mcePatchFxn = &rf_patch_mce_bt5, .rfePatchFxn = &rf_patch_rfe_bt5, }; /*---------------------------------------------------------------------------*/ +/* + * CMD_RADIO_SETUP must be configured with default TX power value + * in the .txPower field. + */ +#define DEFAULT_TX_POWER 0x941E /* 5 dBm */ +/*---------------------------------------------------------------------------*/ /* Overrides for CMD_BLE5_RADIO_SETUP */ uint32_t rf_ble_overrides_common[] CC_ALIGN(4) = { @@ -137,71 +143,39 @@ rfc_CMD_BLE5_RADIO_SETUP_t rf_ble_cmd_radio_setup = .defaultPhy.mainMode = 0x0, .defaultPhy.coding = 0x0, .loDivider = 0x00, - .config.frontEndMode = 0x0, - .config.biasMode = 0x0, + .config.frontEndMode = 0x0, /* set by driver */ + .config.biasMode = 0x0, /* set by driver */ .config.analogCfgMode = 0x0, .config.bNoFsPowerUp = 0x0, - .txPower = 0x941E, + .txPower = DEFAULT_TX_POWER, .pRegOverrideCommon = rf_ble_overrides_common, .pRegOverride1Mbps = rf_ble_overrides_1mbps, .pRegOverride2Mbps = rf_ble_overrides_2mbps, .pRegOverrideCoded = rf_ble_overrides_coded, }; /*---------------------------------------------------------------------------*/ -/* Structure for CMD_BLE5_ADV_NC.pParams */ -rfc_bleAdvPar_t rf_ble_adv_par = -{ - .pRxQ = 0, - .rxConfig.bAutoFlushIgnored = 0x0, - .rxConfig.bAutoFlushCrcErr = 0x0, - .rxConfig.bAutoFlushEmpty = 0x0, - .rxConfig.bIncludeLenByte = 0x0, - .rxConfig.bIncludeCrc = 0x0, - .rxConfig.bAppendRssi = 0x0, - .rxConfig.bAppendStatus = 0x0, - .rxConfig.bAppendTimestamp = 0x0, - .advConfig.advFilterPolicy = 0x0, - .advConfig.deviceAddrType = 0x0, - .advConfig.peerAddrType = 0x0, - .advConfig.bStrictLenFilter = 0x0, - .advConfig.rpaMode = 0x0, - .advLen = 0x18, - .scanRspLen = 0x00, - .pAdvData = 0, - .pScanRspData = 0, - .pDeviceAddress = 0, - .pWhiteList = 0, - .__dummy0 = 0x0000, - .__dummy1 = 0x00, - .endTrigger.triggerType = TRIG_NEVER, - .endTrigger.bEnaCmd = 0x0, - .endTrigger.triggerNo = 0x0, - .endTrigger.pastTrig = 0x0, - .endTime = 0x00000000, -}; -/*---------------------------------------------------------------------------*/ /* CMD_BLE5_ADV_NC: Bluetooth 5 Non-Connectable Advertiser Command */ rfc_CMD_BLE5_ADV_NC_t rf_ble_cmd_ble_adv_nc = { - .commandNo = 0x182D, - .status = 0x0000, - .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx + .commandNo = CMD_BLE5_ADV_NC, + .status = IDLE, + .pNextOp = 0, .startTime = 0x00000000, - .startTrigger.triggerType = 0x0, + .startTrigger.triggerType = TRIG_NOW, .startTrigger.bEnaCmd = 0x0, .startTrigger.triggerNo = 0x0, - .startTrigger.pastTrig = 0x0, - .condition.rule = 0x1, + .startTrigger.pastTrig = 0x1, + .condition.rule = 0x0, /* set by driver */ .condition.nSkip = 0x0, - .channel = 0x8C, - .whitening.init = 0x51, + .channel = 0x00, /* set by driver */ + .whitening.init = 0x00, /* set by driver */ .whitening.bOverride = 0x1, .phyMode.mainMode = 0x0, .phyMode.coding = 0x0, .rangeDelay = 0x00, .txPower = 0x0000, - .pParams = &rf_ble_adv_par, - .pOutput = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx + .pParams = 0x00000000, /* set by driver */ + .pOutput = 0x00000000, /* set by driver */ .tx20Power = 0x00000000, }; /*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ble-settings.h b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ble-settings.h index 2e6defa71..c5295c868 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ble-settings.h +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ble-settings.h @@ -43,7 +43,6 @@ extern RF_Mode rf_ble_mode; /*---------------------------------------------------------------------------*/ /* RF Core API commands */ extern rfc_CMD_BLE5_RADIO_SETUP_t rf_ble_cmd_radio_setup; -extern rfc_bleAdvPar_t rf_ble_adv_par; extern rfc_CMD_BLE5_ADV_NC_t rf_ble_cmd_ble_adv_nc; /*---------------------------------------------------------------------------*/ /* RF Core API Overrides */ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.c index cc012da89..d95ff87ba 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.c @@ -44,7 +44,7 @@ #include DeviceFamily_constructPath(driverlib/rf_mailbox.h) #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h) #include DeviceFamily_constructPath(driverlib/rf_ieee_cmd.h) -#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_ieee_802_15_4.h) +#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_multi_protocol.h) #include DeviceFamily_constructPath(rf_patches/rf_patch_mce_ieee_802_15_4.h) #include @@ -55,7 +55,7 @@ RF_Mode rf_ieee_mode = { .rfMode = RF_MODE_AUTO, - .cpePatchFxn = &rf_patch_cpe_ieee_802_15_4, + .cpePatchFxn = &rf_patch_cpe_multi_protocol, .mcePatchFxn = &rf_patch_mce_ieee_802_15_4, .rfePatchFxn = 0, }; @@ -104,8 +104,8 @@ rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup = .condition.nSkip = 0x0, .mode = 0x01, .loDivider = 0x00, - .config.frontEndMode = 0x0, - .config.biasMode = 0x0, + .config.frontEndMode = 0x0, /* set by driver */ + .config.biasMode = 0x0, /* set by driver */ .config.analogCfgMode = 0x0, .config.bNoFsPowerUp = 0x0, .txPower = DEFAULT_TX_POWER, diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-addr.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-addr.c index 357e7e7c5..7a445a229 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-addr.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-addr.c @@ -81,7 +81,7 @@ ble_addr_ptr(void) } /*---------------------------------------------------------------------------*/ int -ble_addr_cpy(uint8_t *dst) +ble_addr_be_cpy(uint8_t *dst) { if(!dst) { return -1; @@ -102,6 +102,23 @@ ble_addr_cpy(uint8_t *dst) } /*---------------------------------------------------------------------------*/ int +ble_addr_le_cpy(uint8_t *dst) +{ + if(!dst) { + return -1; + } + + volatile const uint8_t *const ble_addr = ble_addr_ptr(); + + size_t i; + for(i = 0; i < BLE_ADDR_SIZE; i++) { + dst[i] = ble_addr[i]; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +int ble_addr_to_eui64(uint8_t *dst, uint8_t *src) { if(!dst || !src) { @@ -126,7 +143,7 @@ ble_addr_to_eui64_cpy(uint8_t *dst) int res; uint8_t ble_addr[BLE_ADDR_SIZE]; - res = ble_addr_cpy(ble_addr); + res = ble_addr_le_cpy(ble_addr); if(res) { return -1; } diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-addr.h b/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-addr.h index fd63c17d0..effc95d22 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-addr.h +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-addr.h @@ -59,6 +59,7 @@ uint8_t *ble_addr_ptr(void); /*---------------------------------------------------------------------------*/ /** * \brief Copy the node's factory BLE address to a destination memory area + * in big-endian (be) order. * \param dst A pointer to the destination area where the BLE address is to be * written * \return 0 : Returned successfully @@ -68,7 +69,21 @@ uint8_t *ble_addr_ptr(void); * the process. The factory address on devices is normally little-endian, * therefore you should expect dst to store the address in a big-endian order. */ -int ble_addr_cpy(uint8_t *dst); +int ble_addr_be_cpy(uint8_t *dst); +/*---------------------------------------------------------------------------*/ +/** + * \brief Copy the node's factory BLE address to a destination memory area + * in little-endian (le) order. + * \param dst A pointer to the destination area where the BLE address is to be + * written + * \return 0 : Returned successfully + * -1 : Returned with error + * + * This function will copy 6 bytes, but will **not** invert the byte order. + * This is usefull for the RF core which assumes the BLE MAC address in + * little-endian order. + */ +int ble_addr_le_cpy(uint8_t *dst); /*---------------------------------------------------------------------------*/ /** * \brief Copy the node's BLE address to a destination memory area and converts diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-beacond.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-beacond.c index 383d168be..2e8d9d4bc 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-beacond.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf/ble-beacond.c @@ -52,6 +52,7 @@ #include /*---------------------------------------------------------------------------*/ +#include "rf/rf.h" #include "rf/sched.h" #include "rf/ble-addr.h" #include "rf/ble-beacond.h" @@ -70,32 +71,58 @@ /*---------------------------------------------------------------------------*/ #if RF_CONF_BLE_BEACON_ENABLE /*---------------------------------------------------------------------------*/ -/* BLE Advertisement channels. Not to be changed by the user. */ -typedef enum { - BLE_ADV_CHANNEL_37 = (1 << 0), - BLE_ADV_CHANNEL_38 = (1 << 1), - BLE_ADV_CHANNEL_39 = (1 << 2), - - BLE_ADV_CHANNEL_ALL = (BLE_ADV_CHANNEL_37 | - BLE_ADV_CHANNEL_38 | - BLE_ADV_CHANNEL_39), -} ble_adv_channel_t; - -#define BLE_ADV_CHANNEL_MIN 37 -#define BLE_ADV_CHANNEL_MAX 39 -/*---------------------------------------------------------------------------*/ /* Maximum BLE advertisement size. Not to be changed by the user. */ #define BLE_ADV_MAX_SIZE 31 /*---------------------------------------------------------------------------*/ -/* BLE Intervals: Send a burst of advertisements every BLE_ADV_INTERVAL secs */ -#define BLE_ADV_INTERVAL (CLOCK_SECOND * 5) -#define BLE_ADV_DUTY_CYCLE (CLOCK_SECOND / 10) -#define BLE_ADV_MESSAGES 10 +/* + * BLE Intervals: Send a burst of advertisements every BLE_ADV_INTERVAL + * specified in milliseconds. + */ +#define BLE_ADV_INTERVAL ((100 * CLOCK_SECOND) / 1000) + +/* GAP Advertisement data types */ +#define BLE_ADV_TYPE_FLAGS 0x01 +#define BLE_ADV_TYPE_16BIT_MORE 0x02 +#define BLE_ADV_TYPE_16BIT_COMPLETE 0x03 +#define BLE_ADV_TYPE_32BIT_MORE 0x04 +#define BLE_ADV_TYPE_32BIT_COMPLETE 0x05 +#define BLE_ADV_TYPE_128BIT_MORE 0x06 +#define BLE_ADV_TYPE_128BIT_COMPLETE 0x07 +#define BLE_ADV_TYPE_LOCAL_NAME_SHORT 0x08 +#define BLE_ADV_TYPE_LOCAL_NAME_COMPLETE 0x09 +#define BLE_ADV_TYPE_POWER_LEVEL 0x0A +#define BLE_ADV_TYPE_OOB_CLASS_OF_DEVICE 0x0D +#define BLE_ADV_TYPE_OOB_SIMPLE_PAIRING_HASHC 0x0E +#define BLE_ADV_TYPE_OOB_SIMPLE_PAIRING_RANDR 0x0F +#define BLE_ADV_TYPE_SM_TK 0x10 +#define BLE_ADV_TYPE_SM_OOB_FLAG 0x11 +#define BLE_ADV_TYPE_SLAVE_CONN_INTERVAL_RANGE 0x12 +#define BLE_ADV_TYPE_SIGNED_DATA 0x13 +#define BLE_ADV_TYPE_SERVICE_LIST_16BIT 0x14 +#define BLE_ADV_TYPE_SERVICE_LIST_128BIT 0x15 +#define BLE_ADV_TYPE_SERVICE_DATA 0x16 +#define BLE_ADV_TYPE_PUBLIC_TARGET_ADDR 0x17 +#define BLE_ADV_TYPE_RANDOM_TARGET_ADDR 0x18 +#define BLE_ADV_TYPE_APPEARANCE 0x19 +#define BLE_ADV_TYPE_ADV_INTERVAL 0x1A +#define BLE_ADV_TYPE_LE_BD_ADDR 0x1B +#define BLE_ADV_TYPE_LE_ROLE 0x1C +#define BLE_ADV_TYPE_SIMPLE_PAIRING_HASHC_256 0x1D +#define BLE_ADV_TYPE_SIMPLE_PAIRING_RANDR_256 0x1E +#define BLE_ADV_TYPE_SERVICE_DATA_32BIT 0x20 +#define BLE_ADV_TYPE_SERVICE_DATA_128BIT 0x21 +#define BLE_ADV_TYPE_3D_INFO_DATA 0x3D +#define BLE_ADV_TYPE_MANUFACTURER_SPECIFIC 0xFF + +/* GAP Advertisement data type flags */ + +/* Discovery Mode: LE Limited Discoverable Mode */ +#define BLE_ADV_TYPE_FLAGS_LIMITED 0x01 +/* Discovery Mode: LE General Discoverable Mode */ +#define BLE_ADV_TYPE_FLAGS_GENERAL 0x02 +/* Discovery Mode: BR/EDR Not Supported */ +#define BLE_ADV_TYPE_FLAGS_BREDR_NOT_SUPPORTED 0x04 -/* BLE Advertisement-related macros */ -#define BLE_ADV_TYPE_DEVINFO 0x01 -#define BLE_ADV_TYPE_NAME 0x09 -#define BLE_ADV_TYPE_MANUFACTURER 0xFF #define BLE_ADV_NAME_BUF_LEN BLE_ADV_MAX_SIZE #define BLE_ADV_PAYLOAD_BUF_LEN 64 #define BLE_UUID_SIZE 16 @@ -117,6 +144,11 @@ typedef struct { /* RF driver */ RF_Handle rf_handle; + + /* BLE command specific structures. Common accross BLE and BLE5. */ + uint8_t ble_mac_addr[6]; + rfc_bleAdvPar_t ble_adv_par; + rfc_bleAdvOutput_t ble_adv_output; } ble_beacond_t; static ble_beacond_t ble_beacond; @@ -126,13 +158,13 @@ PROCESS(ble_beacond_process, "RF BLE Beacon Daemon Process"); rf_ble_beacond_result_t rf_ble_beacond_init(void) { - ble_adv_par.pDeviceAddress = (uint16_t *)ble_addr_ptr(); + ble_cmd_radio_setup.config.frontEndMode = RF_2_4_GHZ_FRONT_END_MODE; + ble_cmd_radio_setup.config.biasMode = RF_2_4_GHZ_BIAS_MODE; RF_Params rf_params; RF_Params_init(&rf_params); - /* Should immediately turn off radio if possible */ - rf_params.nInactivityTimeout = 0; + rf_params.nInactivityTimeout = RF_CONF_INACTIVITY_TIMEOUT; ble_beacond.rf_handle = ble_open(&rf_params); @@ -140,6 +172,18 @@ rf_ble_beacond_init(void) return RF_BLE_BEACOND_ERROR; } + /* + * It is important that the contents of the BLE MAC address is copied into + * RAM, as the System CPU, and subsequently flash, goes idle when pending + * on an RF command. This causes pend to hang forever. + */ + ble_addr_le_cpy(ble_beacond.ble_mac_addr); + ble_beacond.ble_adv_par.pDeviceAddress = (uint16_t *)ble_beacond.ble_mac_addr; + ble_beacond.ble_adv_par.endTrigger.triggerType = TRIG_NEVER; + + rf_ble_cmd_ble_adv_nc.pParams = &ble_beacond.ble_adv_par; + rf_ble_cmd_ble_adv_nc.pOutput = &ble_beacond.ble_adv_output; + return RF_BLE_BEACOND_OK; } /*---------------------------------------------------------------------------*/ @@ -154,12 +198,14 @@ rf_ble_beacond_config(clock_time_t interval, const char *name) ble_beacond.ble_adv_interval = interval; res = RF_BLE_BEACOND_OK; + } else { + ble_beacond.ble_adv_interval = BLE_ADV_INTERVAL; } if(name != NULL) { const size_t name_len = strlen(name); - if((name_len == 0) || (name_len >= BLE_ADV_NAME_BUF_LEN)) { + if((0 < name_len) && (name_len < BLE_ADV_NAME_BUF_LEN)) { ble_beacond.adv_name_len = name_len; memcpy(ble_beacond.adv_name, name, name_len); @@ -235,37 +281,9 @@ rf_ble_get_tx_power(void) return dbm; } /*---------------------------------------------------------------------------*/ -static rf_ble_beacond_result_t -ble_beacon_burst(uint8_t channels_bm, uint8_t *data, uint8_t len) -{ - rf_result_t res; - - uint8_t channel; - for(channel = BLE_ADV_CHANNEL_MIN; channel <= BLE_ADV_CHANNEL_MAX; ++channel) { - const uint8_t channel_bv = (1 << (channel - BLE_ADV_CHANNEL_MIN)); - if((channel_bv & channels_bm) == 0) { - continue; - } - - ble_adv_par.advLen = len; - ble_adv_par.pAdvData = data; - - ble_cmd_beacon.channel = channel; - - res = ble_sched_beacon(NULL, 0); - - if(res != RF_RESULT_OK) { - return RF_BLE_BEACOND_ERROR; - } - } - - return RF_BLE_BEACOND_OK; -} -/*---------------------------------------------------------------------------*/ PROCESS_THREAD(ble_beacond_process, ev, data) { - static size_t i; - static size_t len; + size_t len; PROCESS_BEGIN(); @@ -278,30 +296,33 @@ PROCESS_THREAD(ble_beacond_process, ev, data) PROCESS_EXIT(); } + /* Device info */ /* Set the adv payload each pass: The device name may have changed */ len = 0; - /* Device info */ - ble_beacond.tx_buf[len++] = (uint8_t)0x02; /* 2 bytes */ - ble_beacond.tx_buf[len++] = (uint8_t)BLE_ADV_TYPE_DEVINFO; - ble_beacond.tx_buf[len++] = (uint8_t)0x1A; /* LE general discoverable + BR/EDR */ - ble_beacond.tx_buf[len++] = (uint8_t)ble_beacond.adv_name_len; - ble_beacond.tx_buf[len++] = (uint8_t)BLE_ADV_TYPE_NAME; + #define append_byte(x) ble_beacond.tx_buf[len++] = (uint8_t)((x)) + + /* 2 bytes */ + append_byte(2); + append_byte(BLE_ADV_TYPE_FLAGS); + /* LE general discoverable + BR/EDR not supported */ + append_byte(BLE_ADV_TYPE_FLAGS_GENERAL | + BLE_ADV_TYPE_FLAGS_BREDR_NOT_SUPPORTED); + + /* 1 + len(name) bytes (excluding zero termination) */ + append_byte(1 + ble_beacond.adv_name_len); + append_byte(BLE_ADV_TYPE_LOCAL_NAME_COMPLETE); memcpy(ble_beacond.tx_buf + len, ble_beacond.adv_name, ble_beacond.adv_name_len); len += ble_beacond.adv_name_len; - /* - * Send BLE_ADV_MESSAGES beacon bursts. Each burst on all three - * channels, with a BLE_ADV_DUTY_CYCLE interval between bursts - */ - ble_beacon_burst(BLE_ADV_CHANNEL_ALL, ble_beacond.tx_buf, len); - for(i = 1; i < BLE_ADV_MESSAGES; ++i) { - etimer_set(&ble_beacond.ble_adv_et, BLE_ADV_DUTY_CYCLE); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&ble_beacond.ble_adv_et)); + #undef append_byte - ble_beacon_burst(BLE_ADV_CHANNEL_ALL, ble_beacond.tx_buf, len); - } + /* Send advertisements on all three channels */ + ble_beacond.ble_adv_par.advLen = len; + ble_beacond.ble_adv_par.pAdvData = ble_beacond.tx_buf; + + ble_sched_beacons(BLE_ADV_CHANNEL_ALL); } PROCESS_END(); } diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf/ieee-mode.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf/ieee-mode.c index d9f3a5acf..6f21c72ba 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf/ieee-mode.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf/ieee-mode.c @@ -217,6 +217,9 @@ rat_overflow_cb(void *arg) static void init_rf_params(void) { + cmd_radio_setup.config.frontEndMode = RF_2_4_GHZ_FRONT_END_MODE; + cmd_radio_setup.config.biasMode = RF_2_4_GHZ_BIAS_MODE; + data_queue_t *rx_q = data_queue_init(sizeof(lensz_t)); cmd_rx.pRxQ = rx_q; @@ -550,32 +553,42 @@ read(void *buf, unsigned short buf_len) static rf_result_t cca_request(cmd_cca_req_t *cmd_cca_req) { + RF_Stat stat = RF_StatRadioInactiveError; rf_result_t res; + bool stop_rx = false; - const bool rx_is_idle = !rx_is_active(); + /* RX is required to be running in order to do a CCA request */ + if(!rx_is_active()) { + /* If RX is not pending, i.e. soon to be running, schedule the RX command */ + if(cmd_rx.status != PENDING) { + res = netstack_sched_rx(false); + if(res != RF_RESULT_OK) { + LOG_ERR("CCA request failed to schedule RX\n"); + return res; + } - if(rx_is_idle) { - res = netstack_sched_rx(false); - if(res != RF_RESULT_OK) { + /* We only stop RX if we had to schedule it */ + stop_rx = true; + } + + /* Make sure RX is running before we continue, unless we timeout and fail */ + RTIMER_BUSYWAIT_UNTIL(!rx_is_active(), TIMEOUT_ENTER_RX_WAIT); + + if(!rx_is_active()) { + LOG_ERR("CCA request failed to turn on RX, RX status=0x%04X\n", cmd_rx.status); return RF_RESULT_ERROR; } } - const rtimer_clock_t t0 = RTIMER_NOW(); - while((cmd_rx.status != ACTIVE) && - RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + TIMEOUT_ENTER_RX_WAIT)) ; + /* Perform the CCA request */ + stat = RF_runImmediateCmd(ieee_radio.rf_handle, (uint32_t *)&cmd_cca_req); - RF_Stat stat = RF_StatRadioInactiveError; - if(rx_is_active()) { - stat = RF_runImmediateCmd(ieee_radio.rf_handle, (uint32_t *)&cmd_cca_req); - } - - if(rx_is_idle) { + if(stop_rx) { netstack_stop_rx(); } if(stat != RF_StatCmdDoneSuccess) { - LOG_ERR("CCA request failed, stat=0x%02X\n", stat); + LOG_ERR("CCA request command failed, stat=0x%02X\n", stat); return RF_RESULT_ERROR; } diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf/prop-mode.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf/prop-mode.c index a100f262a..241ae986d 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf/prop-mode.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf/prop-mode.c @@ -61,6 +61,7 @@ #include /*---------------------------------------------------------------------------*/ /* Platform RF dev */ +#include "rf/rf.h" #include "rf/dot-15-4g.h" #include "rf/sched.h" #include "rf/data-queue.h" @@ -193,6 +194,8 @@ static int off(void); static void init_rf_params(void) { + cmd_radio_setup.config.frontEndMode = RF_SUB_1_GHZ_FRONT_END_MODE; + cmd_radio_setup.config.biasMode = RF_SUB_1_GHZ_BIAS_MODE; cmd_radio_setup.centerFreq = PROP_MODE_CENTER_FREQ; cmd_radio_setup.loDivider = PROP_MODE_LO_DIVIDER; @@ -207,26 +210,36 @@ static int8_t get_rssi(void) { rf_result_t res; + bool stop_rx = false; + int8_t rssi = RF_GET_RSSI_ERROR_VAL; - const bool rx_is_idle = !rx_is_active(); + /* RX is required to be running in order to do a RSSI measurement */ + if(!rx_is_active()) { + /* If RX is not pending, i.e. soon to be running, schedule the RX command */ + if(cmd_rx.status != PENDING) { + res = netstack_sched_rx(false); + if(res != RF_RESULT_OK) { + LOG_ERR("RSSI measurement failed to schedule RX\n"); + return res; + } - if(rx_is_idle) { - res = netstack_sched_rx(false); - if(res != RF_RESULT_OK) { - return RF_GET_RSSI_ERROR_VAL; + /* We only stop RX if we had to schedule it */ + stop_rx = true; + } + + /* Make sure RX is running before we continue, unless we timeout and fail */ + RTIMER_BUSYWAIT_UNTIL(!rx_is_active(), TIMEOUT_ENTER_RX_WAIT); + + if(!rx_is_active()) { + LOG_ERR("RSSI measurement failed to turn on RX, RX status=0x%04X\n", cmd_rx.status); + return RF_RESULT_ERROR; } } - const rtimer_clock_t t0 = RTIMER_NOW(); - while((cmd_rx.status != ACTIVE) && - RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + TIMEOUT_ENTER_RX_WAIT)) ; + /* Perform the RSSI measurement */ + rssi = RF_getRssi(prop_radio.rf_handle); - int8_t rssi = RF_GET_RSSI_ERROR_VAL; - if(rx_is_active()) { - rssi = RF_getRssi(prop_radio.rf_handle); - } - - if(rx_is_idle) { + if(stop_rx) { netstack_stop_rx(); } diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf/rf.h b/arch/cpu/simplelink-cc13xx-cc26xx/rf/rf.h index cfc6b2277..65b2b1543 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf/rf.h +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf/rf.h @@ -60,6 +60,37 @@ RF_MODE_2_4_GHZ) /** @} */ /*---------------------------------------------------------------------------*/ +/** + * \name The different front-end modes the CC13xx/CC26xx devices support. The + * front-end mode can be configured independently of the bias mode. The + * two types of modes are as follows: + * - Differential: Both RF_P and RF_N are used as a differential RF + * interface. + * - Single ended: Either the RF_P pin or the RF_N pin is used as the + * RF path. + * + * @{ + */ +/* Available front-end mode configurations */ +#define RF_FRONT_END_MODE_DIFFERENTIAL 0 +#define RF_FRONT_END_MODE_SINGLE_ENDED_RFP 1 +#define RF_FRONT_END_MODE_SINGLE_ENDED_RFN 2 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name The different bias modes the CC13xx/CC26xx devices support. The + * bias mode can be configured independently of the front-end mode. The + * two different modes are as follows: + * - Internal bias: the LNA is biased by an internal bias. + * - External bias: the LNA is biased by an external bias. + * + * @{ + */ +/* Available bias mode configurations */ +#define RF_BIAS_MODE_INTERNAL 0 +#define RF_BIAS_MODE_EXTERNAL 1 +/** @} */ +/*---------------------------------------------------------------------------*/ #endif /* RF_CORE_H_ */ /*---------------------------------------------------------------------------*/ /** diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf/sched.c b/arch/cpu/simplelink-cc13xx-cc26xx/rf/sched.c index 44387c138..f15d33d2f 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf/sched.c +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf/sched.c @@ -51,6 +51,7 @@ #include #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h) #include DeviceFamily_constructPath(driverlib/rf_mailbox.h) +#include DeviceFamily_constructPath(driverlib/rf_ble_mailbox.h) #include /*---------------------------------------------------------------------------*/ @@ -68,8 +69,6 @@ #define LOG_MODULE "Radio" #define LOG_LEVEL LOG_LEVEL_NONE /*---------------------------------------------------------------------------*/ -/* Configuration parameters */ -/*---------------------------------------------------------------------------*/ #define CMD_FS_RETRIES 3 #define RF_EVENTS_CMD_DONE (RF_EventCmdDone | RF_EventLastCmdDone | \ @@ -82,6 +81,13 @@ #define EVENTS_CMD_DONE(events) (((events) & RF_EVENTS_CMD_DONE) != 0) /*---------------------------------------------------------------------------*/ +/* BLE advertisement channel range (inclusive) */ +#define BLE_ADV_CHANNEL_MIN 37 +#define BLE_ADV_CHANNEL_MAX 39 + +/* Number of BLE advertisement channels */ +#define NUM_BLE_ADV_CHANNELS (BLE_ADV_CHANNEL_MAX - BLE_ADV_CHANNEL_MIN + 1) +/*---------------------------------------------------------------------------*/ /* Synth re-calibration every 3 minutes */ #define SYNTH_RECAL_INTERVAL (CLOCK_SECOND * 60 * 3) /* Set re-calibration interval with a jitter of 10 seconds */ @@ -89,6 +95,12 @@ static struct etimer synth_recal_timer; /*---------------------------------------------------------------------------*/ +#if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC13X0_CC26X0) +typedef rfc_CMD_BLE_ADV_NC_t ble_cmd_adv_nc_t; +#elif (DeviceFamily_PARENT == DeviceFamily_PARENT_CC13X2_CC26X2) +typedef rfc_CMD_BLE5_ADV_NC_t ble_cmd_adv_nc_t; +#endif +/*---------------------------------------------------------------------------*/ static RF_Object rf_netstack; #if RF_CONF_BLE_BEACON_ENABLE @@ -479,45 +491,171 @@ ble_open(RF_Params *params) #endif } /*---------------------------------------------------------------------------*/ +#if RF_CONF_BLE_BEACON_ENABLE +static RF_Op * +init_ble_adv_array(ble_cmd_adv_nc_t *ble_adv_array, uint8_t bm_channel) +{ + RF_Op *first_ble_adv = NULL; + ble_cmd_adv_nc_t *cmd_adv_37 = &ble_adv_array[0]; + ble_cmd_adv_nc_t *cmd_adv_38 = &ble_adv_array[1]; + ble_cmd_adv_nc_t *cmd_adv_39 = &ble_adv_array[2]; + + /* Setup channel 37 advertisement if enabled */ + if(bm_channel & BLE_ADV_CHANNEL_37) { + /* Default configurations from ble_cmd_adv_nc */ + memcpy(cmd_adv_37, &ble_cmd_adv_nc, sizeof(ble_cmd_adv_nc)); + + cmd_adv_37->channel = 37; + /* Magic number: initialization for whitener, specific for channel 37 */ + cmd_adv_37->whitening.init = 0x65; + + /* + * The next advertisement is chained depending on whether they are + * enbled or not. If both 38 and 39 are disabled, then there is no + * chaining. + */ + if(bm_channel & BLE_ADV_CHANNEL_38) { + cmd_adv_37->pNextOp = (RF_Op *)cmd_adv_38; + cmd_adv_37->condition.rule = COND_ALWAYS; + } else if(bm_channel & BLE_ADV_CHANNEL_39) { + cmd_adv_37->pNextOp = (RF_Op *)cmd_adv_39; + cmd_adv_37->condition.rule = COND_ALWAYS; + } else { + cmd_adv_37->pNextOp = NULL; + cmd_adv_37->condition.rule = COND_NEVER; + } + + /* Channel 37 will always be first if enabled */ + first_ble_adv = (RF_Op *)cmd_adv_37; + } + + /* Setup channel 38 advertisement if enabled */ + if(bm_channel & BLE_ADV_CHANNEL_38) { + memcpy(cmd_adv_38, &ble_cmd_adv_nc, sizeof(ble_cmd_adv_nc)); + + cmd_adv_38->channel = 38; + /* Magic number: initialization for whitener, specific for channel 38 */ + cmd_adv_38->whitening.init = 0x66; + + /* + * The next advertisement is chained depending on whether they are + * enbled or not. If 39 is disabled, then there is no chaining. + */ + if(bm_channel & BLE_ADV_CHANNEL_39) { + cmd_adv_38->pNextOp = (RF_Op *)cmd_adv_39; + cmd_adv_38->condition.rule = COND_ALWAYS; + } else { + cmd_adv_38->pNextOp = NULL; + cmd_adv_38->condition.rule = COND_NEVER; + } + + /* + * Channel 38 is only first if the first_ble_adv pointer is not + * set by channel 37. + */ + if(first_ble_adv == NULL) { + first_ble_adv = (RF_Op *)cmd_adv_38; + } + } + + /* Setup channel 39 advertisement if enabled */ + if(bm_channel & BLE_ADV_CHANNEL_39) { + memcpy(cmd_adv_39, &ble_cmd_adv_nc, sizeof(ble_cmd_adv_nc)); + + cmd_adv_39->channel = 39; + /* Magic number: initialization for whitener, specific for channel 39 */ + cmd_adv_39->whitening.init = 0x67; + + /* Channel 39 is always the last advertisement in the chain */ + cmd_adv_39->pNextOp = NULL; + cmd_adv_39->condition.rule = COND_NEVER; + + /* + * Channel 39 is only first if the first_ble_adv pointer is not + * set by channel 37 or channel 38. + */ + if(first_ble_adv == NULL) { + first_ble_adv = (RF_Op *)cmd_adv_39; + } + } + + return first_ble_adv; +} +#endif /* RF_CONF_BLE_BEACON_ENABLE */ +/*---------------------------------------------------------------------------*/ rf_result_t -ble_sched_beacon(RF_Callback cb, RF_EventMask bm_event) +ble_sched_beacons(uint8_t bm_channel) { #if RF_CONF_BLE_BEACON_ENABLE - RF_ScheduleCmdParams sched_params; - RF_ScheduleCmdParams_init(&sched_params); + /* + * Allocate the advertisement commands on the stack rather than statically + * to RAM in order to save space. We don't need them after the + * advertisements have been transmitted. + */ + ble_cmd_adv_nc_t ble_cmd_adv_nc_array[NUM_BLE_ADV_CHANNELS]; + RF_Op *initial_adv = NULL; + RF_ScheduleCmdParams sched_params; + RF_CmdHandle beacon_handle; + RF_EventMask beacon_events; + rf_result_t rf_result; + + /* If no channels are mapped, then early return OK */ + if((bm_channel & BLE_ADV_CHANNEL_ALL) == 0) { + return RF_RESULT_OK; + } + + initial_adv = init_ble_adv_array(ble_cmd_adv_nc_array, bm_channel); + + if(initial_adv == NULL) { + LOG_ERR("Initializing BLE Advertisement chain failed\n"); + return RF_RESULT_ERROR; + } + + RF_ScheduleCmdParams_init(&sched_params); sched_params.priority = RF_PriorityNormal; sched_params.endTime = 0; sched_params.allowDelay = RF_AllowDelayAny; - CMD_STATUS(ble_cmd_beacon) = PENDING; - - RF_CmdHandle beacon_handle = RF_scheduleCmd( - &rf_ble, - (RF_Op *)&ble_cmd_beacon, - &sched_params, - cb, - bm_event); + /* + * The most efficient way to schedule the command is as follows: + * 1. Schedule the BLE advertisement chain + * 2. Reschedule the RX command IF it was running. + * 3. Pend on the BLE avertisement chain + */ + beacon_handle = RF_scheduleCmd( + &rf_ble, + initial_adv, + &sched_params, + NULL, + 0); if(!CMD_HANDLE_OK(beacon_handle)) { LOG_ERR("Unable to schedule BLE Beacon command, handle=%d status=0x%04x\n", - beacon_handle, CMD_STATUS(ble_cmd_beacon)); + beacon_handle, CMD_STATUS(ble_cmd_adv_nc)); + return RF_RESULT_ERROR; } - const uint_fast8_t rx_key = cmd_rx_disable(); + /* Note that this only reschedules RX if it is running */ + rf_result = cmd_rx_restore(cmd_rx_disable()); /* Wait until Beacon operation finishes */ - RF_EventMask beacon_events = RF_pendCmd(&rf_ble, beacon_handle, 0); - if(!EVENTS_CMD_DONE(beacon_events)) { - LOG_ERR("Pending on scheduled BLE Beacon command generated error, events=0x%08llx status=0x%04x\n", - beacon_events, CMD_STATUS(ble_cmd_beacon)); + beacon_events = RF_pendCmd(&rf_ble, beacon_handle, 0); + + if(rf_result != RF_RESULT_OK) { + LOG_ERR("Rescheduling CMD_RX failed when BLE advertising\n"); + + return RF_RESULT_ERROR; + } + + if(!EVENTS_CMD_DONE(beacon_events)) { + LOG_ERR("Pending on scheduled BLE Beacon command generated error, events=0x%08llx status=0x%04x\n", + beacon_events, CMD_STATUS(ble_cmd_adv_nc)); - cmd_rx_restore(rx_key); return RF_RESULT_ERROR; } - cmd_rx_restore(rx_key); return RF_RESULT_OK; #else diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf/sched.h b/arch/cpu/simplelink-cc13xx-cc26xx/rf/sched.h index de32dbbd4..fe4963036 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf/sched.h +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf/sched.h @@ -58,6 +58,16 @@ typedef enum { RF_RESULT_ERROR, } rf_result_t; /*---------------------------------------------------------------------------*/ +typedef enum { + BLE_ADV_CHANNEL_37 = (1 << 0), + BLE_ADV_CHANNEL_38 = (1 << 1), + BLE_ADV_CHANNEL_39 = (1 << 2), + + BLE_ADV_CHANNEL_ALL = (BLE_ADV_CHANNEL_37 | + BLE_ADV_CHANNEL_38 | + BLE_ADV_CHANNEL_39), +} ble_adv_channel_t; +/*---------------------------------------------------------------------------*/ /** * \name Common RF scheduler functionality. * @@ -91,7 +101,7 @@ rf_result_t netstack_stop_rx(void); * @{ */ RF_Handle ble_open(RF_Params *params); -rf_result_t ble_sched_beacon(RF_Callback cb, RF_EventMask bm_event); +rf_result_t ble_sched_beacons(uint8_t bm_adv_channel); /** @} */ /*---------------------------------------------------------------------------*/ #endif /* RF_SCHED_H_ */ diff --git a/arch/cpu/simplelink-cc13xx-cc26xx/rf/settings.h b/arch/cpu/simplelink-cc13xx-cc26xx/rf/settings.h index 174114bfb..1d20fce91 100644 --- a/arch/cpu/simplelink-cc13xx-cc26xx/rf/settings.h +++ b/arch/cpu/simplelink-cc13xx-cc26xx/rf/settings.h @@ -89,7 +89,7 @@ #define ble_mode rf_ble_mode #define ble_cmd_radio_setup rf_ble_cmd_radio_setup #define ble_adv_par rf_ble_adv_par -#define ble_cmd_beacon rf_ble_cmd_ble_adv_nc +#define ble_cmd_adv_nc rf_ble_cmd_ble_adv_nc /* CC13x2/CC26x2 devices */ #elif (DeviceFamily_PARENT == DeviceFamily_PARENT_CC13X2_CC26X2) @@ -97,7 +97,7 @@ #define ble_mode rf_ble_mode #define ble_cmd_radio_setup rf_ble_cmd_radio_setup #define ble_adv_par rf_ble_adv_par -#define ble_cmd_beacon rf_ble_cmd_ble_adv_nc +#define ble_cmd_adv_nc rf_ble_cmd_ble_adv_nc #endif /* DeviceFamily_PARENT */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/contiki-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/contiki-conf.h index 212f4fd48..542f69869 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/contiki-conf.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/contiki-conf.h @@ -31,6 +31,10 @@ * \addtogroup cc13xx-cc26xx-platform * @{ * + * The order of which these header files are included is important in order + * for the configurations to be correctly set. This has to do with some + * slight unfortunate configuration dependencies of the board file. + * * \file * Configuration for the SimpleLink CC13xx/CC26xx platform. * \author @@ -40,18 +44,16 @@ #ifndef CONTIKI_CONF_H_ #define CONTIKI_CONF_H_ /*---------------------------------------------------------------------------*/ -#include "board-conf.h" -/*---------------------------------------------------------------------------*/ -/* Include Project Specific conf */ +/* Include project-specific configurations */ #ifdef PROJECT_CONF_PATH #include PROJECT_CONF_PATH #endif /*---------------------------------------------------------------------------*/ -/* Include CPU-related configuration */ -#include "cc13xx-cc26xx-conf.h" +/* Include board-specific configurations */ +#include "board-conf.h" /*---------------------------------------------------------------------------*/ -/* Must be included after cc13xx-cc26xx-conf.h */ -#include +/* Include CPU-related configurations */ +#include "cc13xx-cc26xx-conf.h" /*---------------------------------------------------------------------------*/ #endif /* CONTIKI_CONF_H_ */ /*---------------------------------------------------------------------------*/ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/board-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/board-conf.h index 71d59501d..5e5c75528 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/board-conf.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/board-conf.h @@ -50,7 +50,7 @@ #ifndef BOARD_CONF_H_ #define BOARD_CONF_H_ /*---------------------------------------------------------------------------*/ -#include "contiki-conf.h" +#include "rf-conf.h" /*---------------------------------------------------------------------------*/ /** * \name LED configurations for the dev/leds.h API. diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1310/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1310/Board.h index 6b3c762d7..88999fe6f 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1310/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1310/Board.h @@ -36,6 +36,9 @@ #define Board_CC1310_LAUNCHXL #define BOARD_STRING "TI CC1310 LaunchPad" +#define RF_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL + #ifdef __cplusplus extern "C" { #endif diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1310/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1310/rf-conf.h new file mode 100644 index 000000000..d26d3a864 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1310/rf-conf.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for the Sub-1 GHz path + * on the radio. + * + * These are the following front-end mode configurations for the + * CC1310-LAUNCHXL board: + * - Sub-1 GHz: differential and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1312r1/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1312r1/Board.h index c3763b019..a230c764e 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1312r1/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1312r1/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC1312R1_LAUNCHXL -#define BOARD_STRING "TI CC1312R1 LaunchPad" - #ifdef __cplusplus extern "C" { #endif #include "CC1312R1_LAUNCHXL.h" +#define Board_CC1312R1_LAUNCHXL +#define BOARD_STRING "TI CC1312R1 LaunchPad" + #define Board_initGeneral() CC1312R1_LAUNCHXL_initGeneral() #define Board_shutDownExtFlash() CC1312R1_LAUNCHXL_shutDownExtFlash() #define Board_wakeUpExtFlash() CC1312R1_LAUNCHXL_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1312r1/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1312r1/rf-conf.h new file mode 100644 index 000000000..f649dd170 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1312r1/rf-conf.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for the Sub-1 GHz path + * on the radio. + * + * These are the following front-end mode configurations for the + * CC1312R1-LAUNCHXL board: + * - Sub-1 GHz: differential and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/Board.h index c8094432a..4b8fbe5c0 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC1350_LAUNCHXL_433 -#define BOARD_STRING "TI CC1350-433 LaunchPad" - #ifdef __cplusplus extern "C" { #endif #include "CC1350_LAUNCHXL_433.h" +#define Board_CC1350_LAUNCHXL_433 +#define BOARD_STRING "TI CC1350-433 LaunchPad" + #define Board_initGeneral() CC1350_LAUNCHXL_433_initGeneral() #define Board_shutDownExtFlash() CC1350_LAUNCHXL_433_shutDownExtFlash() #define Board_wakeUpExtFlash() CC1350_LAUNCHXL_433_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/CC1350_LAUNCHXL_433_fxns.c b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/CC1350_LAUNCHXL_433_fxns.c index a8a6b16c0..92e349480 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/CC1350_LAUNCHXL_433_fxns.c +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/CC1350_LAUNCHXL_433_fxns.c @@ -165,23 +165,60 @@ void Board_initHook() #if defined(Board_RF_SUB1GHZ) /* - * ======== CC1350_LAUNCHXL_433_rfDriverCallback ======== - * This is an implementation for the CC1350 launchpad which uses a + * Mask to be used to determine the effective value of the setup command's + * loDivider field. + */ +#define LODIVIDER_MASK 0x7F + +/* + * ======== rfDriverCallback ======== + * This is an implementation for the CC1350 LaunchPad which uses a * single signal for antenna switching. */ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) { + /* Decode input arguments. */ (void)client; RF_RadioSetup* setupCommand = (RF_RadioSetup*)arg; + /* Local variable. */ + bool sub1GHz = false; + uint8_t loDivider = 0; + if (events & RF_GlobalEventRadioSetup) { /* Power up the antenna switch */ PINCC26XX_setOutputValue(Board_RF_POWER, 1); - if (setupCommand->common.commandNo == CMD_PROP_RADIO_DIV_SETUP) { - /* Sub-1 GHz, requires antenna switch high */ + /* Decision about the frequency band shall be made based on the + loDivider field. */ + switch (setupCommand->common.commandNo) { + case (CMD_RADIO_SETUP): + case (CMD_BLE5_RADIO_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->common.loDivider; + + /* Sub-1 GHz, requires antenna switch high. */ + if ((loDivider != 0) && (loDivider != 2)) { + sub1GHz = true; + } + break; + case (CMD_PROP_RADIO_DIV_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->prop_div.loDivider; + + /* Sub-1 GHz, requires antenna switch high. */ + if ((loDivider != 0) && (loDivider != 2)) { + sub1GHz = true; + } + break; + default:break; + } + + /* Select the correct antenna. */ + if (sub1GHz) { PINCC26XX_setOutputValue(Board_RF_SUB1GHZ, 1); } + else { + PINCC26XX_setOutputValue(Board_RF_SUB1GHZ, 0); + } } else if (events & RF_GlobalEventRadioPowerDown) { /* Disable antenna switch to save current */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/rf-conf.h new file mode 100644 index 000000000..371af4d89 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350-4/rf-conf.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for both the Sub-1 GHz + * path and the 2.4 GHz path on the radio. + * + * These are the following front-end mode configurations for the + * CC1350-4-LAUNCHXL board: + * - Sub-1 GHz: differential and external bias + * - 2.4 GHz: differential and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL + +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/Board.h index 2099b1845..97ff04a59 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC1350_LAUNCHXL -#define BOARD_STRING "TI CC1350 LaunchPad" - #ifdef __cplusplus extern "C" { #endif #include "CC1350_LAUNCHXL.h" +#define Board_CC1350_LAUNCHXL +#define BOARD_STRING "TI CC1350 LaunchPad" + #define Board_initGeneral() CC1350_LAUNCHXL_initGeneral() #define Board_shutDownExtFlash() CC1350_LAUNCHXL_shutDownExtFlash() #define Board_wakeUpExtFlash() CC1350_LAUNCHXL_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/CC1350_LAUNCHXL_fxns.c b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/CC1350_LAUNCHXL_fxns.c index 90f69a0c0..56de7c562 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/CC1350_LAUNCHXL_fxns.c +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/CC1350_LAUNCHXL_fxns.c @@ -166,6 +166,12 @@ void Board_initHook() */ #if defined(Board_RF_SUB1GHZ) +/* + * Mask to be used to determine the effective value of the setup command's + * loDivider field. + */ +#define LODIVIDER_MASK 0x7F + /* * ======== rfDriverCallback ======== * This is an implementation for the CC1350 launchpad which uses a @@ -173,17 +179,48 @@ void Board_initHook() */ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) { + /* Decode input arguments. */ (void)client; RF_RadioSetup* setupCommand = (RF_RadioSetup*)arg; + /* Local variable. */ + bool sub1GHz = false; + uint8_t loDivider = 0; + if (events & RF_GlobalEventRadioSetup) { /* Power up the antenna switch */ PINCC26XX_setOutputValue(Board_RF_POWER, 1); - if (setupCommand->common.commandNo == CMD_PROP_RADIO_DIV_SETUP) { - /* Sub-1 GHz, requires antenna switch high */ + /* Decision about the frequency band shall be made based on the + loDivider field. */ + switch (setupCommand->common.commandNo) { + case (CMD_RADIO_SETUP): + case (CMD_BLE5_RADIO_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->common.loDivider; + + /* Sub-1 GHz, requires antenna switch high. */ + if ((loDivider != 0) && (loDivider != 2)) { + sub1GHz = true; + } + break; + case (CMD_PROP_RADIO_DIV_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->prop_div.loDivider; + + /* Sub-1 GHz, requires antenna switch high. */ + if ((loDivider != 0) && (loDivider != 2)) { + sub1GHz = true; + } + break; + default:break; + } + + /* Select the correct antenna. */ + if (sub1GHz) { PINCC26XX_setOutputValue(Board_RF_SUB1GHZ, 1); } + else { + PINCC26XX_setOutputValue(Board_RF_SUB1GHZ, 0); + } } else if (events & RF_GlobalEventRadioPowerDown) { /* Disable antenna switch to save current */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/rf-conf.h new file mode 100644 index 000000000..e6cd0b744 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1350/rf-conf.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for both the Sub-1 GHz + * path and the 2.4 GHz path on the radio. + * + * These are the following front-end mode configurations for the + * CC1350-LAUNCHXL board: + * - Sub-1 GHz: differential and external bias + * - 2.4 GHz: differential and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL + +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/Board.h index d22d73c17..40f76e18b 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC1352P_2_LAUNCHXL -#define BOARD_STRING "TI CC1352P-2 LaunchPad" - #ifdef __cplusplus extern "C" { #endif #include "CC1352P_2_LAUNCHXL.h" +#define Board_CC1352P_2_LAUNCHXL +#define BOARD_STRING "TI CC1352P-2 LaunchPad" + #define Board_initGeneral() CC1352P_2_LAUNCHXL_initGeneral() #define Board_shutDownExtFlash() CC1352P_2_LAUNCHXL_shutDownExtFlash() #define Board_wakeUpExtFlash() CC1352P_2_LAUNCHXL_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/CC1352P_2_LAUNCHXL_fxns.c b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/CC1352P_2_LAUNCHXL_fxns.c index f8b4930c8..57f545360 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/CC1352P_2_LAUNCHXL_fxns.c +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/CC1352P_2_LAUNCHXL_fxns.c @@ -152,6 +152,12 @@ void CC1352P_2_LAUNCHXL_shutDownExtFlash(void) */ #if defined(Board_RF_SUB1GHZ) +/* + * Mask to be used to determine the effective value of the setup command's + * loDivider field. + */ +#define LODIVIDER_MASK 0x7F + /* * ======== Antenna switching ======== */ @@ -170,7 +176,7 @@ void initAntennaSwitch() } /* - * ======== rfDriverCallback ======== + * ======== CC1352P1_LAUNCHXL_rfDriverCallback ======== * Sets up the antenna switch depending on the current PHY configuration. * Truth table: * @@ -183,6 +189,10 @@ void initAntennaSwitch() */ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) { + /* Local variable. */ + bool sub1GHz = false; + uint8_t loDivider = 0; + /* Switch off all paths first. Needs to be done anyway in every sub-case below. */ PINCC26XX_setOutputValue(Board_RF_24GHZ, 0); PINCC26XX_setOutputValue(Board_RF_HIGH_PA, 0); @@ -195,15 +205,36 @@ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) /* Decode the generic argument as a setup command. */ RF_RadioSetup* setupCommand = (RF_RadioSetup*)arg; - if (setupCommand->common.commandNo == CMD_PROP_RADIO_DIV_SETUP) { + switch (setupCommand->common.commandNo) { + case (CMD_RADIO_SETUP): + case (CMD_BLE5_RADIO_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->common.loDivider; + + /* Sub-1GHz front-end. */ + if (loDivider != 0) { + sub1GHz = true; + } + break; + case (CMD_PROP_RADIO_DIV_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->prop_div.loDivider; + + /* Sub-1GHz front-end. */ + if (loDivider != 0) { + sub1GHz = true; + } + break; + default:break; + } + + if (sub1GHz) { /* Sub-1 GHz */ if (paType == RF_TxPowerTable_HighPA) { /* PA enable --> HIGH PA * LNA enable --> Sub-1 GHz */ PINCC26XX_setMux(antennaPins, Board_RF_24GHZ, PINCC26XX_MUX_GPIO); - // Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not - // de-asserted on CC1352 Rev A. + /* Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not + de-asserted on CC1352 Rev A. */ PINCC26XX_setMux(antennaPins, Board_RF_HIGH_PA, PINCC26XX_MUX_RFC_GPO3); PINCC26XX_setMux(antennaPins, Board_RF_SUB1GHZ, PINCC26XX_MUX_RFC_GPO0); } else { @@ -221,8 +252,8 @@ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) * LNA enable --> 2.4 GHz */ PINCC26XX_setMux(antennaPins, Board_RF_24GHZ, PINCC26XX_MUX_RFC_GPO0); - // Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not - // de-asserted on CC1352 Rev A. + /* Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not + de-asserted on CC1352 Rev A. */ PINCC26XX_setMux(antennaPins, Board_RF_HIGH_PA, PINCC26XX_MUX_RFC_GPO3); PINCC26XX_setMux(antennaPins, Board_RF_SUB1GHZ, PINCC26XX_MUX_GPIO); } else { diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/rf-conf.h new file mode 100644 index 000000000..1eb0926b7 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-2/rf-conf.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for both the Sub-1 GHz + * path and the 2.4 GHz path on the radio. + * + * These are the following front-end mode configurations for the + * CC1352P-2-LAUNCHXL board: + * - Sub-1 GHz: differential and external bias + * - 2.4 GHz: differential and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL + +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/Board.h index 381651708..de9bc8e9d 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC1352P_4_LAUNCHXL -#define BOARD_STRING "TI CC1352P-4 LaunchPad" - #ifdef __cplusplus extern "C" { #endif #include "CC1352P_4_LAUNCHXL.h" +#define Board_CC1352P_4_LAUNCHXL +#define BOARD_STRING "TI CC1352P-4 LaunchPad" + #define Board_initGeneral() CC1352P_4_LAUNCHXL_initGeneral() #define Board_shutDownExtFlash() CC1352P_4_LAUNCHXL_shutDownExtFlash() #define Board_wakeUpExtFlash() CC1352P_4_LAUNCHXL_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/CC1352P_4_LAUNCHXL_fxns.c b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/CC1352P_4_LAUNCHXL_fxns.c index ef9c0531c..eea9c3b33 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/CC1352P_4_LAUNCHXL_fxns.c +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/CC1352P_4_LAUNCHXL_fxns.c @@ -152,6 +152,12 @@ void CC1352P_4_LAUNCHXL_shutDownExtFlash(void) */ #if defined(Board_RF_SUB1GHZ) +/* + * Mask to be used to determine the effective value of the setup command's + * loDivider field. + */ +#define LODIVIDER_MASK 0x7F + /* * ======== Antenna switching ======== */ @@ -170,7 +176,7 @@ void initAntennaSwitch() } /* - * ======== rfDriverCallback ======== + * ======== CC1352P1_LAUNCHXL_rfDriverCallback ======== * Sets up the antenna switch depending on the current PHY configuration. * Truth table: * @@ -183,6 +189,10 @@ void initAntennaSwitch() */ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) { + /* Local variable. */ + bool sub1GHz = false; + uint8_t loDivider = 0; + /* Switch off all paths first. Needs to be done anyway in every sub-case below. */ PINCC26XX_setOutputValue(Board_RF_24GHZ, 0); PINCC26XX_setOutputValue(Board_RF_HIGH_PA, 0); @@ -195,15 +205,36 @@ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) /* Decode the generic argument as a setup command. */ RF_RadioSetup* setupCommand = (RF_RadioSetup*)arg; - if (setupCommand->common.commandNo == CMD_PROP_RADIO_DIV_SETUP) { + switch (setupCommand->common.commandNo) { + case (CMD_RADIO_SETUP): + case (CMD_BLE5_RADIO_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->common.loDivider; + + /* Sub-1GHz front-end. */ + if (loDivider != 0) { + sub1GHz = true; + } + break; + case (CMD_PROP_RADIO_DIV_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->prop_div.loDivider; + + /* Sub-1GHz front-end. */ + if (loDivider != 0) { + sub1GHz = true; + } + break; + default:break; + } + + if (sub1GHz) { /* Sub-1 GHz */ if (paType == RF_TxPowerTable_HighPA) { /* PA enable --> HIGH PA * LNA enable --> Sub-1 GHz */ PINCC26XX_setMux(antennaPins, Board_RF_24GHZ, PINCC26XX_MUX_GPIO); - // Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not - // de-asserted on CC1352 Rev A. + /* Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not + de-asserted on CC1352 Rev A. */ PINCC26XX_setMux(antennaPins, Board_RF_HIGH_PA, PINCC26XX_MUX_RFC_GPO3); PINCC26XX_setMux(antennaPins, Board_RF_SUB1GHZ, PINCC26XX_MUX_RFC_GPO0); } else { @@ -221,8 +252,8 @@ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) * LNA enable --> 2.4 GHz */ PINCC26XX_setMux(antennaPins, Board_RF_24GHZ, PINCC26XX_MUX_RFC_GPO0); - // Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not - // de-asserted on CC1352 Rev A. + /* Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not + de-asserted on CC1352 Rev A. */ PINCC26XX_setMux(antennaPins, Board_RF_HIGH_PA, PINCC26XX_MUX_RFC_GPO3); PINCC26XX_setMux(antennaPins, Board_RF_SUB1GHZ, PINCC26XX_MUX_GPIO); } else { diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/rf-conf.h new file mode 100644 index 000000000..af183614b --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p-4/rf-conf.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for both the Sub-1 GHz + * path and the 2.4 GHz path on the radio. + * + * These are the following front-end mode configurations for the + * CC1352P-4-LAUNCHXL board: + * - Sub-1 GHz: differential and external bias + * - 2.4 GHz: differential and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL + +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/Board.h index 1fef09180..db07b3a0d 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC1352P1_LAUNCHXL -#define BOARD_STRING "TI CC1352P1 LaunchPad" - #ifdef __cplusplus extern "C" { #endif #include "CC1352P1_LAUNCHXL.h" +#define Board_CC1352P1_LAUNCHXL +#define BOARD_STRING "TI CC1352P1 LaunchPad" + #define Board_initGeneral() CC1352P1_LAUNCHXL_initGeneral() #define Board_shutDownExtFlash() CC1352P1_LAUNCHXL_shutDownExtFlash() #define Board_wakeUpExtFlash() CC1352P1_LAUNCHXL_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/CC1352P1_LAUNCHXL_fxns.c b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/CC1352P1_LAUNCHXL_fxns.c index 9f3000929..795f60106 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/CC1352P1_LAUNCHXL_fxns.c +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/CC1352P1_LAUNCHXL_fxns.c @@ -152,6 +152,12 @@ void CC1352P1_LAUNCHXL_shutDownExtFlash(void) */ #if defined(Board_RF_SUB1GHZ) +/* + * Mask to be used to determine the effective value of the setup command's + * loDivider field. + */ +#define LODIVIDER_MASK 0x7F + /* * ======== Antenna switching ======== */ @@ -170,7 +176,7 @@ void initAntennaSwitch() } /* - * ======== rfDriverCallback ======== + * ======== CC1352P1_LAUNCHXL_rfDriverCallback ======== * Sets up the antenna switch depending on the current PHY configuration. * Truth table: * @@ -183,6 +189,10 @@ void initAntennaSwitch() */ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) { + /* Local variable. */ + bool sub1GHz = false; + uint8_t loDivider = 0; + /* Switch off all paths first. Needs to be done anyway in every sub-case below. */ PINCC26XX_setOutputValue(Board_RF_24GHZ, 0); PINCC26XX_setOutputValue(Board_RF_HIGH_PA, 0); @@ -195,15 +205,36 @@ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) /* Decode the generic argument as a setup command. */ RF_RadioSetup* setupCommand = (RF_RadioSetup*)arg; - if (setupCommand->common.commandNo == CMD_PROP_RADIO_DIV_SETUP) { + switch (setupCommand->common.commandNo) { + case (CMD_RADIO_SETUP): + case (CMD_BLE5_RADIO_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->common.loDivider; + + /* Sub-1GHz front-end. */ + if (loDivider != 0) { + sub1GHz = true; + } + break; + case (CMD_PROP_RADIO_DIV_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->prop_div.loDivider; + + /* Sub-1GHz front-end. */ + if (loDivider != 0) { + sub1GHz = true; + } + break; + default:break; + } + + if (sub1GHz) { /* Sub-1 GHz */ if (paType == RF_TxPowerTable_HighPA) { /* PA enable --> HIGH PA * LNA enable --> Sub-1 GHz */ PINCC26XX_setMux(antennaPins, Board_RF_24GHZ, PINCC26XX_MUX_GPIO); - // Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not - // de-asserted on CC1352 Rev A. + /* Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not + de-asserted on CC1352 Rev A. */ PINCC26XX_setMux(antennaPins, Board_RF_HIGH_PA, PINCC26XX_MUX_RFC_GPO3); PINCC26XX_setMux(antennaPins, Board_RF_SUB1GHZ, PINCC26XX_MUX_RFC_GPO0); } else { @@ -221,8 +252,8 @@ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) * LNA enable --> 2.4 GHz */ PINCC26XX_setMux(antennaPins, Board_RF_24GHZ, PINCC26XX_MUX_RFC_GPO0); - // Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not - // de-asserted on CC1352 Rev A. + /* Note: RFC_GPO3 is a work-around because the RFC_GPO1 (PA enable signal) is sometimes not + de-asserted on CC1352 Rev A. */ PINCC26XX_setMux(antennaPins, Board_RF_HIGH_PA, PINCC26XX_MUX_RFC_GPO3); PINCC26XX_setMux(antennaPins, Board_RF_SUB1GHZ, PINCC26XX_MUX_GPIO); } else { diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/rf-conf.h new file mode 100644 index 000000000..c18573f7a --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352p1/rf-conf.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for both the Sub-1 GHz + * path and the 2.4 GHz path on the radio. + * + * These are the following front-end mode configurations for the + * CC1352P1-LAUNCHXL board: + * - Sub-1 GHz: differential and external bias + * - 2.4 GHz: differential and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL + +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/Board.h index 8bf0ee002..83b27069a 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC1352R1_LAUNCHXL -#define BOARD_STRING "TI CC1352R1 LaunchPad" - #ifdef __cplusplus extern "C" { #endif #include "CC1352R1_LAUNCHXL.h" +#define Board_CC1352R1_LAUNCHXL +#define BOARD_STRING "TI CC1352R1 LaunchPad" + #define Board_initGeneral() CC1352R1_LAUNCHXL_initGeneral() #define Board_shutDownExtFlash() CC1352R1_LAUNCHXL_shutDownExtFlash() #define Board_wakeUpExtFlash() CC1352R1_LAUNCHXL_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/CC1352R1_LAUNCHXL.c b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/CC1352R1_LAUNCHXL.c index d2b3eeee3..f3d002206 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/CC1352R1_LAUNCHXL.c +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/CC1352R1_LAUNCHXL.c @@ -36,8 +36,6 @@ * CC1352R1_LAUNCHXL board. */ -#include "contiki.h" - #include #include #include diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/CC1352R1_LAUNCHXL_fxns.c b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/CC1352R1_LAUNCHXL_fxns.c index 520b91297..79d97d7b6 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/CC1352R1_LAUNCHXL_fxns.c +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/CC1352R1_LAUNCHXL_fxns.c @@ -164,23 +164,61 @@ void Board_initHook() */ #if defined(Board_RF_SUB1GHZ) +/* + * Mask to be used to determine the effective value of the setup command's + * loDivider field. + */ +#define LODIVIDER_MASK 0x7F + /* * ======== rfDriverCallback ======== - * This is an implementation for the CC1352R1 launchpad which uses a + * This is an implementation for the CC1352R launchpad which uses a * single signal for antenna switching. */ void rfDriverCallback(RF_Handle client, RF_GlobalEvent events, void *arg) { + /* Decode input arguments. */ (void)client; RF_RadioSetup* setupCommand = (RF_RadioSetup*)arg; - if ((events & RF_GlobalEventRadioSetup) && - (setupCommand->common.commandNo == CMD_PROP_RADIO_DIV_SETUP)) { - /* Sub-1 GHz, requires antenna switch high */ - PINCC26XX_setOutputValue(Board_RF_SUB1GHZ, 1); + /* Local variable. */ + bool sub1GHz = false; + uint8_t loDivider = 0; + + if (events & RF_GlobalEventRadioSetup) { + /* Decision about the frequency band shall be made based on the + loDivider field. */ + switch (setupCommand->common.commandNo) { + case (CMD_RADIO_SETUP): + case (CMD_BLE5_RADIO_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->common.loDivider; + + /* Sub-1GHz front-end. */ + if (loDivider != 0) { + sub1GHz = true; + } + break; + case (CMD_PROP_RADIO_DIV_SETUP): + loDivider = LODIVIDER_MASK & setupCommand->prop_div.loDivider; + + /* Sub-1GHz front-end. */ + if (loDivider != 0) { + sub1GHz = true; + } + break; + default:break; + } + + /* Select the correct antenna. */ + if (sub1GHz) { + PINCC26XX_setOutputValue(Board_RF_SUB1GHZ, 1); + } + else { + PINCC26XX_setOutputValue(Board_RF_SUB1GHZ, 0); + } } else if (events & RF_GlobalEventRadioPowerDown) { - /* Disable antenna switch to save current */ + /* Set the antenna to 2.4 GHz as default. */ PINCC26XX_setOutputValue(Board_RF_SUB1GHZ, 0); } } diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/rf-conf.h new file mode 100644 index 000000000..ba652cd53 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc1352r1/rf-conf.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for both the Sub-1 GHz + * path and the 2.4 GHz path on the radio. + * + * These are the following front-end mode configurations for the + * CC1352R1-LAUNCHXL board: + * - Sub-1 GHz: differential and external bias + * - 2.4 GHz: differential and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL + +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc2650/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc2650/Board.h index 8f3e437f0..577ce0422 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc2650/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc2650/Board.h @@ -33,18 +33,18 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC2650_LAUNCHXL -#define BOARD_STRING "TI CC2650 LaunchPad" - #ifdef __cplusplus extern "C" { #endif #include "CC2650_LAUNCHXL.h" -#define Board_initGeneral() CC2650_LAUNCHXL_initGeneral() +#define Board_CC2650_LAUNCHXL +#define BOARD_STRING "TI CC2650 LaunchPad" + +#define Board_initGeneral() CC2650_LAUNCHXL_initGeneral() #define Board_shutDownExtFlash() CC2650_LAUNCHXL_shutDownExtFlash() -#define Board_wakeUpExtFlash() CC2650_LAUNCHXL_wakeUpExtFlash() +#define Board_wakeUpExtFlash() CC2650_LAUNCHXL_wakeUpExtFlash() /* These #defines allow us to reuse TI-RTOS across other device families */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc2650/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc2650/rf-conf.h new file mode 100644 index 000000000..9d6abaeac --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc2650/rf-conf.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for the 2.4 GHz path + * on the radio. + * + * These are the following front-end mode configurations for the + * CC2650-LAUNCHXL board: + * - 2.4 GHz: differential and internal bias + * + * @{ + */ +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_INTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/Board.h index a19145b2c..ddf5e4946 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/Board.h @@ -33,20 +33,18 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC26X2R1_LAUNCHXL -#define BOARD_STRING "TI CC26x2R1 LaunchPad" - #ifdef __cplusplus extern "C" { #endif #include "CC26X2R1_LAUNCHXL.h" -#define Board_initGeneral() CC26X2R1_LAUNCHXL_initGeneral() +#define Board_CC26X2R1_LAUNCHXL +#define BOARD_STRING "TI CC26x2R1 LaunchPad" +#define Board_initGeneral() CC26X2R1_LAUNCHXL_initGeneral() #define Board_shutDownExtFlash() CC26X2R1_LAUNCHXL_shutDownExtFlash() - -#define Board_wakeUpExtFlash() CC26X2R1_LAUNCHXL_wakeUpExtFlash() +#define Board_wakeUpExtFlash() CC26X2R1_LAUNCHXL_wakeUpExtFlash() /* These #defines allow us to reuse TI-RTOS across other device families */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/CC26X2R1_LAUNCHXL.c b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/CC26X2R1_LAUNCHXL.c index a66a6ef00..854d1d2ba 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/CC26X2R1_LAUNCHXL.c +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/CC26X2R1_LAUNCHXL.c @@ -35,7 +35,6 @@ * This file is responsible for setting up the board specific items for the * CC26X2R1_LAUNCHXL board. */ -#include "contiki.h" #include #include diff --git a/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/rf-conf.h new file mode 100644 index 000000000..ed58c8732 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/launchpad/cc26x2r1/rf-conf.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for the 2.4 GHz path + * on the radio. + * + * These are the following front-end mode configurations for the + * CC26X2R1-LAUNCHXL board: + * - 2.4 GHz: differential and internal bias + * + * @{ + */ +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_INTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/board-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/board-conf.h index bb8689c98..5ff2f78d8 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/board-conf.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/board-conf.h @@ -50,8 +50,7 @@ #ifndef BOARD_CONF_H_ #define BOARD_CONF_H_ /*---------------------------------------------------------------------------*/ -#include "contiki-conf.h" -/*---------------------------------------------------------------------------*/ +#include "rf-conf.h" #include "leds-arch.h" /*---------------------------------------------------------------------------*/ /** diff --git a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc1350/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc1350/Board.h index ecdb6d2af..e32e74fc1 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc1350/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc1350/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC1350STK -#define BOARD_STRING "TI CC1350 SensorTag" - #ifdef __cplusplus extern "C" { #endif #include "CC1350STK.h" +#define Board_CC1350STK +#define BOARD_STRING "TI CC1350 SensorTag" + #define Board_initGeneral() CC1350STK_initGeneral() #define Board_shutDownExtFlash() CC1350STK_shutDownExtFlash() #define Board_wakeUpExtFlash() CC1350STK_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc1350/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc1350/rf-conf.h new file mode 100644 index 000000000..1f3dfbe52 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc1350/rf-conf.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for both the Sub-1 GHz + * path and the 2.4 GHz path on the radio. + * + * These are the following front-end mode configurations for the + * CC1350STK board: + * - Sub-1 GHz: single-ended RFN and external bias + * - 2.4 GHz: single-ended RFP and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_SINGLE_ENDED_RFN +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL + +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_SINGLE_ENDED_RFP +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc2650/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc2650/Board.h index e334645bb..8425de454 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc2650/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc2650/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC2650STK -#define BOARD_STRING "TI CC2650 SensorTag" - #ifdef __cplusplus extern "C" { #endif #include "CC2650STK.h" +#define Board_CC2650STK +#define BOARD_STRING "TI CC2650 SensorTag" + #define Board_initGeneral() CC2650STK_initGeneral() #define Board_shutDownExtFlash() CC2650STK_shutDownExtFlash() #define Board_wakeUpExtFlash() CC2650STK_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc2650/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc2650/rf-conf.h new file mode 100644 index 000000000..48db37a96 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/cc2650/rf-conf.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for the 2.4 GHz path + * on the radio. + * + * These are the following front-end mode configurations for the + * CC2650STK board: + * - 2.4 GHz: differential and internal bias + * + * @{ + */ +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_INTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/opt-3001-sensor.c b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/opt-3001-sensor.c index 885fefe88..42e3976d8 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/sensortag/opt-3001-sensor.c +++ b/arch/platform/simplelink/cc13xx-cc26xx/sensortag/opt-3001-sensor.c @@ -303,9 +303,13 @@ value(int type) result_value = SWAP16(result_value); - uint32_t e = (result_value & 0x0FFF) >> 0; - uint32_t m = (result_value & 0xF000) >> 12; - uint32_t converted = m * 100 * (1 << e); + /* formula for computing lux: lux = 0.01 * 2^e * m + * scale up by 100 to avoid floating point, then require + * users to scale down by same. + */ + uint32_t m = (result_value & 0x0FFF) >> 0; + uint32_t e = (result_value & 0xF000) >> 12; + uint32_t converted = m * (1 << e); PRINTF("OPT: %04X r=%d (centilux)\n", result_value, (int)(converted)); diff --git a/arch/platform/simplelink/cc13xx-cc26xx/srf06/board-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/srf06/board-conf.h index 037e7eb3f..7d6f8328f 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/srf06/board-conf.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/srf06/board-conf.h @@ -42,6 +42,8 @@ #ifndef BOARD_CONF_H_ #define BOARD_CONF_H_ /*---------------------------------------------------------------------------*/ +#include "rf-conf.h" +/*---------------------------------------------------------------------------*/ /** * \name LED configurations for the dev/leds.h API. * diff --git a/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc13x0/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc13x0/Board.h index 0941b222f..48d232e54 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc13x0/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc13x0/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC1350DK_7XD -#define BOARD_STRING "TI SmartRF06EB + CC13x0 EM" - #ifdef __cplusplus extern "C" { #endif #include "CC1350DK_7XD.h" +#define Board_CC1350DK_7XD +#define BOARD_STRING "TI SmartRF06EB + CC13x0 EM" + #define Board_initGeneral() CC1350DK_7XD_initGeneral() #define Board_shutDownExtFlash() CC1350DK_7XD_shutDownExtFlash() #define Board_wakeUpExtFlash() CC1350DK_7XD_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc13x0/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc13x0/rf-conf.h new file mode 100644 index 000000000..327e8fb5d --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc13x0/rf-conf.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for both the Sub-1 GHz + * path and the 2.4 GHz path on the radio. + * + * These are the following front-end mode configurations for the + * CC1350DK-7XD board: + * - Sub-1 GHz: differential and external bias + * - 2.4 GHz: differential and external bias + * + * @{ + */ +#define RF_SUB_1_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_SUB_1_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL + +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_EXTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc26x0/Board.h b/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc26x0/Board.h index c42d3a169..d90291418 100644 --- a/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc26x0/Board.h +++ b/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc26x0/Board.h @@ -33,15 +33,15 @@ #ifndef __BOARD_H #define __BOARD_H -#define Board_CC2650DK_7ID -#define BOARD_STRING "TI SmartRF06EB + CC26x0 EM" - #ifdef __cplusplus extern "C" { #endif #include "CC2650DK_7ID.h" +#define Board_CC2650DK_7ID +#define BOARD_STRING "TI SmartRF06EB + CC26x0 EM" + #define Board_initGeneral() CC2650DK_7ID_initGeneral() #define Board_shutDownExtFlash() CC2650DK_7ID_shutDownExtFlash() #define Board_wakeUpExtFlash() CC2650DK_7ID_wakeUpExtFlash() diff --git a/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc26x0/rf-conf.h b/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc26x0/rf-conf.h new file mode 100644 index 000000000..bdbade005 --- /dev/null +++ b/arch/platform/simplelink/cc13xx-cc26xx/srf06/cc26x0/rf-conf.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 launchpad-peripherals + * @{ + * + * \file + * Header file with board-specific RF configurations. + * \author + * Texas Instruments + * \note + * This file should not be included directly + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CONF_H_ +#define RF_CONF_H_ +/*---------------------------------------------------------------------------*/ +#include "rf/rf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Board-specific front-end mode configurations for the 2.4 GHz path + * on the radio. + * + * These are the following front-end mode configurations for the + * CC2650DK-7ID board: + * - 2.4 GHz: differential and internal bias + * + * @{ + */ +#define RF_2_4_GHZ_CONF_FRONT_END_MODE RF_FRONT_END_MODE_DIFFERENTIAL +#define RF_2_4_GHZ_CONF_BIAS_MODE RF_BIAS_MODE_INTERNAL +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* RF_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/arch/platform/z1/Makefile.common b/arch/platform/z1/Makefile.common new file mode 100644 index 000000000..42172022b --- /dev/null +++ b/arch/platform/z1/Makefile.common @@ -0,0 +1,145 @@ + +# +# Currently enabling SMALL breaks the build on this platform. +# No large effect is expected anyway: unused sections are discarded even if SMALL is not set. +# +SMALL=0 + +ARCH = leds.c xmem.c i2cmaster.c \ + spi-legacy.c cc2420.c cc2420-arch.c cc2420-arch-sfd.c\ + node-id-z1.c sensors.c button-sensor.c cfs-coffee.c \ + uart0.c uart0-putchar.c uip-ipchksum.c \ + slip.c slip_uart0.c z1-sensors.c adxl345.c temperature-sensor.c \ + z1-phidgets.c light-sensor.c battery-sensor.c sky-sensors.c tmp102.c \ + platform.c + +CONTIKI_TARGET_DIRS = . dev apps +ifndef CONTIKI_TARGET_MAIN +CONTIKI_TARGET_MAIN = contiki-main.c +endif + +CONTIKI_TARGET_SOURCEFILES += $(ARCH) + +MCU=msp430f2617 +CPU_HAS_MSP430X=1 + +LDFLAGS += -Wl,--defsym -Wl,__P1SEL2=0x0041 -Wl,--defsym -Wl,__P5SEL2=0x0045 + +ifdef nodemac +CFLAGS += -DMACID=$(nodemac) +endif + +CFLAGS += -g + +include $(ARCH_PATH)/cpu/msp430/Makefile.msp430 + + +NUMPAR=20 +IHEXFILE=tmpimage.ihex + +ifeq ($(HOST_OS),Darwin) + ifndef MOTELIST + USBDEVPREFIX= + SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-linux + MOTELIST = $(CONTIKI)/tools/zolertia/motelist-zolertia-macos + BSL = $(CONTIKI)/tools/zolertia/z1-bsl-nopic --z1 + BSL_FILETYPE = -I + MOTES = $(shell $(MOTELIST) -b z1 -c 2>&- | \ + cut -f 2 -d ,) + REFNUM = $(shell $(MOTELIST) -c 2>&- | \ + cut -f 1 -d , | tail -c5 | sed 's/^0*//') + ifneq (,$(REFNUM)) + # No device fo-und + ifeq (,$(findstring und, $(REFNUM))) + CFLAGS += -DSERIALNUM=$(REFNUM:0%=%) + endif + endif + endif +else + # If we are not running under Mac, we assume Linux + ifndef MOTELIST + USBDEVPREFIX= + SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-linux + MOTELIST = $(CONTIKI)/tools/zolertia/motelist-zolertia + BSL = $(CONTIKI)/tools/zolertia/z1-bsl-nopic --z1 + BSL_FILETYPE = -I + MOTES = $(shell $(MOTELIST) -b z1 -c 2>&- | \ + cut -f 2 -d , | \ + perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);') + CMOTES=$(MOTES) + REFNUM = $(shell $(MOTELIST) -c 2>&- | \ + cut -f 1 -d , | tail -c5 | sed 's/^0*//') + ifneq (,$(REFNUM)) + # No device fo-und + ifeq (,$(findstring und, $(REFNUM))) + CFLAGS += -DSERIALNUM=$(REFNUM) + endif + endif + endif +endif + +motelist: + $(MOTELIST) +z1-motelist: + $(MOTELIST) -b z1 +z1-motes: + @echo $(MOTES) + +ifdef MOTE +%.upload: %.ihex + cp $< $(IHEXFILE) + $(MAKE) z1-u.$(subst /,-,$(word $(MOTE), $(MOTES))) +else # MOTE +%.upload: %.ihex + cp $< $(IHEXFILE) + @echo $(MOTES) + $(MAKE) z1-reset z1-upload +endif # MOTE + +z1-upload: z1-reset + $(MAKE) -j $(NUMPAR) z1-upload-sequence + +z1-upload-sequence: $(foreach PORT, $(MOTES), z1-u.$(subst /,-,$(PORT))) + @echo Done + +z1-reset: + $(MAKE) -k -j $(NUMPAR) z1-reset-sequence + +z1-reset-sequence: $(foreach PORT, $(MOTES), z1-r.$(subst /,-,$(PORT))) + @echo Done + +z1-u.%: + @echo +++++ Erasing $(subst -,/,$*); \ + $(BSL) -c $(subst -,/,$*) -e && sleep 2 ; \ + echo +++++ Programming $(subst -,/,$*) ; \ + $(BSL) -c $(subst -,/,$*) $(BSL_FILETYPE) -p $(IHEXFILE) && sleep 2 ; \ + echo +++++ Resetting $(subst -,/,$*) ; \ + $(BSL) -c $(subst -,/,$*) -r + +z1-r.%: + $(BSL) -c $(subst -,/,$*) -r + +sizeplot: + msp430-size $(OBJECTDIR)/*.o | $(CONTIKI)/tools/sky/check-size > size-data + gnuplot $(CONTIKI)/tools/sky/plot-size + gv size.pdf + +winslip: +ifdef INTERFACE + $(CONTIKI)/tools/wpcapslip/wpcapslip -s $(USBDEVPREFIX)$(firstword $(CMOTES)) $(INTERFACE) 172.16.0.0 255.255.0.0 +else + @echo "Usage: \"$(MAKE) $@ INTERFACE=\"" + @echo "Use the \"ipconfig\" command to find out the IP addresses of the local interfaces" +endif + +linslip: $(CONTIKI)/tools/tunslip + $(CONTIKI)/tools/tunslip -s $(USBDEVPREFIX)$(firstword $(CMOTES)) 172.16.0.0 255.255.0.0 + +$(CONTIKI)/tools/tunslip: + (cd $(CONTIKI)/tools; $(MAKE) tunslip) + +ifdef MOTE + PORT = $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) +else + PORT = $(USBDEVPREFIX)$(firstword $(CMOTES)) +endif diff --git a/arch/platform/z1/Makefile.z1 b/arch/platform/z1/Makefile.z1 new file mode 100644 index 000000000..aeff61bf2 --- /dev/null +++ b/arch/platform/z1/Makefile.z1 @@ -0,0 +1,11 @@ +# Common Makefile between Z1 and Z1SP + +CONTIKI_TARGET_SOURCEFILES += contiki-z1-platform.c + +include $(ARCH_PATH)/platform/z1/Makefile.common + +ifeq ($(ZOLERTIA_Z1SP),1) +include $(ARCH_PATH)/platform/z1/Makefile.z1sp +endif + +MODULES += arch/dev/cc2420 os/storage/cfs diff --git a/arch/platform/z1/Makefile.z1sp b/arch/platform/z1/Makefile.z1sp new file mode 100644 index 000000000..29b8fcbd1 --- /dev/null +++ b/arch/platform/z1/Makefile.z1sp @@ -0,0 +1,6 @@ +# Makefile for Z1 Starter Platform + +# This is the actual flag we need to include specific Z1SP components +CFLAGS += -DZ1_IS_Z1SP + +CONTIKI_TARGET_SOURCEFILES += potentiometer-sensor.c diff --git a/arch/platform/z1/README.z1sp b/arch/platform/z1/README.z1sp new file mode 100644 index 000000000..8db1e48da --- /dev/null +++ b/arch/platform/z1/README.z1sp @@ -0,0 +1,9 @@ +Using the Z1 starter platform (Z1SP) +============================================ + +To enable the Z1SP components, you should include in your application Makefile +the ZOLERTIA_Z1SP flag set to 1, see "examples/z1/Makefile". + +For Z1SP specific information please go to: + +http://zolertia.sourceforge.net/wiki/index.php/Mainpage:z1sp diff --git a/arch/platform/z1/apps/burn-nodeid.c b/arch/platform/z1/apps/burn-nodeid.c new file mode 100644 index 000000000..0f469cac4 --- /dev/null +++ b/arch/platform/z1/apps/burn-nodeid.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * A program for burning a node ID into the flash ROM of a Tmote Sky node. + * \author + * Adam Dunkels + */ + +#include "dev/leds.h" +#include "dev/watchdog.h" +#include "sys/node-id.h" +#include "contiki.h" +#include "sys/etimer.h" + +#include "node-id-z1.h" + +#include + +static struct etimer etimer; + +PROCESS(burn_process, "Burn node id"); +AUTOSTART_PROCESSES(&burn_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(burn_process, ev, data) +{ + PROCESS_BEGIN(); + + etimer_set(&etimer, 5*CLOCK_SECOND); + PROCESS_WAIT_UNTIL(etimer_expired(&etimer)); + + watchdog_stop(); + leds_on(LEDS_RED); +#if NODEID + #warning "***** BURNING NODE ID" + printf("Burning node id %d\n", NODEID); + node_id_burn(NODEID); + leds_on(LEDS_BLUE); + node_id_restore(); + printf("Restored node id %d\n", node_id); +#else +#error "burn-nodeid must be compiled with nodeid=" + node_id_restore(); + printf("Restored node id %d\n", node_id); +#endif + leds_off(LEDS_RED + LEDS_BLUE); + watchdog_start(); + while(1) { + PROCESS_WAIT_EVENT(); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/cfs-coffee-arch.h b/arch/platform/z1/cfs-coffee-arch.h new file mode 100644 index 000000000..3225e2f32 --- /dev/null +++ b/arch/platform/z1/cfs-coffee-arch.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2008, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Coffee architecture-dependent header for the Zolertia Z1 platform. + * \author + * Nicolas Tsiftes + * Enric M. Calvo + */ + +#ifndef CFS_COFFEE_ARCH_H +#define CFS_COFFEE_ARCH_H + +#include "contiki-conf.h" +#include "dev/xmem.h" + +/*** M25P16 Memory Organization +The memory is organized as: +16Mbit = 2 097 152 bytes (8 bits each) +32 sectors (512 Kbits, 65536 bytes each) +8192 pages (256 bytes each). +Each page can be individually programmed (bits are programmed from 1 to 0). The device is +sector or bulk erasable (bits are erased from 0 to 1) but not page erasable +*/ + +/* Total size of the External Flash Memory in the Z1 */ +#define COFFEE_XMEM_TOTAL_SIZE_KB 2048UL + +/* Coffee configuration parameters. */ +#define COFFEE_SECTOR_SIZE 65536UL +#define COFFEE_PAGE_SIZE 256UL +#define COFFEE_START COFFEE_SECTOR_SIZE +#define COFFEE_SIZE (COFFEE_XMEM_TOTAL_SIZE_KB * 1024UL - COFFEE_START) +#define COFFEE_NAME_LENGTH 16 +#define COFFEE_MAX_OPEN_FILES 6 +#define COFFEE_FD_SET_SIZE 8 +#define COFFEE_LOG_TABLE_LIMIT 256 +#define COFFEE_DYN_SIZE 4*1024 +#define COFFEE_LOG_SIZE 1024 + +#define COFFEE_MICRO_LOGS 1 + +/* Flash operations. */ +#define COFFEE_WRITE(buf, size, offset) \ + xmem_pwrite((char *)(buf), (size), COFFEE_START + (offset)) + +#define COFFEE_READ(buf, size, offset) \ + xmem_pread((char *)(buf), (size), COFFEE_START + (offset)) + +#define COFFEE_ERASE(sector) \ + xmem_erase(COFFEE_SECTOR_SIZE, COFFEE_START + (sector) * COFFEE_SECTOR_SIZE) + +/* Coffee types. */ +typedef int16_t coffee_page_t; + +#endif /* !CFS_COFFEE_ARCH_H */ diff --git a/arch/platform/z1/contiki-conf.h b/arch/platform/z1/contiki-conf.h new file mode 100644 index 000000000..e31a9fbcd --- /dev/null +++ b/arch/platform/z1/contiki-conf.h @@ -0,0 +1,72 @@ +#ifndef CONTIKI_CONF_H +#define CONTIKI_CONF_H + +/* include the project config */ +#ifdef PROJECT_CONF_PATH +#include PROJECT_CONF_PATH +#endif /* PROJECT_CONF_PATH */ +/*---------------------------------------------------------------------------*/ +#include "z1-def.h" +#include "msp430-def.h" +/*---------------------------------------------------------------------------*/ + +/* Configure radio driver */ +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc2420_driver +#endif /* NETSTACK_CONF_RADIO */ + +/* Symbol for the TSCH 15ms timeslot timing template */ +#define TSCH_CONF_ARCH_HDR_PATH "dev/cc2420/cc2420-tsch-15ms.h" + +/* The TSCH default slot length of 10ms is a bit too short for this platform, + * use 15ms instead. */ +#ifndef TSCH_CONF_DEFAULT_TIMESLOT_TIMING +#define TSCH_CONF_DEFAULT_TIMESLOT_TIMING tsch_timeslot_timing_us_15000 +#endif /* TSCH_CONF_DEFAULT_TIMESLOT_TIMING */ + +/* Save RAM through a smaller uIP buffer */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 140 +#endif + +#define PROCESS_CONF_NUMEVENTS 8 +#define PROCESS_CONF_STATS 1 +/*#define PROCESS_CONF_FASTPOLL 4*/ + +/* So far, printfs without interrupt. */ +#define UART0_CONF_TX_WITH_INTERRUPT 0 +/* This does not work in Cooja. */ +#define UART0_CONF_RX_WITH_DMA 0 + +/* Handle 10 neighbors */ +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#endif + +/* Handle 10 routes */ +#ifndef NETSTACK_MAX_ROUTE_ENTRIES +#define NETSTACK_MAX_ROUTE_ENTRIES 10 +#endif + +/* Handle 10 links */ +#ifndef TSCH_SCHEDULE_CONF_MAX_LINKS +#define TSCH_SCHEDULE_CONF_MAX_LINKS 10 +#endif + +#ifndef TSCH_CONF_MAX_INCOMING_PACKETS +#define TSCH_CONF_MAX_INCOMING_PACKETS 2 +#endif + +#ifndef TSCH_QUEUE_CONF_NUM_PER_NEIGHBOR +#define TSCH_QUEUE_CONF_NUM_PER_NEIGHBOR 4 +#endif + +/* Platform-specific (H/W) AES implementation */ +#ifndef AES_128_CONF +#define AES_128_CONF cc2420_aes_128_driver +#endif /* AES_128_CONF */ + +/*---------------------------------------------------------------------------*/ +#include "msp430-conf.h" +/*---------------------------------------------------------------------------*/ +#endif /* CONTIKI_CONF_H */ diff --git a/arch/platform/z1/contiki-z1-platform.c b/arch/platform/z1/contiki-z1-platform.c new file mode 100644 index 000000000..60272bb00 --- /dev/null +++ b/arch/platform/z1/contiki-z1-platform.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + * Author: Enric M. Calvo based on previous work by + * Niclas Finne , Joakim Eriksson + * + */ + +#include "dev/button-sensor.h" + +void +init_platform(void) +{ + process_start(&sensors_process, NULL); +} diff --git a/arch/platform/z1/dev/adxl345.c b/arch/platform/z1/dev/adxl345.c new file mode 100644 index 000000000..08e170432 --- /dev/null +++ b/arch/platform/z1/dev/adxl345.c @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * Device drivers for adxl345 accelerometer in Zolertia Z1. + * \author + * Marcus Lundén, SICS + * Enric M. Calvo, Zolertia + * Antonio Lignan, Zolertia + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "adxl345.h" +#include "cc2420.h" +#include "i2cmaster.h" +#include "isr_compat.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +/* Callback pointers when interrupt occurs */ +void (*accm_int1_cb)(uint8_t reg); +void (*accm_int2_cb)(uint8_t reg); +/*---------------------------------------------------------------------------*/ +/* Bitmasks for the interrupts */ +static uint16_t int1_mask = 0, int2_mask = 0; + +/* Default values for adxl345 at startup. + * This will be sent to the adxl345 in a + * stream at init to set it up in a default state + */ + +static uint8_t adxl345_default_settings[] = { + /* Note, as the two first two bulks are to be written in a stream, they contain + * the register address as first byte in that section. + * 0--14 are in one stream, start at ADXL345_THRESH_TAP + */ + /* XXX NB Register address, not register value!! */ + ADXL345_THRESH_TAP, + ADXL345_THRESH_TAP_DEFAULT, + ADXL345_OFSX_DEFAULT, + ADXL345_OFSY_DEFAULT, + ADXL345_OFSZ_DEFAULT, + ADXL345_DUR_DEFAULT, + ADXL345_LATENT_DEFAULT, + ADXL345_WINDOW_DEFAULT, + ADXL345_THRESH_ACT_DEFAULT, + ADXL345_THRESH_INACT_DEFAULT, + ADXL345_TIME_INACT_DEFAULT, + ADXL345_ACT_INACT_CTL_DEFAULT, + ADXL345_THRESH_FF_DEFAULT, + ADXL345_TIME_FF_DEFAULT, + ADXL345_TAP_AXES_DEFAULT, + + /* 15--19 start at ADXL345_BW_RATE */ + /* XXX NB Register address, not register value!! */ + ADXL345_BW_RATE, + ADXL345_BW_RATE_DEFAULT, + ADXL345_POWER_CTL_DEFAULT, + ADXL345_INT_ENABLE_DEFAULT, + ADXL345_INT_MAP_DEFAULT, + + /* These two: 20, 21 write separately */ + ADXL345_DATA_FORMAT_DEFAULT, + ADXL345_FIFO_CTL_DEFAULT +}; +/*---------------------------------------------------------------------------*/ +PROCESS(accmeter_process, "Accelerometer process"); +/*---------------------------------------------------------------------------*/ +static void +accm_write_reg(uint8_t reg, uint8_t val) +{ + uint8_t tx_buf[] = {reg, val}; + + i2c_transmitinit(ADXL345_ADDR); + while (i2c_busy()); + PRINTF("ADXL345: I2C Ready to TX\n"); + + i2c_transmit_n(2, tx_buf); + while (i2c_busy()); + PRINTF("ADXL345: WRITE_REG 0x%02X @ reg 0x%02X\n", val, reg); +} +/*---------------------------------------------------------------------------*/ +/* First byte in stream must be the register address to begin writing to. + * The data is then written from second byte and increasing. + */ +static void +accm_write_stream(uint8_t len, uint8_t *data) +{ + i2c_transmitinit(ADXL345_ADDR); + while (i2c_busy()); + PRINTF("ADXL345: I2C Ready to TX(stream)\n"); + + i2c_transmit_n(len, data); // start tx and send conf reg + while (i2c_busy()); + PRINTF("ADXL345: WRITE_STR %u B to 0x%02X\n", len, data[0]); +} + +/*---------------------------------------------------------------------------*/ +static uint8_t +accm_read_reg(uint8_t reg) +{ + uint8_t retVal = 0; + uint8_t rtx = reg; + PRINTF("ADXL345: READ_REG 0x%02X\n", reg); + + /* transmit the register to read */ + i2c_transmitinit(ADXL345_ADDR); + while (i2c_busy()); + i2c_transmit_n(1, &rtx); + while (i2c_busy()); + + /* receive the data */ + i2c_receiveinit(ADXL345_ADDR); + while (i2c_busy()); + i2c_receive_n(1, &retVal); + while (i2c_busy()); + + return retVal; +} +/*---------------------------------------------------------------------------*/ +static void +accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) +{ + uint8_t rtx = reg; + PRINTF("ADXL345: READ_STR %u B from 0x%02X\n", len, reg); + + /* transmit the register to start reading from */ + i2c_transmitinit(ADXL345_ADDR); + while (i2c_busy()); + i2c_transmit_n(1, &rtx); + while (i2c_busy()); + + /* receive the data */ + i2c_receiveinit(ADXL345_ADDR); + while (i2c_busy()); + i2c_receive_n(len, whereto); + while (i2c_busy()); +} + +/*---------------------------------------------------------------------------*/ +/* Read an axis of the accelerometer (x, y or z). Return value is a signed + * 10 bit int. + * The resolution of the acceleration measurement can be increased up to 13 bit, + * but will change the data format of this read out. Refer to the data sheet if + * so is wanted/needed. + */ +int16_t +accm_read_axis(enum ADXL345_AXIS axis) +{ + int16_t rd = 0; + uint8_t tmp[2]; + if(axis > Z_AXIS){ + return 0; + } + accm_read_stream(ADXL345_DATAX0 + axis, 2, &tmp[0]); + rd = (int16_t)(tmp[0] | (tmp[1]<<8)); + return rd; +} +/*---------------------------------------------------------------------------*/ +int +accm_set_grange(uint8_t grange) +{ + uint8_t tempreg = 0; + + if(grange > ADXL345_RANGE_16G) { + PRINTF("ADXL345: grange invalid: %u\n", grange); + return ADXL345_ERROR; + } + + if(!enabled) { + return ADXL345_ERROR; + } + + /* Keep the previous contents of the register, zero out the last two bits */ + tempreg = (accm_read_reg(ADXL345_DATA_FORMAT) & 0xFC); + tempreg |= grange; + accm_write_reg(ADXL345_DATA_FORMAT, tempreg); + return ADXL345_SUCCESS; +} + +/*---------------------------------------------------------------------------*/ +void +accm_init(void) +{ + PRINTF("ADXL345: init\n"); + accm_int1_cb = NULL; + accm_int2_cb = NULL; + + /* Set up ports and pins for interrups. */ + ADXL345_DIR &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + ADXL345_SEL &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + ADXL345_SEL2 &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + + /* Set up ports and pins for I2C communication */ + i2c_enable(); + + /* set default register values. */ + accm_write_stream(15, &adxl345_default_settings[0]); + accm_write_stream(5, &adxl345_default_settings[15]); + accm_write_reg(ADXL345_DATA_FORMAT, adxl345_default_settings[20]); + accm_write_reg(ADXL345_FIFO_CTL, adxl345_default_settings[21]); + + process_start(&accmeter_process, NULL); + + /* Enable msp430 interrupts on the two interrupt pins. */ + dint(); + /* low to high transition interrupts */ + ADXL345_IES &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + /* enable interrupts */ + ADXL345_IE |= (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + eint(); + + enabled = 1; +} +/*---------------------------------------------------------------------------*/ +void +accm_stop(void) +{ + dint(); + ADXL345_IE &= ~(ADXL345_INT1_PIN | ADXL345_INT2_PIN); + accm_write_reg(ADXL345_INT_ENABLE, ~(int1_mask | int2_mask)); + accm_write_reg(ADXL345_INT_MAP, ~int2_mask); + eint(); + enabled = 0; +} +/*---------------------------------------------------------------------------*/ +int +accm_set_irq(uint8_t int1, uint8_t int2) +{ + if(!enabled) { + return ADXL345_ERROR; + } + + /* Set the corresponding interrupt mapping to INT1 or INT2 */ + PRINTF("ADXL345: IRQs set to INT1: 0x%02X IRQ2: 0x%02X\n", int1, int2); + + int1_mask = int1; + int2_mask = int2; + + accm_write_reg(ADXL345_INT_ENABLE, (int1 | int2)); + /* int1 bits are zeroes in the map register so this is for both ints */ + accm_write_reg(ADXL345_INT_MAP, int2); + return ADXL345_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +/* Invoked after an interrupt happened. Reads the interrupt source reg at the + * accelerometer, which resets the interrupts, and invokes the corresponding + * callback. It passes the source register value so the callback can determine + * what interrupt happened, if several interrupts are mapped to the same pin. + */ +static void +poll_handler(void) +{ + uint8_t ireg = 0; + ireg = accm_read_reg(ADXL345_INT_SOURCE); + + /* Invoke callbacks for the corresponding interrupts */ + if(ireg & int1_mask){ + if(accm_int1_cb != NULL){ + PRINTF("ADXL345: INT1 cb invoked\n"); + accm_int1_cb(ireg); + } + } else if(ireg & int2_mask){ + if(accm_int2_cb != NULL){ + PRINTF("ADXL345: INT2 cb invoked\n"); + accm_int2_cb(ireg); + } + } +} +/*---------------------------------------------------------------------------*/ +/* This process is sleeping until an interrupt from the accelerometer occurs, + * which polls this process from the interrupt service routine. */ +PROCESS_THREAD(accmeter_process, ev, data) +{ + PROCESS_POLLHANDLER(poll_handler()); + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + while(1){ + PROCESS_WAIT_EVENT_UNTIL(0); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/* This interrupt vector is shared with the interrupts from CC2420, so that + * was moved here + */ +static struct timer suppressTimer1, suppressTimer2; + +ISR(PORT1, port1_isr) +{ + /* ADXL345_IFG.x goes high when interrupt occurs, use to check what + * interrupted + */ + if((ADXL345_IFG & ADXL345_INT1_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ + /* Check if this should be suppressed or not */ + if(timer_expired(&suppressTimer1)) { + timer_set(&suppressTimer1, SUPPRESS_TIME_INT1); + ADXL345_IFG &= ~ADXL345_INT1_PIN; // clear interrupt flag + process_poll(&accmeter_process); + LPM4_EXIT; + } + } else if((ADXL345_IFG & ADXL345_INT2_PIN) && + !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ + /* Check if this should be suppressed or not */ + if(timer_expired(&suppressTimer2)) { + timer_set(&suppressTimer2, SUPPRESS_TIME_INT2); + /* clear interrupt flag */ + ADXL345_IFG &= ~ADXL345_INT2_PIN; + process_poll(&accmeter_process); + LPM4_EXIT; + } + } else { + /* CC2420 interrupt */ + if(cc2420_interrupt()) { + LPM4_EXIT; + } + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return ADXL345_ERROR; + } + + if(value) { + accm_init(); + } else { + accm_stop(); + } + enabled = value; + return ADXL345_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return ADXL345_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(!enabled) { + return ADXL345_ERROR; + } + + if((type != X_AXIS) && (type != Y_AXIS) && (type != Z_AXIS)) { + return ADXL345_ERROR; + } + + switch(type) { + case X_AXIS: + return accm_read_axis(X_AXIS); + case Y_AXIS: + return accm_read_axis(Y_AXIS); + case Z_AXIS: + return accm_read_axis(Z_AXIS); + default: + return ADXL345_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adxl345, ADXL345_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/dev/adxl345.h b/arch/platform/z1/dev/adxl345.h new file mode 100644 index 000000000..a8d4789d8 --- /dev/null +++ b/arch/platform/z1/dev/adxl345.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * Device drivers header file for adxl345 accelerometer in Zolertia Z1. + * \author + * Marcus Lundén, SICS + * Enric Calvo, Zolertia + * Antonio Lignan, Zolertia + */ +/*---------------------------------------------------------------------------*/ +#ifndef ADXL345_H_ +#define ADXL345_H_ +#include +#include "dev/i2cmaster.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +/* Used in accm_read_axis(), eg accm_read_axis(X_AXIS) */ +enum ADXL345_AXIS { + X_AXIS = 0, + Y_AXIS = 2, + Z_AXIS = 4, +}; +/* -------------------------------------------------------------------------- */ +/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), + * I2C, default threshold values etc. + */ +void accm_init(void); + +/* Read an axis of the accelerometer (x, y or z). Return value is a signed 10 + * bit int. + * The resolution of the acceleration measurement can be increased up to 13 bit, + * but will change the data format of this read out. Refer to the data sheet if + * so is wanted/needed. + */ +int16_t accm_read_axis(enum ADXL345_AXIS axis); + +/* Sets the g-range, ie the range the accelerometer measures (ie 2g means -2 to + * +2 g on every axis). Possible values: + * - ADXL345_RANGE_2G + * - ADXL345_RANGE_4G + * - ADXL345_RANGE_8G + * - ADXL345_RANGE_16G + */ +int accm_set_grange(uint8_t grange); + +/* Map interrupt (FF, tap, dbltap etc) to interrupt pin (IRQ_INT1, IRQ_INT2). + * This must come after accm_init() as the registers will otherwise be + * overwritten. + */ +int accm_set_irq(uint8_t int1, uint8_t int2); + +/* Macros for setting the pointers to callback functions from the interrupts. + * The function will be called with an uint8_t as parameter, containing the + * interrupt flag register from the ADXL345. That way, several interrupts can be + * mapped to the same pin and be read + */ +#define ACCM_REGISTER_INT1_CB(ptr) accm_int1_cb = ptr; +#define ACCM_REGISTER_INT2_CB(ptr) accm_int2_cb = ptr; +/* -------------------------------------------------------------------------- */ +/* Application definitions, change if required by application. */ + +/* Time after an interrupt that subsequent interrupts are suppressed. Should + * later be turned into one specific time per type of interrupt (tap, freefall. + * etc) + */ +#define SUPPRESS_TIME_INT1 CLOCK_SECOND/4 +#define SUPPRESS_TIME_INT2 CLOCK_SECOND/4 + +/* Suggested defaults according to the data sheet etc */ +#define ADXL345_THRESH_TAP_DEFAULT 0x48 /* 4.5g (0x30 == 3.0g) */ +#define ADXL345_OFSX_DEFAULT 0x00 /* for calibration only */ +#define ADXL345_OFSY_DEFAULT 0x00 +#define ADXL345_OFSZ_DEFAULT 0x00 +#define ADXL345_DUR_DEFAULT 0x20 /* 20 ms (datasheet: 10ms++) */ +#define ADXL345_LATENT_DEFAULT 0x50 /* 100 ms (datasheet: 20ms++) */ +#define ADXL345_WINDOW_DEFAULT 0xFF /* 320 ms (datasheet: 80ms++) */ +#define ADXL345_THRESH_ACT_DEFAULT 0x15 /* 1.3g (62.5 mg/LSB) */ +#define ADXL345_THRESH_INACT_DEFAULT 0x08 /* 0.5g (62.5 mg/LSB) */ +#define ADXL345_TIME_INACT_DEFAULT 0x02 /* 2 s (1 s/LSB) */ +#define ADXL345_ACT_INACT_CTL_DEFAULT 0xFF /* all axis, ac-coupled */ +#define ADXL345_THRESH_FF_DEFAULT 0x09 /* 563 mg */ +#define ADXL345_TIME_FF_DEFAULT 0x20 /* 60 ms */ +#define ADXL345_TAP_AXES_DEFAULT 0x07 /* all axis, no suppression */ + +#define ADXL345_BW_RATE_DEFAULT (0x00 | ADXL345_SRATE_100) /* 100 Hz */ +/* link bit set, no autosleep, start normal measuring */ +#define ADXL345_POWER_CTL_DEFAULT 0x28 +#define ADXL345_INT_ENABLE_DEFAULT 0x00 /* no interrupts enabled */ +#define ADXL345_INT_MAP_DEFAULT 0x00 /* all mapped to int_1 */ + +/* XXX NB: In the data format register, data format of axis readings is chosen + * between left or right justify. This affects the position of the MSB/LSB and is + * different depending on g-range and resolution. If changed, make sure this is + * reflected in the _read_axis() function. Also, the resolution can be increased + * from 10 bit to at most 13 bit, but this also changes position of MSB etc on data + * format so check this in read_axis() too. + */ +/* right-justify, 2g, 10-bit mode, int is active high */ +#define ADXL345_DATA_FORMAT_DEFAULT (0x00 | ADXL345_RANGE_2G) +#define ADXL345_FIFO_CTL_DEFAULT 0x00 /* FIFO bypass mode */ + +/* -------------------------------------------------------------------------- */ +/* Reference definitions, should not be changed */ +/* adxl345 slave address */ +#define ADXL345_ADDR 0x53 + +/* ADXL345 registers */ +#define ADXL345_DEVID 0x00 +/* registers 0x01 to 0x1C are reserved, do not access */ +#define ADXL345_THRESH_TAP 0x1D +#define ADXL345_OFSX 0x1E +#define ADXL345_OFSY 0x1F +#define ADXL345_OFSZ 0x20 +#define ADXL345_DUR 0x21 +#define ADXL345_LATENT 0x22 +#define ADXL345_WINDOW 0x23 +#define ADXL345_THRESH_ACT 0x24 +#define ADXL345_THRESH_INACT 0x25 +#define ADXL345_TIME_INACT 0x26 +#define ADXL345_ACT_INACT_CTL 0x27 +#define ADXL345_THRESH_FF 0x28 +#define ADXL345_TIME_FF 0x29 +#define ADXL345_TAP_AXES 0x2A +#define ADXL345_ACT_TAP_STATUS 0x2B +#define ADXL345_BW_RATE 0x2C +#define ADXL345_POWER_CTL 0x2D +#define ADXL345_INT_ENABLE 0x2E +#define ADXL345_INT_MAP 0x2F +#define ADXL345_INT_SOURCE 0x30 +#define ADXL345_DATA_FORMAT 0x31 +#define ADXL345_DATAX0 0x32 /* read only, LSByte X, two's complement */ +#define ADXL345_DATAX1 0x33 /* read only, MSByte X */ +#define ADXL345_DATAY0 0x34 /* read only, LSByte Y */ +#define ADXL345_DATAY1 0x35 /* read only, MSByte X */ +#define ADXL345_DATAZ0 0x36 /* read only, LSByte Z */ +#define ADXL345_DATAZ1 0x37 /* read only, MSByte X */ +#define ADXL345_FIFO_CTL 0x38 +#define ADXL345_FIFO_STATUS 0x39 /* read only */ + +/* ADXL345 interrupts */ +#define ADXL345_INT_DISABLE 0X00 /* used for disabling interrupts */ +#define ADXL345_INT_OVERRUN 0X01 +#define ADXL345_INT_WATERMARK 0X02 +#define ADXL345_INT_FREEFALL 0X04 +#define ADXL345_INT_INACTIVITY 0X08 +#define ADXL345_INT_ACTIVITY 0X10 +#define ADXL345_INT_DOUBLETAP 0X20 +#define ADXL345_INT_TAP 0X40 +#define ADXL345_INT_DATAREADY 0X80 + +/* Accelerometer hardware ports, pins and registers on the msp430 µC */ +#define ADXL345_DIR P1DIR +#define ADXL345_PIN P1PIN +#define ADXL345_REN P1REN +#define ADXL345_SEL P1SEL +#define ADXL345_SEL2 P1SEL2 +#define ADXL345_INT1_PIN (1<<6) /* P1.6 */ +#define ADXL345_INT2_PIN (1<<7) /* P1.7 */ +#define ADXL345_IES P1IES +#define ADXL345_IE P1IE +#define ADXL345_IFG P1IFG +#define ADXL345_VECTOR PORT1_VECTOR + +/* g-range for DATA_FORMAT register */ +#define ADXL345_RANGE_2G 0x00 +#define ADXL345_RANGE_4G 0x01 +#define ADXL345_RANGE_8G 0x02 +#define ADXL345_RANGE_16G 0x03 + + +/* The adxl345 has programmable sample rates, but unexpected results may occur + * if the wrong rate and I2C bus speed is used (see datasheet p 17). Sample + * rates in Hz. This setting does not change the internal sampling rate, just + * how often it is piped to the output registers (ie the interrupt features use + * the full sample rate internally). + * Example use: + * adxl345_set_reg(ADXL345_BW_RATE, ((_ADXL345_STATUS & LOW_POWER) + * | ADXL345_SRATE_50)); + */ + +/* XXX NB don't use at all as I2C data rate<= 400kHz */ +#define ADXL345_SRATE_3200 0x0F +/* XXX NB don't use at all as I2C data rate<= 400kHz */ +#define ADXL345_SRATE_1600 0x0E +#define ADXL345_SRATE_800 0x0D /* when I2C data rate == 400 kHz */ +#define ADXL345_SRATE_400 0x0C /* when I2C data rate == 400 kHz */ +#define ADXL345_SRATE_200 0x0B /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_100 0x0A /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_50 0x09 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_25 0x08 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_12_5 0x07 /* 12.5 Hz, when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_6_25 0x06 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_3_13 0x05 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_1_56 0x04 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_78 0x03 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_39 0x02 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_20 0x01 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_10 0x00 /* 0.10 Hz, when I2C data rate >= 100 kHz */ +/* -------------------------------------------------------------------------- */ +/* Callback pointers for the interrupts */ +extern void (*accm_int1_cb)(uint8_t reg); +extern void (*accm_int2_cb)(uint8_t reg); +/* -------------------------------------------------------------------------- */ +#define ACCM_INT1 0x01 +#define ACCM_INT2 0x02 +#define ADXL345_SUCCESS 0x00 +#define ADXL345_ERROR (-1) +/* -------------------------------------------------------------------------- */ +#define ADXL345_SENSOR "ADXL345 sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor adxl345; +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +#endif /* ifndef ADXL345_H_ */ diff --git a/arch/platform/z1/dev/battery-sensor.c b/arch/platform/z1/dev/battery-sensor.c new file mode 100644 index 000000000..dd787ccae --- /dev/null +++ b/arch/platform/z1/dev/battery-sensor.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2010/08/25 19:30:52 $ + * $Revision: 1.11 $ + */ +#include "contiki.h" +#include "dev/battery-sensor.h" +#include "dev/sky-sensors.h" + +/* Configure ADC12_2 to sample channel 11 (voltage) and use */ +/* the Vref+ as reference (SREF_1) since it is a stable reference */ +#define INPUT_CHANNEL (1 << INCH_11) +#define INPUT_REFERENCE SREF_1 +#define BATTERY_MEM ADC12MEM11 + +const struct sensors_sensor battery_sensor; +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return BATTERY_MEM; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + return sky_sensors_configure(INPUT_CHANNEL, INPUT_REFERENCE, type, c); +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return sky_sensors_status(INPUT_CHANNEL, type); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(battery_sensor, BATTERY_SENSOR, value, configure, status); diff --git a/arch/platform/z1/dev/button-sensor.c b/arch/platform/z1/dev/button-sensor.c new file mode 100644 index 000000000..58479bf3b --- /dev/null +++ b/arch/platform/z1/dev/button-sensor.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/hwconf.h" +#include "dev/button-sensor.h" +#include "isr_compat.h" + +const struct sensors_sensor button_sensor; + +static struct timer debouncetimer; +static int status(int type); + +HWCONF_PIN(BUTTON, 2, 5); +HWCONF_IRQ(BUTTON, 2, 5); + +/*---------------------------------------------------------------------------*/ +ISR(PORT2, irq_p2) +{ + if(BUTTON_CHECK_IRQ()) { + if(timer_expired(&debouncetimer)) { + timer_set(&debouncetimer, CLOCK_SECOND / 4); + sensors_changed(&button_sensor); + LPM4_EXIT; + } + } + P2IFG = 0x00; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return BUTTON_READ() || !timer_expired(&debouncetimer); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch (type) { + case SENSORS_ACTIVE: + if (c) { + if(!status(SENSORS_ACTIVE)) { + timer_set(&debouncetimer, 0); + BUTTON_IRQ_EDGE_SELECTD(); + + BUTTON_SELECT(); + BUTTON_MAKE_INPUT(); + + BUTTON_ENABLE_IRQ(); + } + } else { + BUTTON_DISABLE_IRQ(); + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch (type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return BUTTON_IRQ_ENABLED(); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, + value, configure, status); diff --git a/arch/platform/z1/dev/cc2420-arch.c b/arch/platform/z1/dev/cc2420-arch.c new file mode 100644 index 000000000..394c5c569 --- /dev/null +++ b/arch/platform/z1/dev/cc2420-arch.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 "contiki.h" +#include "contiki-net.h" +#include "dev/spi-legacy.h" +#include "cc2420.h" +#include "isr_compat.h" + +#ifdef CC2420_CONF_SFD_TIMESTAMPS +#define CONF_SFD_TIMESTAMPS CC2420_CONF_SFD_TIMESTAMPS +#endif /* CC2420_CONF_SFD_TIMESTAMPS */ + +#ifndef CONF_SFD_TIMESTAMPS +#define CONF_SFD_TIMESTAMPS 0 +#endif /* CONF_SFD_TIMESTAMPS */ + +#ifdef CONF_SFD_TIMESTAMPS +#include "cc2420-arch-sfd.h" +#endif /* CONF_SFD_TIMESTAMPS */ + +/*---------------------------------------------------------------------------*/ +#if 0 +/* this is now handled in the ADXL345 accelerometer code as it uses irq on port1 too. */ +ISR(CC2420_IRQ, cc24240_port1_interrupt) +{ + if(cc2420_interrupt()) { + LPM4_EXIT; + } +} +#endif +/*---------------------------------------------------------------------------*/ +void +cc2420_arch_init(void) +{ + spi_init(); + + /* all input by default, set these as output */ + CC2420_CSN_PORT(DIR) |= BV(CC2420_CSN_PIN); + CC2420_VREG_PORT(DIR) |= BV(CC2420_VREG_PIN); + CC2420_RESET_PORT(DIR) |= BV(CC2420_RESET_PIN); + +#if CONF_SFD_TIMESTAMPS + cc2420_arch_sfd_init(); +#endif /* CONF_SFD_TIMESTAMPS */ + + CC2420_SPI_DISABLE(); /* Unselect radio. */ +} +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/dev/i2cmaster.c b/arch/platform/z1/dev/i2cmaster.c new file mode 100644 index 000000000..59437b904 --- /dev/null +++ b/arch/platform/z1/dev/i2cmaster.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * I2C communication device drivers for Zolertia Z1 sensor node. + * \author + * Enric M. Calvo, Zolertia + * Marcus Lundén, SICS + */ + +#include "i2cmaster.h" +#include "isr_compat.h" + +signed char tx_byte_ctr, rx_byte_ctr; +unsigned char rx_buf[2]; +unsigned char *tx_buf_ptr; +unsigned char *rx_buf_ptr; +unsigned char receive_data; +unsigned char transmit_data1; +unsigned char transmit_data2; +unsigned char prescale_lsb = I2C_PRESC_Z1_LSB; +unsigned char prescale_msb = I2C_PRESC_Z1_MSB; +volatile unsigned int i; /* volatile to prevent optimization */ + +/* ------------------------------------------------------------------------------ + * Change the data rate prior initializing transmission or reception + * ----------------------------------------------------------------------------- */ +void +i2c_setrate(uint8_t p_lsb, uint8_t p_msb) +{ + prescale_lsb = p_lsb; + prescale_lsb = p_msb; +} +/* ------------------------------------------------------------------------------ + * This function initializes the USCI module for master-receive operation. + * ----------------------------------------------------------------------------- */ +void +i2c_receiveinit(uint8_t slave_address) +{ + UCB1CTL1 = UCSWRST; /* Enable SW reset */ + UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; /* I2C Master, synchronous mode */ + UCB1CTL1 = UCSSEL_2 | UCSWRST; /* Use SMCLK, keep SW reset */ + UCB1BR0 = prescale_lsb; /* prescaler (default 400 kHz) */ + UCB1BR1 = prescale_msb; + UCB1I2CSA = slave_address; /* set slave address */ + UCB1CTL1 &= ~UCTR; /* I2C Receiver */ + UCB1CTL1 &= ~UCSWRST; /* Clear SW reset, resume operation */ + UCB1I2CIE = UCNACKIE; +#if I2C_RX_WITH_INTERRUPT + UC1IE = UCB1RXIE; /* Enable RX interrupt if desired */ +#endif +} +/* ------------------------------------------------------------------------------ + * Initializes USCI for master-transmit operation. + * ------------------------------------------------------------------------------ */ +void +i2c_transmitinit(uint8_t slave_address) +{ + UCB1CTL1 |= UCSWRST; /* Enable SW reset */ + UCB1CTL0 |= (UCMST | UCMODE_3 | UCSYNC); /* I2C Master, synchronous mode */ + UCB1CTL1 = UCSSEL_2 + UCSWRST; /* Use SMCLK, keep SW reset */ + UCB1BR0 = prescale_lsb; /* prescaler (default 400 kHz) */ + UCB1BR1 = prescale_msb; + UCB1I2CSA = slave_address; /* Set slave address */ + UCB1CTL1 &= ~UCSWRST; /* Clear SW reset, resume operation */ + UCB1I2CIE = UCNACKIE; + UC1IE = UCB1TXIE; /* Enable TX ready interrupt */ +} +/* ------------------------------------------------------------------------------ + * This function is used to start an I2C communication in master-receiver mode WITHOUT INTERRUPTS + * for more than 1 byte + * ------------------------------------------------------------------------------ */ +static volatile uint8_t rx_byte_tot = 0; +uint8_t +i2c_receive_n(uint8_t byte_ctr, uint8_t *rx_buf) +{ + + rx_byte_tot = byte_ctr; + rx_byte_ctr = byte_ctr; + rx_buf_ptr = rx_buf; + + while((UCB1CTL1 & UCTXSTT) || (UCB1STAT & UCNACKIFG)) /* Slave acks address or not? */ + PRINTFDEBUG("____ UCTXSTT not clear OR NACK received\n"); + +#if I2C_RX_WITH_INTERRUPT + PRINTFDEBUG(" RX Interrupts: YES \n"); + + /* SPECIAL-CASE: Stop condition must be sent while receiving the 1st byte for 1-byte only read operations */ + if(rx_byte_tot == 1) { /* See page 537 of slau144e.pdf */ + dint(); + UCB1CTL1 |= UCTXSTT; /* I2C start condition */ + while(UCB1CTL1 & UCTXSTT) /* Waiting for Start bit to clear */ + PRINTFDEBUG("____ STT clear wait\n"); + UCB1CTL1 |= UCTXSTP; /* I2C stop condition */ + eint(); + } else { /* all other cases */ + UCB1CTL1 |= UCTXSTT; /* I2C start condition */ + } + return 0; + +#else + uint8_t n_received = 0; + + PRINTFDEBUG(" RX Interrupts: NO \n"); + + UCB1CTL1 |= UCTXSTT; /* I2C start condition */ + + while(rx_byte_ctr > 0) { + if(UC1IFG & UCB1RXIFG) { /* Waiting for Data */ + rx_buf[rx_byte_tot - rx_byte_ctr] = UCB1RXBUF; + rx_byte_ctr--; + UC1IFG &= ~UCB1RXIFG; /* Clear USCI_B1 RX int flag */ + n_received++; + } + } + UCB1CTL1 |= UCTXSTP; /* I2C stop condition */ + return n_received; +#endif +} +/* ------------------------------------------------------------------------------ + * This function is used to check if there is communication in progress. + * ------------------------------------------------------------------------------ */ +uint8_t +i2c_busy(void) +{ + return UCB1STAT & UCBBUSY; +} +/*---------------------------------------------------------------------------- + * Setup ports and pins for I2C use. + * ------------------------------------------------------------------------------ */ + +void +i2c_enable(void) +{ + I2C_PxSEL |= (I2C_SDA | I2C_SCL); /* Secondary function (USCI) selected */ + I2C_PxSEL2 |= (I2C_SDA | I2C_SCL); /* Secondary function (USCI) selected */ + I2C_PxDIR |= I2C_SCL; /* SCL is output (not needed?) */ + I2C_PxDIR &= ~I2C_SDA; /* SDA is input (not needed?) */ + I2C_PxREN |= (I2C_SDA | I2C_SCL); /* Activate internal pull-up/-down resistors */ + I2C_PxOUT |= (I2C_SDA | I2C_SCL); /* Select pull-up resistors */ +} +void +i2c_disable(void) +{ + I2C_PxSEL &= ~(I2C_SDA | I2C_SCL); /* GPIO function selected */ + I2C_PxSEL2 &= ~(I2C_SDA | I2C_SCL); /* GPIO function selected */ + I2C_PxREN &= ~(I2C_SDA | I2C_SCL); /* Deactivate internal pull-up/-down resistors */ + I2C_PxOUT &= ~(I2C_SDA | I2C_SCL); /* Select pull-up resistors */ +} +/* ------------------------------------------------------------------------------ + * This function is used to start an I2C communication in master-transmit mode. + * ------------------------------------------------------------------------------ */ +static volatile uint8_t tx_byte_tot = 0; +void +i2c_transmit_n(uint8_t byte_ctr, uint8_t *tx_buf) +{ + tx_byte_tot = byte_ctr; + tx_byte_ctr = byte_ctr; + tx_buf_ptr = tx_buf; + UCB1CTL1 |= UCTR + UCTXSTT; /* I2C TX, start condition */ +} +/*----------------------------------------------------------------------------*/ +ISR(USCIAB1TX, i2c_tx_interrupt) +{ + /* TX Part */ + if(UC1IFG & UCB1TXIFG) { /* TX int. condition */ + if(tx_byte_ctr == 0) { + UCB1CTL1 |= UCTXSTP; /* I2C stop condition */ + UC1IFG &= ~UCB1TXIFG; /* Clear USCI_B1 TX int flag */ + } else { + UCB1TXBUF = tx_buf_ptr[tx_byte_tot - tx_byte_ctr]; + tx_byte_ctr--; + } + } + /* RX Part */ +#if I2C_RX_WITH_INTERRUPT + else if(UC1IFG & UCB1RXIFG) { /* RX int. condition */ + rx_buf_ptr[rx_byte_tot - rx_byte_ctr] = UCB1RXBUF; + rx_byte_ctr--; + if(rx_byte_ctr == 1) { /* stop condition should be set before receiving last byte */ + /* Only for 1-byte transmissions, STOP is handled in receive_n_int */ + if(rx_byte_tot != 1) { + UCB1CTL1 |= UCTXSTP; /* I2C stop condition */ + } + UC1IFG &= ~UCB1RXIFG; /* Clear USCI_B1 RX int flag. XXX Just in case, check if necessary */ + } + } +#endif +} + +ISR(USCIAB1RX, i2c_rx_interrupt) +{ + if(UCB1STAT & UCNACKIFG) { + PRINTFDEBUG("!!! NACK received in RX\n"); + UCB1CTL1 |= UCTXSTP; + UCB1STAT &= ~UCNACKIFG; + } +} diff --git a/arch/platform/z1/dev/i2cmaster.h b/arch/platform/z1/dev/i2cmaster.h new file mode 100644 index 000000000..cf9d96e6d --- /dev/null +++ b/arch/platform/z1/dev/i2cmaster.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * I2C communication device driver header file for Zolertia Z1 sensor node. + * \author + * Enric Calvo, Zolertia + * Marcus Lundén, SICS + */ + +#ifndef I2CMASTER_H_ +#define I2CMASTER_H_ + +#include "contiki.h" + +void i2c_enable(void); +void i2c_disable(void); + +void i2c_receiveinit(uint8_t slave_address); +uint8_t i2c_receive_n(uint8_t byte_ctr, uint8_t *rx_buf); + +void i2c_transmitinit(uint8_t slave_address); +void i2c_transmit_n(uint8_t byte_ctr, uint8_t *tx_buf); + +uint8_t i2c_busy(void); +void i2c_setrate(uint8_t p_lsb, uint8_t p_msb); + +#if 0 +#include +#define PRINTFDEBUG(...) printf(__VA_ARGS__) +#else +#define PRINTFDEBUG(...) +#endif + +#endif /* #ifdef I2CMASTER_H_ */ diff --git a/arch/platform/z1/dev/light-sensor.c b/arch/platform/z1/dev/light-sensor.c new file mode 100644 index 000000000..ebc52d4db --- /dev/null +++ b/arch/platform/z1/dev/light-sensor.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2005-2010, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/sky-sensors.h" +#include "dev/light-sensor.h" +#include "dev/potentiometer-sensor.h" + +/* Photodiode 1 (P64) on INCH_4 */ +/* Photodiode 2 (P65) on INCH_5 */ +/* Enric#define INPUT_CHANNEL ((1 << INCH_4) | (1 << INCH_5)) */ +#ifndef INPUT_CHANNEL +#define INPUT_CHANNEL (1 << INCH_4) +#endif + +#ifndef INPUT_REFERENCE +#define INPUT_REFERENCE SREF_0 +#endif + +#ifdef POTENTIOMETER_MEM +#define PHOTOSYNTHETIC_MEM POTENTIOMETER_MEM +#define TOTAL_SOLAR_MEM POTENTIOMETER_MEM +#else +#define PHOTOSYNTHETIC_MEM ADC12MEM4 +#define TOTAL_SOLAR_MEM ADC12MEM4 +#endif + + +const struct sensors_sensor light_sensor; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + switch(type) { + /* Photosynthetically Active Radiation. */ + case LIGHT_SENSOR_PHOTOSYNTHETIC: + return PHOTOSYNTHETIC_MEM; + + /* Total Solar Radiation. */ + case LIGHT_SENSOR_TOTAL_SOLAR: + return TOTAL_SOLAR_MEM; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return sky_sensors_status(INPUT_CHANNEL, type); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + return sky_sensors_configure(INPUT_CHANNEL, INPUT_REFERENCE, type, c); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(light_sensor, "Light", value, configure, status); diff --git a/arch/platform/z1/dev/light-sensor.h b/arch/platform/z1/dev/light-sensor.h new file mode 100644 index 000000000..411c6fa33 --- /dev/null +++ b/arch/platform/z1/dev/light-sensor.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2010-01-08 + * Updated : $Date: 2010/01/14 20:23:02 $ + * $Revision: 1.2 $ + */ + +#ifndef LIGHT_SENSOR_H_ +#define LIGHT_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor light_sensor; + +#define LIGHT_SENSOR_PHOTOSYNTHETIC 0 +#define LIGHT_SENSOR_TOTAL_SOLAR 1 + + +#endif /* LIGHT-SENSOR_H_ */ diff --git a/arch/platform/z1/dev/light-ziglet.c b/arch/platform/z1/dev/light-ziglet.c new file mode 100644 index 000000000..3f322e30a --- /dev/null +++ b/arch/platform/z1/dev/light-ziglet.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Device drivers for light ziglet sensor in Zolertia Z1. + * It is recommended to use with a 100KHz data rate + * \author + * Antonio Lignan, Zolertia + * Marcus Lundén, SICS + */ + +#include +#include "contiki.h" +#include "i2cmaster.h" +#include "light-ziglet.h" + +#if 0 +#define PRINTFDEBUG(...) printf(__VA_ARGS__) +#else +#define PRINTFDEBUG(...) +#endif + +/* Bitmasks and bit flag variable for keeping track of tmp102 status. */ +enum TSL2563_STATUSTYPES { + /* must be a bit and not more, not using 0x00. */ + INITED = 0x01, + RUNNING = 0x02, + STOPPED = 0x04, +}; + +static enum TSL2563_STATUSTYPES _TSL2563_STATUS = 0x00; + +uint16_t +calculateLux(uint16_t *buffer) +{ + uint32_t ch0, ch1 = 0; + uint32_t aux = (1 << 14); + uint32_t ratio, lratio, tmp = 0; + + ch0 = (buffer[0] * aux) >> 10; + ch1 = (buffer[1] * aux) >> 10; + + PRINTFDEBUG("B0 %u, B1 %u\n", buffer[0], buffer[1]); + PRINTFDEBUG("ch0 %lu, ch1 %lu\n", ch0, ch1); + + ratio = (ch1 << 10); + ratio = ratio / ch0; + lratio = (ratio + 1) >> 1; + + PRINTFDEBUG("ratio %lu, lratio %lu\n", ratio, lratio); + + if((lratio >= 0) && (lratio <= K1T)) { + tmp = (ch0 * B1T) - (ch1 * M1T); + } else if(lratio <= K2T) { + tmp = (ch0 * B2T) - (ch1 * M2T); + } else if(lratio <= K3T) { + tmp = (ch0 * B3T) - (ch1 * M3T); + } else if(lratio <= K4T) { + tmp = (ch0 * B4T) - (ch1 * M4T); + } else if(lratio <= K5T) { + tmp = (ch0 * B5T) - (ch1 * M5T); + } else if(lratio <= K6T) { + tmp = (ch0 * B6T) - (ch1 * M6T); + } else if(lratio <= K7T) { + tmp = (ch0 * B7T) - (ch1 * M7T); + } else if(lratio > K8T) { + tmp = (ch0 * B8T) - (ch1 * M8T); + } + + if(tmp < 0) { + tmp = 0; + } + + tmp += (1 << 13); + + PRINTFDEBUG("tmp %lu\n", tmp); + + return tmp >> 14; +} +/*---------------------------------------------------------------------------*/ +/* Init the light ziglet sensor: ports, pins, registers, interrupts (none enabled), I2C, + default threshold values etc. */ + +void +light_ziglet_init(void) +{ + if(!(_TSL2563_STATUS & INITED)) { + PRINTFDEBUG("light ziglet init\n"); + _TSL2563_STATUS |= INITED; + + /* Set up ports and pins for I2C communication */ + i2c_enable(); + return; + } +} +/*---------------------------------------------------------------------------*/ +/* Write to a 16-bit register. + args: + reg register to write to + val value to write + */ + +void +tsl2563_write_reg(uint8_t reg, uint16_t val) +{ + uint8_t tx_buf[] = { reg, 0x00, 0x00 }; + + tx_buf[1] = (uint8_t)(val >> 8); + tx_buf[2] = (uint8_t)(val & 0x00FF); + + i2c_transmitinit(TSL2563_ADDR); + while(i2c_busy()); + PRINTFDEBUG("I2C Ready to TX\n"); + + i2c_transmit_n(3, tx_buf); + while(i2c_busy()); + PRINTFDEBUG("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); +} +/*---------------------------------------------------------------------------*/ +/* Read register. + args: + reg what register to read + returns the value of the read register type uint16_t + */ + +uint16_t +tsl2563_read_reg(uint8_t reg) +{ + uint16_t readBuf[] = { 0x00, 0x00 }; + uint8_t buf[] = { 0x00, 0x00, 0x00, 0x00 }; + uint16_t retVal = 0; + uint8_t rtx = reg; + + /* Transmit the register to read */ + i2c_transmitinit(TSL2563_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, &rtx); + while(i2c_busy()); + + /* Receive the data */ + i2c_receiveinit(TSL2563_ADDR); + while(i2c_busy()); + i2c_receive_n(4, buf); + while(i2c_busy()); + + PRINTFDEBUG("\nb0 %u, b1 %u, b2 %u, b3 %u\n", buf[0], buf[1], buf[2], buf[3]); + + readBuf[0] = (buf[1] << 8 | (buf[0])); + readBuf[1] = (buf[3] << 8 | (buf[2])); + + retVal = calculateLux(readBuf); + return retVal; +} +uint16_t +light_ziglet_on(void) +{ + uint16_t data; + uint8_t regon = TSL2563_PWRN; + /* Turn on the sensor */ + i2c_transmitinit(TSL2563_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, ®on); + while(i2c_busy()); + data = (uint16_t)tsl2563_read_reg(TSL2563_READ); + return data; +} +void +light_ziglet_off(void) +{ + uint8_t regoff = 0x00; + /* Turn off the sensor */ + i2c_transmitinit(TSL2563_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, ®off); + while(i2c_busy()); + return; +} +/*---------------------------------------------------------------------------*/ +/* Read light ziglet sensor + */ + +uint16_t +light_ziglet_read(void) +{ + uint16_t lux = 0; + lux = light_ziglet_on(); + light_ziglet_off(); + return lux; +} diff --git a/arch/platform/z1/dev/light-ziglet.h b/arch/platform/z1/dev/light-ziglet.h new file mode 100644 index 000000000..4db18e24e --- /dev/null +++ b/arch/platform/z1/dev/light-ziglet.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Device drivers header file for light ziglet sensor in Zolertia Z1 WSN Platform. + * \author + * Antonio Lignan, Zolertia + * Marcus Lundén, SICS + */ + +#ifndef LIGHT_ZIGLET_H_ +#define LIGHT_ZIGLET_H_ +#include +#include "i2cmaster.h" + +/* Init the light ziglet sensor: ports, pins, I2C, interrupts */ +void light_ziglet_init(void); + +/* Write to a register. + args: + reg register to write to + val value to write + */ +void tsl2563_write_reg(uint8_t reg, uint16_t val); + +/* Read one register. + args: + reg what register to read + returns the value of the read register + */ +uint16_t tsl2563_read_reg(uint8_t reg); + +/* Takes a single light reading + args: none + returns a lux value + */ +uint16_t light_ziglet_read(); + +/* Calculates the lux values from the calibration table + args: raw values from sensor + returns a lux value + */ +uint16_t calculateLux(uint16_t *readRaw); + +/* Turns the light ziglet ON and polls the sensor for a light reading */ +uint16_t light_ziglet_on(void); + +/* -------------------------------------------------------------------------- */ +/* Reference definitions */ + +/* TSL2563 slave address */ +#define TSL2563_ADDR 0x39 + +/* Registers */ +#define TSL2563_READ 0xAC +#define TSL2563_PWRN 0x03 + +/* Calibration settings */ +#define K1T 0X0040 +#define B1T 0x01f2 +#define M1T 0x01b2 + +#define K2T 0x0080 +#define B2T 0x0214 +#define M2T 0x02d1 + +#define K3T 0x00c0 +#define B3T 0x023f +#define M3T 0x037b + +#define K4T 0x0100 +#define B4T 0x0270 +#define M4T 0x03fe + +#define K5T 0x0138 +#define B5T 0x016f +#define M5T 0x01fc + +#define K6T 0x019a +#define B6T 0x00d2 +#define M6T 0x00fb + +#define K7T 0x029a +#define B7T 0x0018 +#define M7T 0x0012 + +#define K8T 0x029a +#define B8T 0x0000 +#define M8T 0x0000 + +/* -------------------------------------------------------------------------- */ +#endif /* ifndef LIGHT_ZIGLET_H_ */ + diff --git a/arch/platform/z1/dev/potentiometer-sensor.c b/arch/platform/z1/dev/potentiometer-sensor.c new file mode 100644 index 000000000..12597bd0e --- /dev/null +++ b/arch/platform/z1/dev/potentiometer-sensor.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 Zolertia(TM) is a trademark by Advancare,SL + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + * ----------------------------------------------------------------- + * + * Author : Enric M. Calvo (based on work by A. Dunkels, J. Eriksson, N. Finne) + * Created : 2011-02-22 + * $Revision: 1.0 $ + */ + +#include "dev/potentiometer-sensor.h" +#include "dev/sky-sensors.h" +#include "contiki.h" + +/* Configure ADC12_2 to sample channel 11 (voltage) and use */ +/* the Vref+ as reference (SREF_1) since it is a stable reference */ +#define INPUT_CHANNEL (1 << INCH_4) +#define INPUT_REFERENCE SREF_0 +#define POTENTIOMETER_MEM ADC12MEM4 + +const struct sensors_sensor potentiometer_sensor; +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return POTENTIOMETER_MEM; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + return sky_sensors_configure(INPUT_CHANNEL, INPUT_REFERENCE, type, c); +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return sky_sensors_status(INPUT_CHANNEL, type); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(potentiometer_sensor, POTENTIOMETER_SENSOR, value, configure, status); diff --git a/arch/platform/z1/dev/potentiometer-sensor.h b/arch/platform/z1/dev/potentiometer-sensor.h new file mode 100644 index 000000000..d9d8b983d --- /dev/null +++ b/arch/platform/z1/dev/potentiometer-sensor.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Zolertia(TM) is a trademark by Advancare,SL + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + * ----------------------------------------------------------------- + * + * Author : Enric M. Calvo (based on work by A. Dunkels, J. Eriksson, N. Finne) + * Created : 2011-02-22 + * $Revision: 1.0 $ + */ + +#ifndef POTENTIOMETER_SENSOR_H_ +#define POTENTIOMETER_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor potentiometer_sensor; + +#define POTENTIOMETER_SENSOR "Potentiometer" + +#endif /* POTENTIOMETER_SENSOR_H_ */ diff --git a/arch/platform/z1/dev/reed-sensor.c b/arch/platform/z1/dev/reed-sensor.c new file mode 100644 index 000000000..7e7a0df6d --- /dev/null +++ b/arch/platform/z1/dev/reed-sensor.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * Reed sensor driver file + * \author + * Antonio Lignan + */ + +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/reed-sensor.h" +#include "sys/process.h" +#include "sys/ctimer.h" +/*---------------------------------------------------------------------------*/ +#ifndef REED_CHECK_PERIOD +#define REED_CHECK_PERIOD CLOCK_SECOND +#endif +/*---------------------------------------------------------------------------*/ +static int current_status = -1; +static struct ctimer change_timer; +process_event_t reed_sensor_event_changed; +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return ~(REED_PORT_DIR & REED_READ_PIN); + } + return REED_SENSOR_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if((!status(SENSORS_ACTIVE)) || (type != REED_SENSOR_VAL)) { + return REED_SENSOR_ERROR; + } + return (REED_PORT_READ & REED_READ_PIN) ? REED_CLOSED : REED_OPEN; +} +/*---------------------------------------------------------------------------*/ +static void +check_callback(void *data) +{ + static int new_status; + if(current_status == -1) { + ctimer_stop(&change_timer); + return; + } + + new_status = value(REED_SENSOR_VAL); + if(new_status != current_status) { + current_status = new_status; + process_post(PROCESS_BROADCAST, reed_sensor_event_changed, ¤t_status); + } + ctimer_reset(&change_timer); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + REED_PORT_SEL |= REED_READ_PIN; + REED_PORT_DIR &= ~REED_READ_PIN; + REED_PORT_REN |= REED_READ_PIN; + REED_PORT_PRES |= REED_READ_PIN; + } + } else { + REED_PORT_DIR |= REED_READ_PIN; + REED_PORT_REN &= ~REED_READ_PIN; + } + return REED_SENSOR_SUCCESS; + case REED_SENSOR_MODE: + if(c == REED_SENSOR_EVENT_MODE) { + current_status = value(REED_SENSOR_VAL); + ctimer_set(&change_timer, REED_CHECK_PERIOD, check_callback, NULL); + } else if(c == REED_SENSOR_EVENT_POLL) { + current_status = -1; + ctimer_stop(&change_timer); + } else { + return REED_SENSOR_ERROR; + } + return REED_SENSOR_SUCCESS; + } + return REED_SENSOR_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(reed_sensor, REED_SENSOR, value, configure, status); diff --git a/arch/platform/z1/dev/reed-sensor.h b/arch/platform/z1/dev/reed-sensor.h new file mode 100644 index 000000000..7e86716f5 --- /dev/null +++ b/arch/platform/z1/dev/reed-sensor.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * Header file for the reed sensor + * + * The Reed sensor allows to be used either by polling the sensor status or by + * setting up a timer on the background ticking every REED_CHECK_PERIOD, posting + * a reed_sensor_event_changed event, informing the application about a change + * in the sensor status (basically open or closed). To enable each mode + * (default is polling) call the configure() function with REED_SENSOR_MODE + * using REED_SENSOR_EVENT_MODE or REED_SENSOR_POLL_MODE, after having + * initialized the device using SENSORS_ACTIVATE(reed_sensor). + * + * \file + * Reed sensor header file + * \author + * Antonio Lignan + */ +#include "lib/sensors.h" + +#ifndef REED_SENSOR_H_ +#define REED_SENSOR_H_ +/* -------------------------------------------------------------------------- */ +#define REED_SENSOR_ERROR -1 +#define REED_SENSOR_SUCCESS 0x00 +#define REED_SENSOR_VAL 0x01 +/* -------------------------------------------------------------------------- */ +#define REED_OPEN 0x00 +#define REED_CLOSED 0x01 +/* -------------------------------------------------------------------------- */ +#define REED_SENSOR_MODE 0x01 +#define REED_SENSOR_EVENT_MODE 0x0A +#define REED_SENSOR_EVENT_POLL 0x0B +/* -------------------------------------------------------------------------- */ +#define REED_PORT_DIR P4DIR +#define REED_PORT_SEL P4SEL +#define REED_PORT_REN P4REN +#define REED_PORT_READ P4IN +#define REED_PORT_PRES P4OUT +#define REED_READ_PIN (1 << 2) +/* -------------------------------------------------------------------------- */ +#define REED_SENSOR "Reed Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor reed_sensor; +extern process_event_t reed_sensor_event_changed; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef REED_SENSOR_H_ */ diff --git a/arch/platform/z1/dev/relay-phidget.c b/arch/platform/z1/dev/relay-phidget.c new file mode 100644 index 000000000..d78734b21 --- /dev/null +++ b/arch/platform/z1/dev/relay-phidget.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * ----------------------------------------------------------------- + * + * \file + * Device simple driver for generic relay in phidget port of Zolertia Z1 + * \author + * Antonio Lignan, Zolertia + * + */ + +#include "contiki.h" +#include "relay-phidget.h" + +static uint8_t controlPin; + +enum PHIDGET_RELAY_STATUSTYPES { + /* must be a bit and not more, not using 0x00. */ + INITED = 0x01, + RUNNING = 0x02, + STOPPED = 0x04, +}; + +static enum PHIDGET_RELAY_STATUSTYPES _RELAY_STATUS = 0x00; + +/*---------------------------------------------------------------------------*/ + +void +relay_enable(uint8_t pin) +{ + + if(!(_RELAY_STATUS & INITED)) { + + _RELAY_STATUS |= INITED; + + /* Selects the pin to be configure as the control pin of the relay module */ + controlPin = (1 << pin); + + /* Configures the control pin */ + P6SEL &= ~controlPin; + P6DIR |= controlPin; + } +} +/*---------------------------------------------------------------------------*/ + +void +relay_on() +{ + if((_RELAY_STATUS & INITED)) { + P6OUT |= controlPin; + } +} +/*---------------------------------------------------------------------------*/ +void +relay_off() +{ + if((_RELAY_STATUS & INITED)) { + P6OUT &= ~controlPin; + } +} +/*---------------------------------------------------------------------------*/ + +int8_t +relay_toggle() +{ + if((_RELAY_STATUS & INITED)) { + P6OUT ^= controlPin; + if((P6OUT & controlPin)) { + return 1; + } + return 0; + } + return -1; +} +/*---------------------------------------------------------------------------*/ + diff --git a/arch/platform/z1/dev/relay-phidget.h b/arch/platform/z1/dev/relay-phidget.h new file mode 100644 index 000000000..580151f58 --- /dev/null +++ b/arch/platform/z1/dev/relay-phidget.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * ----------------------------------------------------------------- + * + * \file + * Device simple driver for generic relay in phidget port of Zolertia Z1 + * \author + * Antonio Lignan, Zolertia + * + */ + +#ifndef RELAY_PHIDGET_H_ +#define RELAY_PHIDGETS_H_ + +void relay_enable(uint8_t pin); + +void relay_on(); +void relay_off(); +int8_t relay_toggle(); + +#endif /* RELAY_PHIDGET_H_ */ diff --git a/arch/platform/z1/dev/sht11-arch.h b/arch/platform/z1/dev/sht11-arch.h new file mode 100644 index 000000000..1cd1bc8e6 --- /dev/null +++ b/arch/platform/z1/dev/sht11-arch.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Architecture-specific definitions for the SHT11 sensor on Zolertia Z1 + * when connected to the Ziglet port. + * \author + * Enric M. Calvo , adapted from work by + * Nicolas Tsiftes + */ + +#ifndef SHT11_ARCH_H +#define SHT11_ARCH_H + +/* Architecture-specific definitions for the SHT11 sensor on Zolertia Z1 + * when connected to the Ziglet port. + * CAUTION: I2C needs to be disabled to use the bitbang protocol of SHT11 + */ + +#define SHT11_ARCH_SDA 1 /* P5.1 */ +#define SHT11_ARCH_SCL 2 /* P5.2 */ +/* SHT11_ARCH_PWR is not needed, but until and *-arch abstraction exists, this + * should fix it + */ +#define SHT11_ARCH_PWR 3 /* P5.3 -- unused pin */ + +#define SHT11_PxDIR P5DIR +#define SHT11_PxIN P5IN +#define SHT11_PxOUT P5OUT +#define SHT11_PxSEL P5SEL +#define SHT11_PxREN P5REN + +#endif diff --git a/arch/platform/z1/dev/sht25.c b/arch/platform/z1/dev/sht25.c new file mode 100644 index 000000000..b8356087b --- /dev/null +++ b/arch/platform/z1/dev/sht25.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * SHT25 temperature and humidity sensor driver + * \author + * Antonio Lignan + */ +#include +#include "contiki.h" +#include "i2cmaster.h" +#include "dev/sht25.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return SHT25_ERROR; + } + if(value) { + i2c_enable(); + } else { + i2c_disable(); + } + enabled = value; + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +sht25_read_reg(uint8_t reg) +{ + uint8_t buf[] = { 0x00, 0x00 }; + uint16_t retval; + uint8_t rtx = reg; + + /* transmit the register to read */ + i2c_transmitinit(SHT25_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, &rtx); + while(i2c_busy()); + /* receive the data */ + i2c_receiveinit(SHT25_ADDR); + while(i2c_busy()); + i2c_receive_n(2, &buf[0]); + while(i2c_busy()); + + retval = (uint16_t)(buf[0] << 8 | (buf[1])); + return retval; +} +/*---------------------------------------------------------------------------*/ +static int16_t +sht25_convert(uint8_t variable, uint16_t value) +{ + int16_t rd; + uint32_t buff; + buff = (uint32_t)value; + if(variable == SHT25_VAL_TEMP) { + buff *= 17572; + buff = buff >> 16; + rd = (int16_t)buff - 4685; + } else { + buff *= 12500; + buff = buff >> 16; + rd = (int16_t)buff - 600; + rd = (rd > 10000) ? 10000 : rd; + } + return rd; +} +/*---------------------------------------------------------------------------*/ +static int16_t +sht25_read(uint8_t variable) +{ + int16_t rd; + uint16_t raw; + + if((variable != SHT25_VAL_TEMP) && (variable != SHT25_VAL_HUM)) { + return SHT25_ERROR; + } + raw = sht25_read_reg(variable); + rd = sht25_convert(variable, raw); + return rd; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return sht25_read(type); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(sht25, SHT25_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/dev/sht25.h b/arch/platform/z1/dev/sht25.h new file mode 100644 index 000000000..65d9399d3 --- /dev/null +++ b/arch/platform/z1/dev/sht25.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * SHT25 temperature and humidity sensor driver + * \author + * Antonio Lignan + */ +#include "lib/sensors.h" + +#ifndef SHT25_H_ +#define SHT25_H_ + +/* -------------------------------------------------------------------------- */ +#define SHT25_ADDR 0x40 +#define SHT25_TEMP_HOLD 0xE3 +#define SHT25_HUM_HOLD 0xE5 +#define SHT25_TEMP_NO_HOLD 0xF3 +#define SHT25_HUM_NO_HOLD 0xF5 +#define SHT2X_UREG_WRITE 0xE6 +#define SHT2X_UREG_READ 0xE7 +#define SHT2X_SOFT_RESET 0XFE +#define SHT2X_NULL 0x00 +/* -------------------------------------------------------------------------- */ +#define SHT2X_RES_14T_12RH 0x00 +#define SHT2X_RES_12T_08RH 0x01 +#define SHT2X_RES_13T_10RH 0x80 +#define SHT2X_RES_11T_11RH 0x81 +#define SHT2X_HEATER_ON 0x04 +#define SHT2X_HEATER_OFF 0x00 +#define SHT2X_OTP_RELOAD_EN 0x00 +#define SHT2X_OTP_RELOAD_DIS 0x02 +/* -------------------------------------------------------------------------- */ +#define SHT25_VAL_TEMP SHT25_TEMP_HOLD +#define SHT25_VAL_HUM SHT25_HUM_HOLD +#define SHT25_ERROR -1 +/* -------------------------------------------------------------------------- */ +#define SHT25_SENSOR "SHT25 Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor sht25; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef SHT25_H_ */ diff --git a/arch/platform/z1/dev/sky-sensors.c b/arch/platform/z1/dev/sky-sensors.c new file mode 100644 index 000000000..48ac22428 --- /dev/null +++ b/arch/platform/z1/dev/sky-sensors.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * ----------------------------------------------------------------- + * + * Author : Joakim Eriksson + * Created : 2010-02-02 + * Updated : $Date: 2010/08/25 19:30:53 $ + * $Revision: 1.3 $ + */ +#include "contiki.h" +#include "lib/sensors.h" + +#define ADC12MCTL_NO(adcno) ((unsigned char *) ADC12MCTL0_)[adcno] + +static uint16_t adc_on; +static uint16_t ready; +/*---------------------------------------------------------------------------*/ +static CC_INLINE void +start(void) +{ + uint16_t c, last; + + /* Set up the ADC. */ + P6DIR = 0xff; + P6OUT = 0x00; + + /* Setup ADC12, ref., sampling time */ + /* XXX Note according to the specification a minimum of 17 ms should + be allowed after turn on of the internal reference generator. */ + ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC + REFON; + /* Use sampling timer, repeat-sequence-of-channels */ + ADC12CTL1 = SHP + CONSEQ_3; + + last = 15; + for(c = 0; c < 16; c++) { + /* Clear all end-of-sequences */ + ADC12MCTL_NO(c) &= ~EOS; + if(adc_on & (1 << c)) { + if(last == 15) { + /* Set new start of sequence to lowest active memory holder */ + ADC12CTL1 |= (c * CSTARTADD_1); + } + last = c; + } + } + + /* Set highest end-of-sequence. */ + ADC12MCTL_NO(last) |= EOS; + + ADC12CTL0 |= ADC12ON; + ADC12CTL0 |= ENC; /* enable conversion */ + ADC12CTL0 |= ADC12SC; /* sample & convert */ +} +/*---------------------------------------------------------------------------*/ +static CC_INLINE void +stop(void) +{ + /* stop converting immediately, turn off reference voltage, etc. */ + + ADC12CTL0 &= ~ENC; + /* need to remove CONSEQ_3 if not EOS is configured */ + ADC12CTL1 &= ~CONSEQ_3; + + /* wait for conversion to stop */ + while(ADC12CTL1 & ADC12BUSY); + + /* clear any pending interrupts */ + ADC12IFG = 0; +} +/*---------------------------------------------------------------------------*/ +int +sky_sensors_status(uint16_t input, int type) +{ + if(type == SENSORS_ACTIVE) { + return (adc_on & input) == input; + } + if(type == SENSORS_READY) { + ready |= ADC12IFG & adc_on & input; + return (ready & adc_on & input) == input; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +sky_sensors_configure(uint16_t input, uint8_t ref, int type, int value) +{ + uint16_t c; + + if(type == SENSORS_ACTIVE) { + stop(); + + if(value) { + adc_on |= input; + P6SEL |= input & 0xff; + + /* Set ADC config */ + for(c = 0; c < 16; c++) { + if(input & (1 << c)) { + ADC12MCTL_NO(c) = (c * INCH_1) | ref; + } + } + + } else { + adc_on &= ~input; + ready &= ~input; + P6SEL &= ~(input & 0xff); + } + + if(adc_on == 0) { + P6DIR = 0x00; + P6SEL = 0x00; + + /* Turn off ADC and internal reference generator */ + ADC12CTL0 = 0; + ADC12CTL1 = 0; + } else { + start(); + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/dev/sky-sensors.h b/arch/platform/z1/dev/sky-sensors.h new file mode 100644 index 000000000..df2aeea48 --- /dev/null +++ b/arch/platform/z1/dev/sky-sensors.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * ----------------------------------------------------------------- + * + * Author : Joakim Eriksson + * Created : 2010-02-02 + * Updated : $Date: 2010/08/25 19:30:53 $ + * $Revision: 1.2 $ + */ + +#ifndef SKY_SENSORS_H_ +#define SKY_SENSORS_H_ + +int sky_sensors_status(uint16_t input, int type); +int sky_sensors_configure(uint16_t input, uint8_t reference, + int type, int value); + +#endif /* SKY_SENSORS_H_ */ diff --git a/arch/platform/z1/dev/temperature-sensor.c b/arch/platform/z1/dev/temperature-sensor.c new file mode 100644 index 000000000..1d4328d24 --- /dev/null +++ b/arch/platform/z1/dev/temperature-sensor.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Sensor driver for reading the built-in temperature sensor in the CPU. + * \author + * Adam Dunkels + * Joakim Eriksson + * Niclas Finne + */ + +#include "dev/temperature-sensor.h" +#include "dev/sky-sensors.h" +#include "contiki.h" + +#define INPUT_CHANNEL (1 << INCH_10) +#define INPUT_REFERENCE SREF_1 +#define TEMPERATURE_MEM ADC12MEM10 + +const struct sensors_sensor temperature_sensor; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return TEMPERATURE_MEM; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + return sky_sensors_configure(INPUT_CHANNEL, INPUT_REFERENCE, type, c); +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return sky_sensors_status(INPUT_CHANNEL, type); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(temperature_sensor, TEMPERATURE_SENSOR, + value, configure, status); diff --git a/arch/platform/z1/dev/temperature-sensor.h b/arch/platform/z1/dev/temperature-sensor.h new file mode 100644 index 000000000..05eafe852 --- /dev/null +++ b/arch/platform/z1/dev/temperature-sensor.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Temperature sensor header file. + * \author + * Adam Dunkels + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef TEMPERATURE_SENSOR_H_ +#define TEMPERATURE_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor temperature_sensor; + +#define TEMPERATURE_SENSOR "Temperature" + +#endif /* TEMPERATURE_SENSOR_H_ */ diff --git a/arch/platform/z1/dev/tlc59116.c b/arch/platform/z1/dev/tlc59116.c new file mode 100644 index 000000000..2db0bf093 --- /dev/null +++ b/arch/platform/z1/dev/tlc59116.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2013, Jelmer Tiete. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Device drivers for tlc59116 i2c led driver on Zolertia Z1. + * See http://www.ti.com/product/tlc59116 for datasheet. + * \author + * Jelmer Tiete, VUB + */ + +#include +#include "contiki.h" +#include "tlc59116.h" +#include "i2cmaster.h" + +/*---------------------------------------------------------------------------*/ +/* Write to a register. + * args: + * reg register to write to + * val value to write + */ + +void +tlc59116_write_reg(uint8_t reg, uint8_t val) +{ + uint8_t tx_buf[] = { reg, val }; + + i2c_transmitinit(TLC59116_ADDR); + while(i2c_busy()); + PRINTFDEBUG("I2C Ready to TX\n"); + + i2c_transmit_n(2, tx_buf); + while(i2c_busy()); + PRINTFDEBUG("WRITE_REG 0x%02X @ reg 0x%02X\n", val, reg); +} +/*---------------------------------------------------------------------------*/ +/* Write several registers from a stream. + * args: + * len number of bytes to write + * data pointer to where the data is written from + * + * First byte in stream must be the register address to begin writing to. + * The data is then written from second byte and increasing. + */ + +void +tlc59116_write_stream(uint8_t len, uint8_t *data) +{ + i2c_transmitinit(TLC59116_ADDR); + while(i2c_busy()); + PRINTFDEBUG("I2C Ready to TX(stream)\n"); + + i2c_transmit_n(len, data); /* start tx and send conf reg */ + while(i2c_busy()); + PRINTFDEBUG("WRITE_STR %u B to 0x%02X\n", len, data[0]); +} +/*---------------------------------------------------------------------------*/ +/* Read one register. + * args: + * reg what register to read + * returns the value of the read register + */ + +uint8_t +tlc59116_read_reg(uint8_t reg) +{ + uint8_t retVal = 0; + uint8_t rtx = reg; + + PRINTFDEBUG("READ_REG 0x%02X\n", reg); + + /* transmit the register to read */ + i2c_transmitinit(TLC59116_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, &rtx); + while(i2c_busy()); + + /* receive the data */ + i2c_receiveinit(TLC59116_ADDR); + while(i2c_busy()); + i2c_receive_n(1, &retVal); + while(i2c_busy()); + + return retVal; +} +/*---------------------------------------------------------------------------*/ +/* Read several registers in a stream. + * args: + * reg what register to start reading from + * len number of bytes to read + * whereto pointer to where the data is saved + */ + +void +tlc59116_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) +{ + uint8_t rtx = reg; + + PRINTFDEBUG("READ_STR %u B from 0x%02X\n", len, reg); + + /* transmit the register to start reading from */ + i2c_transmitinit(TLC59116_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, &rtx); + while(i2c_busy()); + + /* receive the data */ + i2c_receiveinit(TLC59116_ADDR); + while(i2c_busy()); + i2c_receive_n(len, whereto); + while(i2c_busy()); +} +/*---------------------------------------------------------------------------*/ +/* Set pwm value for individual led. Make sure PWM mode is enabled. + * args: + * led led output -> 0 till 15 + * pwm led pwm value + */ + +void +tlc59116_led(uint8_t led, uint8_t pwm) +{ + if((led < 0) || (led > 15)) { + PRINTFDEBUG("TLC59116: wrong led value."); + } else { + tlc59116_write_reg(led + TLC59116_PWM0, pwm); + } +} +/*---------------------------------------------------------------------------*/ +/* Init the led driver: ports, pins, registers, interrupts (none enabled), I2C, + * default threshold values etc. + */ + +void +tlc59116_init(void) +{ + /* Set up ports and pins for I2C communication */ + i2c_enable(); + + /* set default register values. */ + tlc59116_write_reg(TLC59116_MODE1, TLC59116_MODE1_DEFAULT); + tlc59116_write_reg(TLC59116_MODE2, TLC59116_MODE2_DEFAULT); + + /*Set all PWM values to 0x00 (off) */ + /*This would maybe be better with a SWRST */ + uint8_t tx_buf[] = + { TLC59116_PWM0_AUTOINCR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + tlc59116_write_stream(17, tx_buf); + + /* set all leds to PWM control */ + tlc59116_write_reg(TLC59116_LEDOUT0, TLC59116_LEDOUT_PWM); + tlc59116_write_reg(TLC59116_LEDOUT1, TLC59116_LEDOUT_PWM); + tlc59116_write_reg(TLC59116_LEDOUT2, TLC59116_LEDOUT_PWM); + tlc59116_write_reg(TLC59116_LEDOUT3, TLC59116_LEDOUT_PWM); +} diff --git a/arch/platform/z1/dev/tlc59116.h b/arch/platform/z1/dev/tlc59116.h new file mode 100644 index 000000000..c5b74f76a --- /dev/null +++ b/arch/platform/z1/dev/tlc59116.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013, Jelmer Tiete. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Device drivers header file for TLC59116 i2c led driver on Zolertia Z1. + * See http://www.ti.com/product/tlc59116 for datasheet. + * \author + * Jelmer Tiete, VUB + */ + +#ifndef TLC59116_H_ +#define TLC59116_H_ +#include +#include "dev/i2cmaster.h" + +#if 0 +#include +#define PRINTFDEBUG(...) printf(__VA_ARGS__) +#else +#define PRINTFDEBUG(...) +#endif + + +/* -------------------------------------------------------------------------- */ +/* Init the led driver: ports, pins, registers, I2C*/ +void tlc59116_init(void); + +/* Write to a register. + * args: + * reg register to write to + * val value to write + */ +void tlc59116_write_reg(uint8_t reg, uint8_t val); + +/* Write several registers from a stream. + * args: + * len number of bytes to read + * data pointer to where the data is read from + * First byte in stream must be the register address to begin writing to. + * The data is then written from the second byte and increasing. The address byte + * is not included in length len. + */ +void tlc59116_write_stream(uint8_t len, uint8_t * data); + +/* Read one register. + * args: + * reg what register to read + * returns the value of the read register + */ +uint8_t tlc59116_read_reg(uint8_t reg); + +/* Read several registers in a stream. + * args: + * reg what register to start reading from + * len number of bytes to read + * whereto pointer to where the data is saved + */ +void tlc59116_read_stream(uint8_t reg, uint8_t len, uint8_t * whereto); + +/* Set pwm value for individual led + * args: + * led led output -> 0 till 15 + * pwm led pwm value + */ +void tlc59116_led(uint8_t led, uint8_t pwm); + + +/* -------------------------------------------------------------------------- */ +/* Application definitions, change if required by application. */ + +/* Suggested defaults according to the data sheet etc */ +#define TLC59116_MODE1_DEFAULT 0x00 /* Default (no sub or all call) + OSC on */ +#define TLC59116_MODE2_DEFAULT 0x00 /* Default (output change on stop) */ + +#define TLC59116_LEDOUT_PWM 0xAA /* LDRx = 01 -> PWM; 4 leds per reg: 01010101b -> 0xAA */ + +/* -------------------------------------------------------------------------- */ +/* Reference definitions, should not be changed */ +/* TLC59116 slave address */ +#define TLC59116_ADDR 0x60 /* 7bit adress, 8bit write adress: 0xC0 */ + /* address with all address pins pulled to ground */ +/* TLC59116 registers */ +#define TLC59116_MODE1 0x00 +#define TLC59116_MODE2 0x01 +#define TLC59116_PWM0_AUTOINCR 0xA2 /* auto increment address for first pwm register */ +#define TLC59116_PWM0 0x02 +#define TLC59116_PWM1 0x03 +#define TLC59116_PWM2 0x04 +#define TLC59116_PWM3 0x05 +#define TLC59116_PWM4 0x06 +#define TLC59116_PWM5 0x07 +#define TLC59116_PWM6 0x08 +#define TLC59116_PWM7 0x09 +#define TLC59116_PWM8 0x0A +#define TLC59116_PWM9 0x0B +#define TLC59116_PWM10 0x0C +#define TLC59116_PWM11 0x0D +#define TLC59116_PWM12 0x0E +#define TLC59116_PWM13 0x0F +#define TLC59116_PWM14 0x10 +#define TLC59116_PWM15 0x11 +#define TLC59116_GRPPWM 0x12 +#define TLC59116_GRPFREQ 0x13 +#define TLC59116_LEDOUT0 0x14 +#define TLC59116_LEDOUT1 0x15 +#define TLC59116_LEDOUT2 0x16 +#define TLC59116_LEDOUT3 0x17 + +/* More registers follow, but not used in this implementation */ + +/* -------------------------------------------------------------------------- */ +#endif /* ifndef TLC59116_H_ */ diff --git a/arch/platform/z1/dev/tmp102.c b/arch/platform/z1/dev/tmp102.c new file mode 100644 index 000000000..4bf267246 --- /dev/null +++ b/arch/platform/z1/dev/tmp102.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * Device drivers for tmp102 temperature sensor in Zolertia Z1. + * \author + * Enric M. Calvo, Zolertia + * Marcus Lundén, SICS + * Antonio Lignan, Zolertia + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "i2cmaster.h" +#include "tmp102.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +void +tmp102_init(void) +{ + /* Power Up TMP102 via pin */ + TMP102_PWR_DIR |= TMP102_PWR_PIN; + TMP102_PWR_SEL &= ~TMP102_PWR_SEL; + TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL; + TMP102_PWR_REN &= ~TMP102_PWR_SEL; + TMP102_PWR_OUT |= TMP102_PWR_PIN; + + /* Set up ports and pins for I2C communication */ + i2c_enable(); + + enabled = 1; +} +/*---------------------------------------------------------------------------*/ +void +tmp102_stop(void) +{ + /* Power off */ + TMP102_PWR_OUT &= ~TMP102_PWR_PIN; + enabled = 0; +} +/*---------------------------------------------------------------------------*/ +void +tmp102_write_reg(uint8_t reg, uint16_t val) +{ + uint8_t tx_buf[] = { reg, 0x00, 0x00 }; + + tx_buf[1] = (uint8_t)(val >> 8); + tx_buf[2] = (uint8_t)(val & 0x00FF); + + i2c_transmitinit(TMP102_ADDR); + while(i2c_busy()); + PRINTF("I2C Ready to TX\n"); + + i2c_transmit_n(3, tx_buf); + while(i2c_busy()); + PRINTF("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); +} +/*---------------------------------------------------------------------------*/ +uint16_t +tmp102_read_reg(uint8_t reg) +{ + uint8_t buf[] = { 0x00, 0x00 }; + uint16_t retVal = 0; + uint8_t rtx = reg; + PRINTF("READ_REG 0x%02X\n", reg); + + /* transmit the register to read */ + i2c_transmitinit(TMP102_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, &rtx); + while(i2c_busy()); + + /* receive the data */ + i2c_receiveinit(TMP102_ADDR); + while(i2c_busy()); + i2c_receive_n(2, &buf[0]); + while(i2c_busy()); + + retVal = (uint16_t)(buf[0] << 8 | (buf[1])); + + return retVal; +} +/*---------------------------------------------------------------------------*/ +uint16_t +tmp102_read_temp_raw(void) +{ + uint16_t rd = 0; + rd = tmp102_read_reg(TMP102_TEMP); + return rd; +} +/*---------------------------------------------------------------------------*/ +int16_t +tmp102_read_temp_x100(void) +{ + int16_t raw = 0; + int16_t sign = 1; + int16_t abstemp, temp_int; + + raw = (int16_t)tmp102_read_reg(TMP102_TEMP); + if(raw < 0) { + abstemp = (raw ^ 0xFFFF) + 1; + sign = -1; + } else { + abstemp = raw; + } + + /* Integer part of the temperature value and percents*/ + temp_int = (abstemp >> 8) * sign * 100; + temp_int += ((abstemp & 0xff) * 100) / 0x100; + return temp_int; +} +/*---------------------------------------------------------------------------*/ +int8_t +tmp102_read_temp_simple(void) +{ + /* Casted to int8_t: We don't expect temperatures outside -128 to 127 C */ + return tmp102_read_temp_x100() / 100; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return TMP102_ERROR; + } + if(value) { + tmp102_init(); + } else { + tmp102_stop(); + } + enabled = value; + return TMP102_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return TMP102_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return (int)tmp102_read_temp_x100(); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(tmp102, TMP102_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/dev/tmp102.h b/arch/platform/z1/dev/tmp102.h new file mode 100644 index 000000000..cf7a71eb8 --- /dev/null +++ b/arch/platform/z1/dev/tmp102.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Device drivers header file for tmp102 temperature sensor in Zolertia + * Z1 WSN Platform. + * \author + * Enric M. Calvo, Zolertia + * Marcus Lundén, SICS + * Antonio Lignan, Zolertia + */ +/* -------------------------------------------------------------------------- */ +#ifndef TMP102_H_ +#define TMP102_H_ +#include +#include "lib/sensors.h" +#include "i2cmaster.h" +/* -------------------------------------------------------------------------- */ +void tmp102_init(void); +void tmp102_write_reg(uint8_t reg, uint16_t val); +uint16_t tmp102_read_reg(uint8_t reg); +uint16_t tmp102_read_temp_raw(); +int8_t tmp102_read_temp_simple(); +int16_t tmp102_read_temp_x100(); +/* -------------------------------------------------------------------------- */ +#define TMP102_ADDR 0x48 +#define TMP102_TEMP 0x00 +#define TMP102_CONF 0x01 +#define TMP102_TLOW 0x02 +#define TMP102_THIGH 0x03 + +/* TMP102 pin-out */ +#define TMP102_PWR_DIR P5DIR +#define TMP102_PWR_SEL P5SEL +#define TMP102_PWR_SEL2 P5SEL2 +#define TMP102_PWR_REN P5REN +#define TMP102_PWR_OUT P5OUT +#define TMP102_PWR_PIN (1<<0) /* P5.0 */ +/* -------------------------------------------------------------------------- */ +#define TMP102_SUCCESS 0 +#define TMP102_ERROR (-1) +#define TMP102_READ 0x01 +/* -------------------------------------------------------------------------- */ +#define TMP102_SENSOR "TMP102 sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor tmp102; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef TMP102_H_ */ diff --git a/arch/platform/z1/dev/xmem.c b/arch/platform/z1/dev/xmem.c new file mode 100644 index 000000000..89ca9c17b --- /dev/null +++ b/arch/platform/z1/dev/xmem.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Device driver for the ST M25P16 40MHz 1Mbyte external memory. + * \author + * Björn Grönvall + * Enric M. Calvo + * + * Data is written bit inverted (~-operator) to flash so that + * unwritten data will read as zeros (UNIX style). + */ + +#include +#include + +#include "contiki.h" +#include "dev/spi-legacy.h" +#include "dev/xmem.h" +#include "dev/watchdog.h" + +#if 1 +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) do {} while (0) +#endif + +#define SPI_FLASH_INS_WREN 0x06 +#define SPI_FLASH_INS_WRDI 0x04 +#define SPI_FLASH_INS_RDSR 0x05 +#define SPI_FLASH_INS_WRSR 0x01 +#define SPI_FLASH_INS_READ 0x03 +#define SPI_FLASH_INS_FAST_READ 0x0b +#define SPI_FLASH_INS_PP 0x02 +#define SPI_FLASH_INS_SE 0xd8 +#define SPI_FLASH_INS_BE 0xc7 +#define SPI_FLASH_INS_DP 0xb9 +#define SPI_FLASH_INS_RES 0xab +/*---------------------------------------------------------------------------*/ +static void +write_enable(void) +{ + int s; + + s = splhigh(); + SPI_FLASH_ENABLE(); + + SPI_WRITE(SPI_FLASH_INS_WREN); + + SPI_FLASH_DISABLE(); + splx(s); +} +/*---------------------------------------------------------------------------*/ +static unsigned +read_status_register(void) +{ + unsigned char u; + + int s; + + s = splhigh(); + SPI_FLASH_ENABLE(); + + + SPI_WRITE(SPI_FLASH_INS_RDSR); + + SPI_FLUSH(); + SPI_READ(u); + + SPI_FLASH_DISABLE(); + splx(s); + + return u; +} +/*---------------------------------------------------------------------------*/ +/* + * Wait for a write/erase operation to finish. + */ +static unsigned +wait_ready(void) +{ + unsigned u; + do { + u = read_status_register(); + watchdog_periodic(); + } while(u & 0x01); /* WIP=1, write in progress */ + return u; +} +/*---------------------------------------------------------------------------*/ +/* + * Erase 64k bytes of data. It takes about 1s before WIP goes low! + */ +static void +erase_sector(unsigned long offset) +{ + int s; + wait_ready(); + + write_enable(); + + s = splhigh(); + SPI_FLASH_ENABLE(); + + SPI_WRITE_FAST(SPI_FLASH_INS_SE); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ + SPI_WAITFORTx_ENDED(); + + SPI_FLASH_DISABLE(); + splx(s); +} +/*---------------------------------------------------------------------------*/ +/* + * Initialize external flash *and* SPI bus! + */ +void +xmem_init(void) +{ + spi_init(); + + P4DIR |= BV(FLASH_CS); /* Unnecessary for Zolertia Z1 | BV(FLASH_PWR); */ + P5DIR |= BV(FLASH_HOLD); /* In P5 for Z1 */ + + SPI_FLASH_DISABLE(); /* Unselect flash. */ + SPI_FLASH_UNHOLD(); +} +/*---------------------------------------------------------------------------*/ +int +xmem_pread(void *_p, int size, unsigned long offset) +{ + unsigned char *p = _p; + const unsigned char *end = p + size; + int s; + wait_ready(); + + s = splhigh(); + SPI_FLASH_ENABLE(); + + SPI_WRITE_FAST(SPI_FLASH_INS_READ); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ + SPI_WAITFORTx_ENDED(); + + SPI_FLUSH(); + for(; p < end; p++) { + unsigned char u; + SPI_READ(u); + *p = ~u; + } + + SPI_FLASH_DISABLE(); + splx(s); + + return size; +} +/*---------------------------------------------------------------------------*/ +static const unsigned char * +program_page(unsigned long offset, const unsigned char *p, int nbytes) +{ + const unsigned char *end = p + nbytes; + int s; + + wait_ready(); + + write_enable(); + + s = splhigh(); + SPI_FLASH_ENABLE(); + + SPI_WRITE_FAST(SPI_FLASH_INS_PP); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ + + for(; p < end; p++) { + SPI_WRITE_FAST(~*p); + } + SPI_WAITFORTx_ENDED(); + + SPI_FLASH_DISABLE(); + splx(s); + + return p; +} +/*---------------------------------------------------------------------------*/ +int +xmem_pwrite(const void *_buf, int size, unsigned long addr) +{ + const unsigned char *p = _buf; + const unsigned long end = addr + size; + unsigned long i, next_page; + + for(i = addr; i < end;) { + next_page = (i | 0xff) + 1; + if(next_page > end) { + next_page = end; + } + p = program_page(i, p, next_page - i); + i = next_page; + } + + return size; +} +/*---------------------------------------------------------------------------*/ +int +xmem_erase(long size, unsigned long addr) +{ + unsigned long end = addr + size; + + if(size % XMEM_ERASE_UNIT_SIZE != 0) { + PRINTF("xmem_erase: bad size\n"); + return -1; + } + + if(addr % XMEM_ERASE_UNIT_SIZE != 0) { + PRINTF("xmem_erase: bad offset\n"); + return -1; + } + + for (; addr < end; addr += XMEM_ERASE_UNIT_SIZE) { + erase_sector(addr); + } + + return size; +} +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/dev/z1-phidgets.c b/arch/platform/z1/dev/z1-phidgets.c new file mode 100644 index 000000000..e86c3e2f0 --- /dev/null +++ b/arch/platform/z1/dev/z1-phidgets.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * ----------------------------------------------------------------- + * + * Author : Joakim Eriksson + * Created : 2010-02-02 + * Updated : $Date: 2010/11/05 10:31:57 $ + * $Revision: 1.3 $ + */ + +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/z1-phidgets.h" + +static uint8_t adc_on; +static uint8_t active; +/*---------------------------------------------------------------------------*/ +static void +sensors_activate(uint8_t type) +{ + uint8_t pre = adc_on; + + adc_on |= type; + + if(pre == 0 && adc_on > 0) { + P6DIR = 0xff; + P6OUT = 0x00; + P6SEL |= 0x8b; /* bit 7 + 3 + 1 + 0 */ + + /* if nothing was started before, start up the ADC system */ + /* Set up the ADC. */ + ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC; /* Setup ADC12, ref., sampling time */ + ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; /* Use sampling timer, repeat-sequenc-of-channels */ + /* convert up to MEM4 */ + ADC12MCTL4 |= EOS; + + ADC12CTL0 |= ADC12ON + REFON; + ADC12CTL0 |= ENC; /* enable conversion */ + ADC12CTL0 |= ADC12SC; /* sample & convert */ + } +} +/*---------------------------------------------------------------------------*/ +static void +sensors_deactivate(uint8_t type) +{ + adc_on &= ~type; + + if(adc_on == 0) { + /* stop converting immediately, turn off reference voltage, etc. */ + /* wait for conversion to stop */ + + ADC12CTL0 &= ~ENC; + /* need to remove CONSEQ_3 if not EOS is configured */ + ADC12CTL1 &= ~CONSEQ_3; + + while(ADC12CTL1 & ADC12BUSY); + + ADC12CTL0 = 0; + ADC12CTL1 = 0; + + P6DIR = 0x00; + P6OUT = 0x00; + P6SEL = 0x00; + } +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* ADC0 corresponds to the port under the logo, ADC1 to the port over the logo, + ADC2 and ADC3 corresponds to port on the JCreate bottom expansion port) */ + switch(type) { + case PHIDGET5V_1: + return ADC12MEM0; + case PHIDGET5V_2: + return ADC12MEM1; + case PHIDGET3V_1: + return ADC12MEM2; + case PHIDGET3V_2: + return ADC12MEM3; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return active; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + /* SREF_1 is Vref+ */ + /* MemReg6 == P6.0/A0 == 5V 1 */ + ADC12MCTL0 = (INCH_0 + SREF_0); + /* MemReg7 == P6.3/A3 == 5V 2 */ + ADC12MCTL1 = (INCH_3 + SREF_0); + /* MemReg8 == P6.1/A1 == 3V 1 */ + ADC12MCTL2 = (INCH_1 + SREF_0); + /* MemReg9 == P6.7/A7 == 3V_2 */ + ADC12MCTL3 = (INCH_7 + SREF_0); + + sensors_activate(0x0F); + active = 1; + } + } else { + sensors_deactivate(0x0F); + active = 0; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(phidgets, "Phidgets", value, configure, status); diff --git a/arch/platform/z1/dev/z1-phidgets.h b/arch/platform/z1/dev/z1-phidgets.h new file mode 100644 index 000000000..f56356508 --- /dev/null +++ b/arch/platform/z1/dev/z1-phidgets.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * ----------------------------------------------------------------- + * + * Author : Joakim Eriksson + * Created : 2010-08-26 + * Updated : $Date: 2010/08/27 12:58:57 $ + * $Revision: 1.2 $ + */ +#ifndef Z1_PHIDGETS_H_ +#define Z1_PHIDGETS_H_ + +#define PHIDGET5V_1 0 +#define PHIDGET5V_2 1 +#define PHIDGET3V_1 2 +#define PHIDGET3V_2 3 + +extern const struct sensors_sensor phidgets; + +#endif /* Z1_PHIDGETS_H_ */ diff --git a/arch/platform/z1/dev/z1-sensors.c b/arch/platform/z1/dev/z1-sensors.c new file mode 100644 index 000000000..db5b418b9 --- /dev/null +++ b/arch/platform/z1/dev/z1-sensors.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * Zolertia Z1 on-board sensors + * \author + * Antonio Lignan, Zolertia + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/button-sensor.h" +#include "dev/tmp102.h" +#include "dev/adxl345.h" +/*---------------------------------------------------------------------------*/ +/** \brief Exports global symbols for the sensor API */ +SENSORS(&button_sensor, &adxl345, &tmp102); +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/node-id-z1.c b/arch/platform/z1/node-id-z1.c new file mode 100644 index 000000000..7f65e2c58 --- /dev/null +++ b/arch/platform/z1/node-id-z1.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Utility to store a node id in the external flash + * \author + * Adam Dunkels + */ + +#include "contiki.h" +#include "sys/node-id.h" +#include "dev/xmem.h" +#include + +unsigned char node_mac[8]; + +/*---------------------------------------------------------------------------*/ +void +node_id_z1_restore(void) +{ + unsigned char buf[12]; + xmem_pread(buf, 12, NODE_ID_XMEM_OFFSET); + if(buf[0] == 0xad && + buf[1] == 0xde) { + node_id = (buf[2] << 8) | buf[3]; + memcpy(node_mac, &buf[4], 8); + } else { + node_id = 0; + } +} +/*---------------------------------------------------------------------------*/ +void +node_id_z1_burn(unsigned short id) +{ + unsigned char buf[12]; + memset(buf, 0, sizeof(buf)); + buf[0] = 0xad; + buf[1] = 0xde; + buf[2] = id >> 8; + buf[3] = id & 0xff; + xmem_erase(XMEM_ERASE_UNIT_SIZE, NODE_ID_XMEM_OFFSET); + xmem_pwrite(buf, 12, NODE_ID_XMEM_OFFSET); +} +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/node-id-z1.h b/arch/platform/z1/node-id-z1.h new file mode 100644 index 000000000..d70c018d6 --- /dev/null +++ b/arch/platform/z1/node-id-z1.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + */ + +#ifndef NODE_ID_Z1_H_ +#define NODE_ID_Z1_H_ + +#include + +void node_id_z1_restore(void); +void node_id_z1_burn(uint16_t node_id); + +#endif /* NODE_ID_Z1_H_ */ diff --git a/arch/platform/z1/platform.c b/arch/platform/z1/platform.c new file mode 100644 index 000000000..0d8d248c5 --- /dev/null +++ b/arch/platform/z1/platform.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 "contiki.h" +#include "cc2420.h" +#include "dev/leds.h" +#include "dev/serial-line.h" +#include "dev/slip.h" +#include "dev/uart0.h" +#include "dev/watchdog.h" +#include "dev/xmem.h" +#include "lib/random.h" +#include "net/netstack.h" +#include "net/mac/framer/frame802154.h" +#include "dev/adxl345.h" +#include "sys/clock.h" +#include "sys/energest.h" + +#if NETSTACK_CONF_WITH_IPV6 +#include "net/ipv6/uip-ds6.h" +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +#include "node-id-z1.h" +#include "cfs-coffee-arch.h" +#include "cfs/cfs-coffee.h" + +extern unsigned char node_mac[8]; + +#if DCOSYNCH_CONF_ENABLED +static struct timer mgt_timer; +#endif +extern int msp430_dco_required; + +#define UIP_OVER_MESH_CHANNEL 8 +#if NETSTACK_CONF_WITH_IPV4 +static uint8_t is_gateway; +#endif /* NETSTACK_CONF_WITH_IPV4 */ + +#ifdef EXPERIMENT_SETUP +#include "experiment-setup.h" +#endif + +void init_platform(void); +/*---------------------------------------------------------------------------*/ +/* Log configuration */ +#include "sys/log.h" +#define LOG_MODULE "Z1" +#define LOG_LEVEL LOG_LEVEL_MAIN +/*---------------------------------------------------------------------------*/ +#ifdef UART0_CONF_BAUD_RATE +#define UART0_BAUD_RATE UART0_CONF_BAUD_RATE +#else +#define UART0_BAUD_RATE 115200 +#endif +/*---------------------------------------------------------------------------*/ +#if 0 +int +force_float_inclusion() +{ + extern int __fixsfsi; + extern int __floatsisf; + extern int __mulsf3; + extern int __subsf3; + + return __fixsfsi + __floatsisf + __mulsf3 + __subsf3; +} +#endif +/*---------------------------------------------------------------------------*/ +void +uip_log(char *msg) +{ + puts(msg); +} +/*---------------------------------------------------------------------------*/ +#if 0 +void +force_inclusion(int d1, int d2) +{ + snprintf(NULL, 0, "%d", d1 % d2); +} +#endif +/*---------------------------------------------------------------------------*/ +static void +set_lladdr(void) +{ + linkaddr_t addr; + + memset(&addr, 0, sizeof(linkaddr_t)); +#if NETSTACK_CONF_WITH_IPV6 + memcpy(addr.u8, node_mac, sizeof(addr.u8)); +#else + if(node_id == 0) { + int i; + for(i = 0; i < sizeof(linkaddr_t); ++i) { + addr.u8[i] = node_mac[7 - i]; + } + } else { + addr.u8[0] = node_id & 0xff; + addr.u8[1] = node_id >> 8; + } +#endif + linkaddr_set_node_addr(&addr); +} +/*---------------------------------------------------------------------------*/ +void +platform_init_stage_one(void) +{ + /* + * Initalize hardware. + */ + msp430_cpu_init(); + + leds_init(); + leds_on(LEDS_RED); +} +/*---------------------------------------------------------------------------*/ +void +platform_init_stage_two(void) +{ + clock_wait(100); + + uart0_init(BAUD2UBR(UART0_BAUD_RATE)); /* Must come before first printf */ + + xmem_init(); + + leds_off(LEDS_RED); + /* + * Hardware initialization done! + */ + + /* Restore node id if such has been stored in external mem */ + node_id_z1_restore(); + + /* If no MAC address was burned, we use the node id or the Z1 product ID */ + if(!(node_mac[0] | node_mac[1] | node_mac[2] | node_mac[3] | + node_mac[4] | node_mac[5] | node_mac[6] | node_mac[7])) { + +#ifdef SERIALNUM + if(!node_id) { + LOG_INFO("Node id is not set, using Z1 product ID\n"); + node_id = SERIALNUM; + } +#endif + node_mac[0] = 0xc1; /* Hardcoded for Z1 */ + node_mac[1] = 0x0c; /* Hardcoded for Revision C */ + node_mac[2] = 0x00; /* Hardcoded to arbitrary even number so that + the 802.15.4 MAC address is compatible with + an Ethernet MAC address - byte 0 (byte 2 in + the DS ID) */ + node_mac[3] = 0x00; /* Hardcoded */ + node_mac[4] = 0x00; /* Hardcoded */ + node_mac[5] = 0x00; /* Hardcoded */ + node_mac[6] = node_id >> 8; + node_mac[7] = node_id & 0xff; + } + + /* Overwrite node MAC if desired at compile time */ +#ifdef MACID +#warning "***** CHANGING DEFAULT MAC *****" + node_mac[0] = 0xc1; /* Hardcoded for Z1 */ + node_mac[1] = 0x0c; /* Hardcoded for Revision C */ + node_mac[2] = 0x00; /* Hardcoded to arbitrary even number so that + the 802.15.4 MAC address is compatible with + an Ethernet MAC address - byte 0 (byte 2 in + the DS ID) */ + node_mac[3] = 0x00; /* Hardcoded */ + node_mac[4] = 0x00; /* Hardcoded */ + node_mac[5] = 0x00; /* Hardcoded */ + node_mac[6] = MACID >> 8; + node_mac[7] = MACID & 0xff; +#endif + +#ifdef IEEE_802154_MAC_ADDRESS + /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */ + { + uint8_t ieee[] = IEEE_802154_MAC_ADDRESS; + memcpy(node_mac, ieee, sizeof(uip_lladdr.addr)); + node_mac[7] = node_id & 0xff; + } +#endif /* IEEE_802154_MAC_ADDRESS */ + + random_init(node_mac[6] + node_mac[7]); + + set_lladdr(); + + /* + * main() will turn the radio on inside netstack_init(). The CC2420 + * must already be initialised by that time, so we do this here early. + * Later on in stage three we set correct values for PANID and radio + * short/long address. + */ + cc2420_init(); + + SENSORS_ACTIVATE(adxl345); + + leds_off(LEDS_ALL); +} +/*---------------------------------------------------------------------------*/ +void +platform_init_stage_three(void) +{ + uint8_t longaddr[8]; + uint16_t shortaddr; + + init_platform(); + + shortaddr = (linkaddr_node_addr.u8[0] << 8) + linkaddr_node_addr.u8[1]; + memset(longaddr, 0, sizeof(longaddr)); + linkaddr_copy((linkaddr_t *)&longaddr, &linkaddr_node_addr); + + cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr); + + LOG_INFO("CC2420 CCA threshold %i\n", CC2420_CONF_CCA_THRESH); + +#if DCOSYNCH_CONF_ENABLED + timer_set(&mgt_timer, DCOSYNCH_PERIOD * CLOCK_SECOND); +#endif +} +/*---------------------------------------------------------------------------*/ +void +platform_idle(void) +{ + /* + * Idle processing. + */ + int s = splhigh(); /* Disable interrupts. */ + /* uart0_active is for avoiding LPM3 when still sending or receiving */ + if(process_nevents() != 0 || uart0_active()) { + splx(s); /* Re-enable interrupts. */ + } else { +#if DCOSYNCH_CONF_ENABLED + /* before going down to sleep possibly do some management */ + if(timer_expired(&mgt_timer)) { + watchdog_periodic(); + timer_reset(&mgt_timer); + msp430_sync_dco(); +#if CC2420_CONF_SFD_TIMESTAMPS + cc2420_arch_sfd_init(); +#endif /* CC2420_CONF_SFD_TIMESTAMPS */ + } +#endif + + /* Re-enable interrupts and go to sleep atomically. */ + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); + watchdog_stop(); + /* check if the DCO needs to be on - if so - only LPM 1 */ + if (msp430_dco_required) { + _BIS_SR(GIE | CPUOFF); /* LPM1 sleep for DMA to work!. */ + } else { + _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This + statement will block + until the CPU is + woken up by an + interrupt that sets + the wake up flag. */ + } + watchdog_start(); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/z1/z1-def.h b/arch/platform/z1/z1-def.h new file mode 100644 index 000000000..e59165ee3 --- /dev/null +++ b/arch/platform/z1/z1-def.h @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +/** + * \file + * Platform configuration for the Z1 platform + * \author + * Joakim Eriksson + */ + +#ifndef Z1_DEF_H_ +#define Z1_DEF_H_ + +#include + +/* + * Definitions below are dictated by the hardware and not really + * changeable! + */ + +#define ZOLERTIA_Z1 1 /* Enric */ + +/* 1 len byte, 2 bytes CRC */ + #define RADIO_PHY_OVERHEAD 3 + /* 250kbps data rate. One byte = 32us */ + #define RADIO_BYTE_AIR_TIME 32 +/* Delay between GO signal and SFD: radio fixed delay + 4Bytes preample + 1B SFD -- 1Byte time is 32us + * ~327us + 129preample = 456 us */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(456)) +/* Delay between GO signal and start listening + * ~50us delay + 129preample + ?? = 183 us */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(183)) +/* Delay between the SFD finishes arriving and it is detected in software */ +#define RADIO_DELAY_BEFORE_DETECT 0 + +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_RADIO 1 +#define PLATFORM_HAS_BATTERY 1 + +/* CPU target speed in Hz */ +#define F_CPU 8000000uL /* 8MHz by default */ + +/* the low-level radio driver */ +#define NETSTACK_CONF_RADIO cc2420_driver + +/* XXX Temporary place for defines that are lacking in mspgcc4's gpio.h */ +#ifdef __IAR_SYSTEMS_ICC__ +#ifndef P1SEL2_ +#define P1SEL2_ (0x0041u) /* Port 1 Selection 2*/ +DEFC(P1SEL2, P1SEL2_) +#endif +#ifndef P5SEL2_ +#define P5SEL2_ (0x0045u) /* Port 5 Selection 2*/ +DEFC(P5SEL2, P5SEL2_) +#endif +#else /* __IAR_SYSTEMS_ICC__ */ +#ifdef __GNUC__ +#ifndef P1SEL2_ +#define P1SEL2_ 0x0041 /* Port 1 Selection 2*/ +sfrb(P1SEL2, P1SEL2_); +#endif +#ifndef P5SEL2_ +#define P5SEL2_ 0x0045 /* Port 5 Selection 2*/ +sfrb(P5SEL2, P5SEL2_); +#endif +#endif /* __GNUC__ */ +#endif /* __IAR_SYSTEMS_ICC__ */ + +/* + * Definitions below are dictated by the hardware and not really + * changeable! + */ + +/* LED ports */ +#ifdef Z1_IS_Z1SP +#define LEDS_PxDIR P4DIR +#define LEDS_PxOUT P4OUT +#define LEDS_CONF_RED 0x04 +#define LEDS_CONF_GREEN 0x01 +#define LEDS_CONF_YELLOW 0x80 +#else +#define LEDS_PxDIR P5DIR +#define LEDS_PxOUT P5OUT +#define LEDS_CONF_RED 0x10 +#define LEDS_CONF_GREEN 0x40 +#define LEDS_CONF_YELLOW 0x20 +#endif /* Z1_IS_Z1SP */ + +#define LEDS_CONF_LEGACY_API 1 + +/* DCO speed resynchronization for more robust UART, etc. */ +#ifndef DCOSYNCH_CONF_ENABLED +#define DCOSYNCH_CONF_ENABLED (!(MAC_CONF_WITH_TSCH)) /* TSCH needs timerB +for SFD timestamping */ +#endif /* DCOSYNCH_CONF_ENABLED */ + +#ifndef CC2420_CONF_SFD_TIMESTAMPS +#define CC2420_CONF_SFD_TIMESTAMPS (MAC_CONF_WITH_TSCH) /* TSCH needs SFD timestamping */ +#endif /* CC2420_CONF_SFD_TIMESTAMPS */ + +#ifndef DCOSYNCH_CONF_PERIOD +#define DCOSYNCH_CONF_PERIOD 30 +#endif /* DCOSYNCH_CONF_PERIOD */ + +#define ROM_ERASE_UNIT_SIZE 512 +#define XMEM_ERASE_UNIT_SIZE (64 * 1024L) + +#define CFS_CONF_OFFSET_TYPE long + +/* Use the first 64k of external flash for node configuration */ +#define NODE_ID_XMEM_OFFSET (0 * XMEM_ERASE_UNIT_SIZE) + +/* Use the second 64k of external flash for codeprop. */ +#define EEPROMFS_ADDR_CODEPROP (1 * XMEM_ERASE_UNIT_SIZE) + +#define CFS_XMEM_CONF_OFFSET (2 * XMEM_ERASE_UNIT_SIZE) +#define CFS_XMEM_CONF_SIZE (1 * XMEM_ERASE_UNIT_SIZE) + +#define CFS_RAM_CONF_SIZE 4096 + +/* + * SPI bus configuration for the Z1 mote. + */ + +/* SPI input/output registers. */ +#define SPI_TXBUF UCB0TXBUF +#define SPI_RXBUF UCB0RXBUF + +/* USART0 Tx ready? */ +#define SPI_WAITFOREOTx() while((UCB0STAT & UCBUSY) != 0) +/* USART0 Rx ready? */ +#define SPI_WAITFOREORx() while((IFG2 & UCB0RXIFG) == 0) +/* USART0 Tx buffer ready? */ +#define SPI_WAITFORTxREADY() while((IFG2 & UCB0TXIFG) == 0) + +#define MOSI 1 /* P3.1 - Output: SPI Master out - slave in (MOSI) */ +#define MISO 2 /* P3.2 - Input: SPI Master in - slave out (MISO) */ +#define SCK 3 /* P3.3 - Output: SPI Serial Clock (SCLK) */ + +/* + * SPI bus - M25P80 external flash configuration. + */ +/* FLASH_PWR P4.3 Output ALWAYS POWERED ON Z1 */ +#define FLASH_CS 4 /* P4.4 Output */ +#define FLASH_HOLD 7 /* P5.7 Output */ + +/* Enable/disable flash access to the SPI bus (active low). */ + +#define SPI_FLASH_ENABLE() (P4OUT &= ~BV(FLASH_CS)) +#define SPI_FLASH_DISABLE() (P4OUT |= BV(FLASH_CS)) + +#define SPI_FLASH_HOLD() (P5OUT &= ~BV(FLASH_HOLD)) +#define SPI_FLASH_UNHOLD() (P5OUT |= BV(FLASH_HOLD)) + +/* + * SPI bus - CC2420 pin configuration. + */ + +#define CC2420_CONF_SYMBOL_LOOP_COUNT 1302 /* 326us msp430X @ 8MHz */ + +/* P1.2 - Input: FIFOP from CC2420 */ +#define CC2420_FIFOP_PORT(type) P1##type +#define CC2420_FIFOP_PIN 2 +/* P1.3 - Input: FIFO from CC2420 */ +#define CC2420_FIFO_PORT(type) P1##type +#define CC2420_FIFO_PIN 3 +/* P1.4 - Input: CCA from CC2420 */ +#define CC2420_CCA_PORT(type) P1##type +#define CC2420_CCA_PIN 4 +/* P4.1 - Input: SFD from CC2420 */ +#define CC2420_SFD_PORT(type) P4##type +#define CC2420_SFD_PIN 1 +/* P3.0 - Output: SPI Chip Select (CS_N) */ +#define CC2420_CSN_PORT(type) P3##type +#define CC2420_CSN_PIN 0 +/* P4.5 - Output: VREG_EN to CC2420 */ +#define CC2420_VREG_PORT(type) P4##type +#define CC2420_VREG_PIN 5 +/* P4.6 - Output: RESET_N to CC2420 */ +#define CC2420_RESET_PORT(type) P4##type +#define CC2420_RESET_PIN 6 + +#define CC2420_IRQ_VECTOR PORT1_VECTOR + +/* Pin status. */ +#define CC2420_FIFOP_IS_1 (!!(CC2420_FIFOP_PORT(IN) & BV(CC2420_FIFOP_PIN))) +#define CC2420_FIFO_IS_1 (!!(CC2420_FIFO_PORT(IN) & BV(CC2420_FIFO_PIN))) +#define CC2420_CCA_IS_1 (!!(CC2420_CCA_PORT(IN) & BV(CC2420_CCA_PIN))) +#define CC2420_SFD_IS_1 (!!(CC2420_SFD_PORT(IN) & BV(CC2420_SFD_PIN))) + +/* The CC2420 reset pin. */ +#define SET_RESET_INACTIVE() (CC2420_RESET_PORT(OUT) |= BV(CC2420_RESET_PIN)) +#define SET_RESET_ACTIVE() (CC2420_RESET_PORT(OUT) &= ~BV(CC2420_RESET_PIN)) + +/* CC2420 voltage regulator enable pin. */ +#define SET_VREG_ACTIVE() (CC2420_VREG_PORT(OUT) |= BV(CC2420_VREG_PIN)) +#define SET_VREG_INACTIVE() (CC2420_VREG_PORT(OUT) &= ~BV(CC2420_VREG_PIN)) + +/* CC2420 rising edge trigger for external interrupt 0 (FIFOP). */ +#define CC2420_FIFOP_INT_INIT() do { \ + CC2420_FIFOP_PORT(IES) &= ~BV(CC2420_FIFOP_PIN); \ + CC2420_CLEAR_FIFOP_INT(); \ +} while(0) + +/* FIFOP on external interrupt 0. */ +#define CC2420_ENABLE_FIFOP_INT() do { CC2420_FIFOP_PORT(IE) |= BV(CC2420_FIFOP_PIN); } while(0) +#define CC2420_DISABLE_FIFOP_INT() do { CC2420_FIFOP_PORT(IE) &= ~BV(CC2420_FIFOP_PIN); } while(0) +#define CC2420_CLEAR_FIFOP_INT() do { CC2420_FIFOP_PORT(IFG) &= ~BV(CC2420_FIFOP_PIN); } while(0) + +/* + * Enables/disables CC2420 access to the SPI bus (not the bus). + * (Chip Select) + */ + +/* ENABLE CSn (active low) */ +#define CC2420_SPI_ENABLE() (CC2420_CSN_PORT(OUT) &= ~BV(CC2420_CSN_PIN)) +/* DISABLE CSn (active low) */ +#define CC2420_SPI_DISABLE() (CC2420_CSN_PORT(OUT) |= BV(CC2420_CSN_PIN)) +#define CC2420_SPI_IS_ENABLED() ((CC2420_CSN_PORT(OUT) & BV(CC2420_CSN_PIN)) != BV(CC2420_CSN_PIN)) + +/* + * I2C configuration + */ + +#define I2C_PxDIR P5DIR +#define I2C_PxIN P5IN +#define I2C_PxOUT P5OUT +#define I2C_PxSEL P5SEL +#define I2C_PxSEL2 P5SEL2 +#define I2C_PxREN P5REN + +#define I2C_SDA (1 << 1) /* SDA == P5.1 */ +#define I2C_SCL (1 << 2) /* SCL == P5.2 */ +#define I2C_PRESC_1KHZ_LSB 0x00 +#define I2C_PRESC_1KHZ_MSB 0x20 +#define I2C_PRESC_100KHZ_LSB 0x50 +#define I2C_PRESC_100KHZ_MSB 0x00 +#define I2C_PRESC_400KHZ_LSB 0x14 +#define I2C_PRESC_400KHZ_MSB 0x00 + +/* Set rate as high as possible by default */ +#ifndef I2C_PRESC_Z1_LSB +#define I2C_PRESC_Z1_LSB I2C_PRESC_400KHZ_LSB +#endif + +#ifndef I2C_PRESC_Z1_MSB +#define I2C_PRESC_Z1_MSB I2C_PRESC_400KHZ_MSB +#endif + +/* I2C configuration with RX interrupts */ +#ifdef I2C_CONF_RX_WITH_INTERRUPT +#define I2C_RX_WITH_INTERRUPT I2C_CONF_RX_WITH_INTERRUPT +#else /* I2C_CONF_RX_WITH_INTERRUPT */ +#define I2C_RX_WITH_INTERRUPT 1 +#endif /* I2C_CONF_RX_WITH_INTERRUPT */ + +/* Platform-specific define for the end of the stack region */ +#define STACK_CONF_ORIGIN ((void *)0x3100) + +#endif /* PLATFORM_CONF_H_ */ diff --git a/examples/6tisch/6p-packet/Makefile b/examples/6tisch/6p-packet/Makefile index 3ba74d3b9..707a02485 100644 --- a/examples/6tisch/6p-packet/Makefile +++ b/examples/6tisch/6p-packet/Makefile @@ -1,7 +1,7 @@ CONTIKI_PROJECT = sixp-node PROJECT_SOURCEFILES += test-sf.c -PLATFORMS_EXCLUDE = sky nrf52dk native simplelink +PLATFORMS_EXCLUDE = sky z1 nrf52dk native simplelink CONTIKI = ../../../ diff --git a/examples/6tisch/channel-selection-demo/Makefile b/examples/6tisch/channel-selection-demo/Makefile index ada4a5062..e3c4288f6 100644 --- a/examples/6tisch/channel-selection-demo/Makefile +++ b/examples/6tisch/channel-selection-demo/Makefile @@ -3,7 +3,7 @@ all: $(CONTIKI_PROJECT) CONTIKI=../../.. -PLATFORMS_EXCLUDE = sky nrf52dk native +PLATFORMS_EXCLUDE = sky z1 nrf52dk native BOARDS_EXCLUDE = srf06/cc13x0 launchpad/cc1310 launchpad/cc1350 sensortag/cc2650 sensortag/cc1350 # The channel selection library diff --git a/examples/6tisch/etsi-plugtest-2017/Makefile b/examples/6tisch/etsi-plugtest-2017/Makefile index 6dc463078..6b1a23a4c 100644 --- a/examples/6tisch/etsi-plugtest-2017/Makefile +++ b/examples/6tisch/etsi-plugtest-2017/Makefile @@ -1,7 +1,7 @@ CONTIKI_PROJECT = node all: $(CONTIKI_PROJECT) -PLATFORMS_EXCLUDE = sky nrf52dk native simplelink +PLATFORMS_EXCLUDE = sky z1 nrf52dk native simplelink BOARDS_EXCLUDE = sensortag/cc2650 sensortag/cc1350 MAKE_WITH_SECURITY ?= 0 # force Security from command line diff --git a/examples/6tisch/simple-node/node.c b/examples/6tisch/simple-node/node.c index 381d81f8e..b8e29e7f6 100644 --- a/examples/6tisch/simple-node/node.c +++ b/examples/6tisch/simple-node/node.c @@ -60,7 +60,7 @@ PROCESS_THREAD(node_process, ev, data) is_coordinator = 0; -#if CONTIKI_TARGET_COOJA +#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_Z1 is_coordinator = (node_id == 1); #endif diff --git a/examples/6tisch/sixtop/Makefile b/examples/6tisch/sixtop/Makefile index 5c35696e4..1e6f0ef5f 100644 --- a/examples/6tisch/sixtop/Makefile +++ b/examples/6tisch/sixtop/Makefile @@ -1,7 +1,7 @@ CONTIKI_PROJECT = node-sixtop all: $(CONTIKI_PROJECT) -PLATFORMS_EXCLUDE = sky nrf52dk native simplelink +PLATFORMS_EXCLUDE = sky z1 nrf52dk native simplelink PROJECT_SOURCEFILES += sf-simple.c CONTIKI=../../.. diff --git a/examples/6tisch/timesync-demo/Makefile b/examples/6tisch/timesync-demo/Makefile index cd18192d0..85c29659f 100644 --- a/examples/6tisch/timesync-demo/Makefile +++ b/examples/6tisch/timesync-demo/Makefile @@ -3,7 +3,7 @@ all: $(CONTIKI_PROJECT) CONTIKI=../../.. -PLATFORMS_EXCLUDE = sky nrf52dk native +PLATFORMS_EXCLUDE = sky z1 nrf52dk native # force Orchestra from command line MAKE_WITH_ORCHESTRA ?= 0 diff --git a/examples/6tisch/tsch-stats/Makefile b/examples/6tisch/tsch-stats/Makefile index 5fdb5feb6..156c0d526 100644 --- a/examples/6tisch/tsch-stats/Makefile +++ b/examples/6tisch/tsch-stats/Makefile @@ -3,7 +3,7 @@ all: $(CONTIKI_PROJECT) CONTIKI=../../.. -PLATFORMS_EXCLUDE = sky nrf52dk native +PLATFORMS_EXCLUDE = sky z1 nrf52dk native BOARDS_EXCLUDE = srf06/cc13x0 launchpad/cc1310 launchpad/cc1350 sensortag/cc2650 sensortag/cc1350 # force Orchestra from command line diff --git a/examples/benchmarks/rpl-req-resp/Makefile b/examples/benchmarks/rpl-req-resp/Makefile index e23a35d5f..dadd7a2d7 100644 --- a/examples/benchmarks/rpl-req-resp/Makefile +++ b/examples/benchmarks/rpl-req-resp/Makefile @@ -1,7 +1,7 @@ CONTIKI_PROJECT = node all: $(CONTIKI_PROJECT) -PLATFORMS_EXCLUDE = sky nrf52dk native simplelink +PLATFORMS_EXCLUDE = sky z1 nrf52dk native simplelink BOARDS_EXCLUDE = srf06/cc13x0 launchpad/cc1310 launchpad/cc1350 sensortag/cc2650 sensortag/cc1350 MODULES_REL += ../testbeds diff --git a/examples/coap/coap-example-client/Makefile b/examples/coap/coap-example-client/Makefile index 1d3440990..21c9649e7 100644 --- a/examples/coap/coap-example-client/Makefile +++ b/examples/coap/coap-example-client/Makefile @@ -3,7 +3,7 @@ CONTIKI_PROJECT = coap-example-client all: $(CONTIKI_PROJECT) # Do not try to build on Sky because of code size limitation -PLATFORMS_EXCLUDE = sky +PLATFORMS_EXCLUDE = sky z1 # Include the CoAP implementation MODULES += os/net/app-layer/coap diff --git a/examples/coap/coap-example-server/Makefile b/examples/coap/coap-example-server/Makefile index 6d9e2db85..1647568cb 100644 --- a/examples/coap/coap-example-server/Makefile +++ b/examples/coap/coap-example-server/Makefile @@ -2,7 +2,7 @@ CONTIKI_PROJECT = coap-example-server all: $(CONTIKI_PROJECT) # Do not try to build on Sky because of code size limitation -PLATFORMS_EXCLUDE = sky +PLATFORMS_EXCLUDE = sky z1 # Include the CoAP implementation MODULES += os/net/app-layer/coap diff --git a/examples/lwm2m-ipso-objects/Makefile b/examples/lwm2m-ipso-objects/Makefile index c2cef2cfd..a8d461859 100644 --- a/examples/lwm2m-ipso-objects/Makefile +++ b/examples/lwm2m-ipso-objects/Makefile @@ -2,7 +2,7 @@ CONTIKI_PROJECT = example-ipso-objects CONTIKI_SOURCEFILES += serial-protocol.c example-ipso-temperature.c -PLATFORMS_EXCLUDE = sky +PLATFORMS_EXCLUDE = sky z1 all: $(CONTIKI_PROJECT) diff --git a/examples/multicast/Makefile b/examples/multicast/Makefile index 86c16e481..3e8a88d4a 100644 --- a/examples/multicast/Makefile +++ b/examples/multicast/Makefile @@ -3,8 +3,8 @@ all: $(CONTIKI_PROJECT) # nrf52dk only supports slave mode, i.e., with no routing PLATFORMS_EXCLUDE = nrf52dk -# does not fit sky motes -PLATFORMS_EXCLUDE += sky +# does not fit on sky and z1 motes +PLATFORMS_EXCLUDE += sky z1 CONTIKI = ../.. diff --git a/examples/platform-specific/cc26x0-cc13x0/Makefile b/examples/platform-specific/cc26x0-cc13x0/Makefile index 9962ab32a..bd9600c78 100644 --- a/examples/platform-specific/cc26x0-cc13x0/Makefile +++ b/examples/platform-specific/cc26x0-cc13x0/Makefile @@ -1,4 +1,4 @@ -CONTIKI_PROJECT = cc26xx-demo +CONTIKI_PROJECT = cc26x0-demo PLATFORMS_ONLY = cc26x0-cc13x0 diff --git a/examples/rpl-border-router/Makefile b/examples/rpl-border-router/Makefile index 4d2db2a85..8d210dd3c 100644 --- a/examples/rpl-border-router/Makefile +++ b/examples/rpl-border-router/Makefile @@ -3,7 +3,7 @@ all: $(CONTIKI_PROJECT) CONTIKI = ../.. # The BR is either native or embedded, and in the latter case must support SLIP -PLATFORMS_EXCLUDE = nrf52dk +PLATFORMS_EXCLUDE = nrf52dk z1 # Include RPL BR module MODULES += os/services/rpl-border-router diff --git a/examples/sensniff/Makefile b/examples/sensniff/Makefile index 3b7c5116c..78cb41a3e 100644 --- a/examples/sensniff/Makefile +++ b/examples/sensniff/Makefile @@ -1,7 +1,7 @@ CONTIKI_PROJECT = sensniff CONTIKI = ../.. -PLATFORMS_ONLY = cc2538dk openmote-cc2538 zoul cc26x0-cc13x0 jn516x simplelink +PLATFORMS_ONLY = cc2538dk openmote-cc2538 z1 zoul cc26x0-cc13x0 jn516x simplelink PROJECT_SOURCEFILES += sensniff-mac.c netstack.c MODULES_REL += pool $(TARGET) diff --git a/examples/sensniff/z1/target-conf.h b/examples/sensniff/z1/target-conf.h new file mode 100644 index 000000000..6e3db2b48 --- /dev/null +++ b/examples/sensniff/z1/target-conf.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 TARGET_CONF_H_ +#define TARGET_CONF_H_ +/*---------------------------------------------------------------------------*/ +#define MSP430_IO_CONF_USE_UART1 0 +#define UART0_CONF_BAUD_RATE 460800 +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_IO_DRIVER_H "pool/msp430-io.h" +/*---------------------------------------------------------------------------*/ +#endif /* TARGET_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/websocket/Makefile b/examples/websocket/Makefile index 87d0789c1..d0b38d95d 100644 --- a/examples/websocket/Makefile +++ b/examples/websocket/Makefile @@ -3,6 +3,6 @@ all: $(CONTIKI_PROJECT) CONTIKI=../.. MODULES += os/net/app-layer/http-socket -PLATFORMS_EXCLUDE = sky +PLATFORMS_EXCLUDE = sky z1 include $(CONTIKI)/Makefile.include diff --git a/tests/01-compile-base/Makefile b/tests/01-compile-base/Makefile index 09f89418d..51e68f9a2 100644 --- a/tests/01-compile-base/Makefile +++ b/tests/01-compile-base/Makefile @@ -6,6 +6,7 @@ hello-world/native \ hello-world/native:MAKE_NET=MAKE_NET_NULLNET \ hello-world/native:MAKE_ROUTING=MAKE_ROUTING_RPL_CLASSIC \ hello-world/sky \ +hello-world/z1 \ storage/eeprom-test/native \ libs/logging/native \ libs/energest/native \ @@ -30,6 +31,7 @@ mqtt-client/native \ coap/coap-example-client/native \ coap/coap-example-server/native \ coap/coap-plugtest-server/native \ +sensniff/z1 \ TOOLS= diff --git a/tests/07-simulation-base/07-hello-world-z1.csc b/tests/07-simulation-base/07-hello-world-z1.csc new file mode 100644 index 000000000..33963c36c --- /dev/null +++ b/tests/07-simulation-base/07-hello-world-z1.csc @@ -0,0 +1,83 @@ + + + + Hello World (Z1) + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Z1MoteType + z11 + Z1 Mote Type #z11 + [CONTIKI_DIR]/examples/hello-world/hello-world.c + make hello-world.z1 TARGET=z1 + [CONTIKI_DIR]/examples/hello-world/hello-world.z1 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 94.96401380574989 + 21.247662337471553 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + z11 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 38 + 13 + + + org.contikios.cooja.plugins.LogListener + + + + 680 + 1 + 240 + 109 + 377 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/hello-world.js + true + + 600 + 0 + 700 + 330 + 24 + + + diff --git a/tests/07-simulation-base/23-rpl-tsch-z1.csc b/tests/07-simulation-base/23-rpl-tsch-z1.csc new file mode 100644 index 000000000..f5a182ecd --- /dev/null +++ b/tests/07-simulation-base/23-rpl-tsch-z1.csc @@ -0,0 +1,206 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/powertracker + + RPL+TSCH (Z1) + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Z1MoteType + z11 + Z1 Mote Type #z11 + [CONTIKI_DIR]/examples/6tisch/simple-node/node.c + make TARGET=z1 clean + make -j node.z1 TARGET=z1 MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=0 MAKE_WITH_PERIODIC_ROUTES_PRINT=1 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + -1.285769821276336 + 38.58045647334346 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + z11 + + + + + org.contikios.cooja.interfaces.Position + -19.324109516886306 + 76.23135780254927 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 5.815501305791592 + 76.77463755494317 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 31.920697784030082 + 50.5212265977149 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 47.21747673247198 + 30.217765340599726 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 10.622284947035123 + 109.81862399725188 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + z11 + + + + org.contikios.cooja.plugins.SimControl + 242 + 4 + 160 + 11 + 241 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.7405603810040515 0.0 0.0 1.7405603810040515 47.95980153208088 -42.576134155447555 + + 236 + 3 + 230 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + ID:1 + + + + 1031 + 0 + 394 + 273 + 6 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + + + + 16529.88882215865 + + 1304 + 2 + 311 + 0 + 412 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 764 + 1 + 995 + 963 + 111 + + diff --git a/tests/07-simulation-base/hello-world.js b/tests/07-simulation-base/hello-world.js new file mode 100644 index 000000000..5afaabe18 --- /dev/null +++ b/tests/07-simulation-base/hello-world.js @@ -0,0 +1,9 @@ +TIMEOUT(5000); + +while(true) { + log.log("> " + msg + "\n"); + if (msg.equals('Hello, world')) { + log.testOK(); + } + YIELD(); +} diff --git a/tools/zolertia/license-bsl.txt b/tools/zolertia/license-bsl.txt new file mode 100644 index 000000000..e6775e9d7 --- /dev/null +++ b/tools/zolertia/license-bsl.txt @@ -0,0 +1,62 @@ +Copyright (c) 2001-2003 Chris Liechti + +All Rights Reserved. + +This is the Python license. In short, you can use this product in +commercial and non-commercial applications, modify it, redistribute it. +A notification to the author when you use and/or modify it is welcome. + +TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING THIS SOFTWARE +============================================ + +LICENSE AGREEMENT +----------------- + +1. This LICENSE AGREEMENT is between the copyright holder of this +product, and the Individual or Organization ("Licensee") accessing +and otherwise using this product in source or binary form and its +associated documentation. + +2. Subject to the terms and conditions of this License Agreement, +the copyright holder hereby grants Licensee a nonexclusive, +royalty-free, world-wide license to reproduce, analyze, test, +perform and/or display publicly, prepare derivative works, distribute, +and otherwise use this product alone or in any derivative version, +provided, however, that copyright holders License Agreement and +copyright holders notice of copyright are retained in this product +alone or in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates this product or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to this product. + +4. The copyright holder is making this product available to Licensee +on an "AS IS" basis. THE COPYRIGHT HOLDER MAKES NO REPRESENTATIONS +OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT +LIMITATION, THE COPYRIGHT HOLDER MAKES NO AND DISCLAIMS ANY +REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR +ANY PARTICULAR PURPOSE OR THAT THE USE OF THIS PRODUCT WILL +NOT INFRINGE ANY THIRD PARTY RIGHTS. + +5. THE COPYRIGHT HOLDER SHALL NOT BE LIABLE TO LICENSEE OR ANY +OTHER USERS OF THIS PRODUCT FOR ANY INCIDENTAL, SPECIAL, OR +CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, +DISTRIBUTING, OR OTHERWISE USING THIS PRODUCT, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY +THEREOF. + +6. This License Agreement will automatically terminate upon a +material breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between the +copyright holder and Licensee. This License Agreement does not grant +permission to use trademarks or trade names from the copyright holder +in a trademark sense to endorse or promote products or services of +Licensee, or any third party. + +8. By copying, installing or otherwise using this product, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. diff --git a/tools/zolertia/motelist-zolertia b/tools/zolertia/motelist-zolertia new file mode 100755 index 000000000..e5f7da99e --- /dev/null +++ b/tools/zolertia/motelist-zolertia @@ -0,0 +1,295 @@ +#!/usr/bin/perl -w +use strict; +# $Id: motelist-z1,v 1.1 2010/08/24 15:48:20 joxe Exp $ +# @author Cory Sharp +# @author Joe Polastre + +my $help = <<'EOF'; +usage: motelist [options] + + $Revision: 1.1 $ + +options: + -h display this help + -c compact format, not pretty but easier for parsing + -f specify the usb-serial file (for smote.cs) + -k kernel version: 2.4, 2.6, auto (default) + -m method to scan usb: procfs, sysfs, auto (default) + -dev_prefix force the device prefix for the serial device + -usb display extra usb information + -b specify which Zolertia board to list (z1, remote, etc) +EOF + +my %Opt = ( + compact => 0, + usb => 0, + board => "", + method => "auto", + kernel => "auto", + dev_prefix => [ "/dev/usb/tts/", "/dev/ttyUSB", "/dev/tts/USB" ], + usbserial => "sudo cat /proc/tty/driver/usbserial |", +); + +while (@ARGV) { + last unless $ARGV[0] =~ /^-/; + my $opt = shift @ARGV; + if( $opt eq "-h" ) { print "$help\n"; exit 0; } + elsif( $opt eq "-c" ) { $Opt{compact} = 1; } + elsif( $opt eq "-f" ) { $Opt{usbserial} = shift @ARGV; } + elsif( $opt eq "-k" ) { $Opt{kernel} = shift @ARGV; } + elsif( $opt eq "-m" ) { $Opt{method} = shift @ARGV; } + elsif( $opt eq "-dev_prefix" ) { $Opt{dev_prefix} = shift @ARGV; } + elsif( $opt eq "-usb" ) { $Opt{usb} = 1; } + elsif( $opt eq "-b" ) { $Opt{board} = shift @ARGV; } + else { print STDERR "$help\nerror, unknown command line option $opt\n"; exit 1; } +} + +if( $Opt{kernel} eq "auto" ) { + $Opt{kernel} = "unknown"; + $Opt{kernel} = $1 if snarf("/proc/version") =~ /\bLinux version (\d+\.\d+)/; +} + +if( $Opt{method} eq "auto" ) { + $Opt{method} = ($Opt{kernel} eq "2.4") ? "procfs" : "sysfs"; +} + +if( $Opt{board} eq "z1" ) { + $Opt{board} = "Zolertia Z1"; +} elsif( $Opt{board} eq "remote" ) { + $Opt{board} = "Zolertia RE-Mote platform"; +} elsif( $Opt{board} eq "firefly" ) { + $Opt{board} = "Zolertia Firefly platform"; +} elsif( $Opt{board} eq "orion" ) { + $Opt{board} = "Zolertia Orion Ethernet router"; +} + +my @devs = $Opt{method} eq "procfs" ? scan_procfs() : scan_sysfs(); +print_motelist( sort { cmp_usbdev($a,$b) } @devs ); + + +# +# SysFS +# +sub scan_sysfs { + + my $tmp = '($_->{UsbVendor}||"") eq "10c4" && ($_->{UsbProduct}||"") eq "ea60"'; + + if($Opt{board}) { + $tmp = '($_->{ProductString}||"") eq $Opt{board} && ' . $tmp + } + + # Scan /sys/bus/usb/drivers/usb for CP210x devices + my @cpdevs = + grep { eval "$tmp" } + map { { + SysPath => $_, + UsbVendor => snarf("$_/idVendor",1), + UsbProduct => snarf("$_/idProduct",1), + ProductString => snarf("$_/product",1), + } } + glob("/sys/bus/usb/drivers/usb/*"); + + # Gather information about each CP210x device + for my $f (@cpdevs) { + my $syspath = $f->{SysPath}; + $f->{InfoSerial} = snarf("$syspath/serial",1); + $f->{InfoManufacturer} = snarf("$syspath/manufacturer",1); + $f->{InfoProduct} = snarf("$syspath/product",1); + $f->{UsbDevNum} = snarf("$syspath/devnum",1); + + my $devstr = readlink($syspath); + if( $devstr =~ m{([^/]+)/usb(\d+)/.*-([^/]+)$} ) { + $f->{UsbPath} = "usb-$1-$3"; + $f->{UsbBusNum} = $2; + } + ($f->{SysDev} = $syspath) =~ s{^.*/}{}; + + my $port = "$syspath/$f->{SysDev}:1.0"; + ($f->{DriverName} = readlink("$port/driver")) =~ s{^.*/}{} if -l "$port/driver"; + ($f->{SerialDevName} = (glob("$port/tty*"),undef)[0]) =~ s{^.*/}{}; + $f->{SerialDevNum} = $1 if $f->{SerialDevName} =~ /(\d+)/; + $f->{SerialDevName} = getSerialDevName( $f->{SerialDevNum} ) || " (none)"; + } + return @cpdevs; +} + + +# +# Scan Procfs +# +sub scan_procfs { + + my $text_devs = snarf("< /proc/bus/usb/devices"); + my $text_serial = snarf($Opt{usbserial}); + + my @usbdevs = map { {parse_usb_devices_text($_)} } + grep { !/^\s*$/ } split /\n+(?=T:)/, $text_devs; + my %usbtree = build_usb_tree( @usbdevs ); + my %usbserialtree = build_usbserial_tree( $text_serial ); + for my $tts ( values %usbserialtree ) { + $usbtree{usbkey($tts->{path})}{usbserial} = $tts if defined $tts->{path}; + } + + my @cpdevs = map { { + UsbVendor => $_->{Vendor}, + UsbProduct => $_->{ProdID}, + InfoManufacturer => $_->{Manufacturer}, + InfoProduct => $_->{Product}, + InfoSerial => $_->{SerialNumber}, + UsbBusNum => $_->{nbus}, + UsbDevNum => $_->{ndev}, + UsbPath => (($Opt{kernel} eq "2.4") ? $_->{usbserial}{path} : $_->{usbpath}), + DriverName => $_->{driver}, + SerialDevNum => $_->{usbserial}{tts}, + SerialDevName => getSerialDevName($_->{usbserial}{tts}) || " (none)", + } } + grep { ($_->{Vendor}||"") eq "0403" && ($_->{ProdID}||"") eq "6001" } + values %usbtree; + + return @cpdevs; +} + +sub build_usb_tree { + my @devs = @_; + my %tree = (); + for my $dev (sort { $a->{Lev} <=> $b->{Lev} } @devs) { + my ($bus,$lev,$prnt) = ( $dev->{Bus}+0, $dev->{Lev}+0, $dev->{Prnt}+0 ); + my $devnum = $dev->{"Dev#"}+0; + $dev->{nbus} = $bus; + $dev->{ndev} = $devnum; + $tree{"bus$bus"} = {} unless exists $tree{"bus$bus"}; + $tree{"bus$bus"}{"dev$devnum"} = $dev; + if( $lev == 0 ) { + $dev->{usbpath} = "usb-$dev->{SerialNumber}"; + } else { + my $sep = ($lev==1) ? "-" : "."; + $dev->{parent} = $tree{"bus$bus"}{"dev$prnt"}; + $dev->{usbpath} = $dev->{parent}{usbpath} . $sep . ($dev->{Port}+1); + } + $tree{usbkey($dev->{usbpath})} = $dev; + } + return %tree; +} + +sub parse_usb_devices_text { + my $text = shift; + $text =~ s/^\S+\s*//gm; + return ($text =~ m/([^\s=]+)=\s*(.*?\S)\s*(?=[^\s=]+=|$)/mg); +} + +sub build_usbserial_tree { + my $text = shift; + my %tree = (); + while( $text =~ /^([^:]+):(.*)/mg ) { + my ($tts,$params) = ($1,$2); + $tree{$tts} = { tts => $tts }; + while ($params =~ m/\s+([^:]+):(?:"([^"]*)"|(\S+))/g) { + $tree{$tts}{$1} = $2||$3; + } + } + return %tree; +} + +sub usbkey { + if( $Opt{kernel} eq "2.4" ) { + (my $key = $_[0]) =~ s/^.*-//; + return $key; + } + return $_[0]; +} + + +# +# getSerialDevName +# +# For each device, force to use dev_prefix if it's not an array. Otherwise, +# assume it's a list of candidate prefixes. Check them and commit to the +# first one that actually exists. +# +sub getSerialDevName { + my $devnum = shift; + my $devname = undef; + if( defined $devnum ) { + if( ref($Opt{dev_prefix}) eq "ARRAY" ) { + $devname = $devnum; + for my $prefix (@{$Opt{dev_prefix}}) { + my $file = $prefix . $devnum; + if( -e $file ) { $devname = $file; last; } + } + } else { + $devname = $Opt{dev_prefix} . $devnum; + } + } + return $devname; +} + + +# +# Print motelist +# +sub print_motelist { + my @devs = @_; + + # If none were found, quit + if( @devs == 0 ) { + print "No devices found.\n"; + return; + } + + # Print a header + if( !$Opt{compact} ) { + if( $Opt{usb} ) { + print << "EOF" unless $Opt{compact}; +--- --- ------------------------ -------------- ---------------- ------------------------------------- +Bus Dev USB Path Reference Device Description +--- --- ------------------------ -------------- ---------------- ------------------------------------- +EOF + } else { + print << "EOF" unless $Opt{compact}; +-------------- ---------------- --------------------------------------------- +Reference Device Description +-------------- ---------------- --------------------------------------------- +EOF + } + } + + # Print the usb information + for my $dev (sort { cmp_usbdev($a,$b) } @devs) { + my $desc = join( " ", $dev->{InfoManufacturer}||"", $dev->{InfoProduct}||"" ) || " (none)"; + my @output = ( $dev->{InfoSerial}||" (none)", $dev->{SerialDevName}, $desc ); + @output = ( $dev->{UsbBusNum}, $dev->{UsbDevNum}, $dev->{UsbPath}, @output ) if $Opt{usb}; + if( $Opt{compact} ) { + print join(",",@output) . "\n"; + } else { + printf( ($Opt{usb}?"%3d %3d %-24s ":"")."%-14s %-16s %s\n", @output ); + } + } +} + + +# +# Cmp Usbdev's +# +sub cmp_usbdev { + my ($a,$b) = @_; + if( defined $a->{SerialDevNum} ) { + if( defined $b->{SerialDevNum} ) { + return $a->{SerialDevNum} <=> $b->{SerialDevNum}; + } + return -1; + } + return 1 if defined $b->{SerialDevNum}; + return ($a->{InfoSerial}||"") cmp ($b->{InfoSerial}||""); +} + +# +# Read a file in +# +sub snarf { + open my $fh, $_[0] or return undef; + my $text = do{local $/;<$fh>}; + close $fh; + $text =~ s/\s+$// if $_[1]; + return $text; +} + diff --git a/tools/zolertia/motelist-zolertia-macos b/tools/zolertia/motelist-zolertia-macos new file mode 100755 index 000000000..526b4887e --- /dev/null +++ b/tools/zolertia/motelist-zolertia-macos @@ -0,0 +1,75 @@ +#!/usr/bin/perl -w +use strict; + +my $help = <<'EOF'; +usage: motelist [options] + +options: + -h display this help + -c compact format, not pretty but easier for parsing +EOF + +my %Opt = ( + compact => 0, + dev_prefix => [ "/dev/tty.SLAB" ], +); + +while (@ARGV) { + last unless $ARGV[0] =~ /^-/; + my $opt = shift @ARGV; + if( $opt eq "-h" ) { print "$help\n"; exit 0; } + elsif( $opt eq "-c" ) { $Opt{compact} = 1; } + else { print STDERR "$help\nerror, unknown command line option $opt\n"; exit 1; } +} + +print_motelist( scan_dev() ); + +# +# Scan /dev for tty.SLAB* +# +sub scan_dev { + my @devs; + foreach (`ls /dev/tty.SLAB* 2>&1`) { + my($dev, $serial) = /(\/dev\/tty.SLAB(\S+))/; + if ($serial ne "*:") { + my $d; + $d->{"InfoSerial"} = $serial; + $d->{"SerialDevName"} = $dev; + push(@devs, $d); + } + } + return @devs; +} + + +# +# Print motelist +# +sub print_motelist { + my @devs = @_; + + # If none were found, quit + if( @devs == 0 ) { + #print "No devices found.\n"; + return; + } + + # Print a header + if( !$Opt{compact} ) { + print << "EOF" unless $Opt{compact}; +Reference Device Description +---------- --------------------------- --------------------------------------- +EOF + } + + # Print the usb information + for my $dev (@devs) { + my $desc = "(none)"; + my @output = ( $dev->{"InfoSerial"}, $dev->{"SerialDevName"}, $desc ); + if( $Opt{compact} ) { + print join(",",@output) . "\n"; + } else { + printf( "%-10s %-27s %s\n", @output ); + } + } +} diff --git a/tools/zolertia/z1-bsl b/tools/zolertia/z1-bsl new file mode 100755 index 000000000..31d58d1df --- /dev/null +++ b/tools/zolertia/z1-bsl @@ -0,0 +1,1929 @@ +#!/usr/bin/env python +# Serial Bootstrap Loader software for the MSP430 embedded proccessor. +# +# (C) 2001-2003 Chris Liechti +# this is distributed under a free software license, see license-bsl.txt +# +# fixes from Colin Domoney +# +# based on the application note slas96b.pdf from Texas Instruments, Inc., +# Volker Rzehak +# additional infos from slaa089a.pdf +# +# Forked by Travis Goodspeed for use with the GoodFET +# JTAG programmer. + +import sys, time, string, cStringIO, struct +sys.path.append("/usr/lib/tinyos") +import serial, os, glob + +#forked from TinyOS Telos version. +VERSION = string.split("Revision: 1.39-goodfet-8 z1 fork")[1] + +DEBUG = 0 #disable debug messages by default + +#copy of the patch file provided by TI +#this part is (C) by Texas Instruments +PATCH = """@0220 +31 40 1A 02 09 43 B0 12 2A 0E B0 12 BA 0D 55 42 +0B 02 75 90 12 00 1F 24 B0 12 BA 02 55 42 0B 02 +75 90 16 00 16 24 75 90 14 00 11 24 B0 12 84 0E +06 3C B0 12 94 0E 03 3C 21 53 B0 12 8C 0E B2 40 +10 A5 2C 01 B2 40 00 A5 28 01 30 40 42 0C 30 40 +76 0D 30 40 AC 0C 16 42 0E 02 17 42 10 02 E2 B2 +08 02 14 24 B0 12 10 0F 36 90 00 10 06 28 B2 40 +00 A5 2C 01 B2 40 40 A5 28 01 D6 42 06 02 00 00 +16 53 17 83 EF 23 B0 12 BA 02 D3 3F B0 12 10 0F +17 83 FC 23 B0 12 BA 02 D0 3F 18 42 12 02 B0 12 +10 0F D2 42 06 02 12 02 B0 12 10 0F D2 42 06 02 +13 02 38 E3 18 92 12 02 BF 23 E2 B3 08 02 BC 23 +30 41 +q +""" + +#These BSL's are (C) by TI. They come with the application note slaa089a +F1X_BSL = """@0220 +24 02 2E 02 31 40 20 02 2B D2 C0 43 EA FF 32 C2 +F2 C0 32 00 00 00 B2 40 80 5A 20 01 F2 40 85 00 +57 00 F2 40 80 00 56 00 E2 D3 21 00 E2 D3 22 00 +E2 C3 26 00 E2 C2 2A 00 E2 C2 2E 00 B2 40 10 A5 +2C 01 B2 40 00 A5 28 01 3B C0 3A 00 B0 12 D6 04 +82 43 12 02 09 43 36 40 0A 02 37 42 B0 12 AC 05 +C6 4C 00 00 16 53 17 83 F9 23 D2 92 0C 02 0D 02 +28 20 55 42 0B 02 75 90 12 00 80 24 75 90 10 00 +6D 24 B0 12 9C 04 55 42 0B 02 75 90 18 00 31 24 +75 90 1E 00 B8 24 75 90 20 00 17 24 2B B2 11 24 +75 90 16 00 22 24 75 90 14 00 B3 24 75 90 1A 00 +18 24 75 90 1C 00 45 24 04 3C B0 12 36 05 BE 3F +21 53 B0 12 3C 05 BA 3F 03 43 B0 12 36 05 D2 42 +0E 02 56 00 D2 42 0F 02 57 00 D2 42 10 02 16 02 +AD 3F B0 12 36 05 10 42 0E 02 16 42 0E 02 15 43 +07 3C 36 40 FE FF B2 40 06 A5 10 02 35 40 0C 00 +B2 40 00 A5 2C 01 92 42 10 02 28 01 B6 43 00 00 +92 B3 2C 01 FD 23 15 83 F3 23 36 90 FE FF CD 27 +37 40 80 00 36 F0 80 FF 36 90 00 11 0E 28 07 57 +36 F0 00 FF 36 90 00 12 08 28 07 57 36 F0 00 FE +04 3C 16 42 0E 02 17 42 10 02 35 43 75 96 03 20 +17 83 FC 23 B2 3F 82 46 00 02 B3 3F 36 40 E0 FF +37 40 20 00 B0 12 AC 05 7C 96 01 24 2B D3 17 83 +F9 23 2B C2 B0 12 9C 04 2B D2 9F 3F 16 42 0E 02 +17 42 10 02 2B B2 38 24 3B D0 10 00 B0 12 AC 05 +36 90 00 10 06 2C 36 90 00 01 09 2C C6 4C 00 00 +25 3C B2 40 00 A5 2C 01 B2 40 40 A5 28 01 16 B3 +03 20 C2 4C 14 02 1A 3C C2 4C 15 02 86 9A FD FF +08 24 2B D3 3B B0 20 00 04 20 3B D0 20 00 82 46 +00 02 36 90 01 02 04 28 3B D2 3B B0 10 00 02 24 +3B C0 32 00 1A 42 14 02 86 4A FF FF 16 53 17 83 +CD 23 B0 12 9C 04 61 3F B0 12 AC 05 17 83 FC 23 +B0 12 9C 04 5E 3F B2 40 F0 0F 0E 02 B2 40 10 00 +10 02 B2 40 80 00 0A 02 D2 42 10 02 0C 02 D2 42 +10 02 0D 02 82 43 12 02 09 43 36 40 0A 02 27 42 +7C 46 B0 12 40 05 17 83 FB 23 16 42 0E 02 17 42 +10 02 36 90 00 01 0A 28 B2 46 14 02 5C 42 14 02 +B0 12 40 05 17 83 5C 42 15 02 01 3C 7C 46 B0 12 +40 05 17 83 EE 23 B2 E3 12 02 5C 42 12 02 B0 12 +40 05 5C 42 13 02 B0 12 40 05 E0 3E 18 42 12 02 +B0 12 AC 05 C2 4C 12 02 B0 12 AC 05 C2 4C 13 02 +38 E3 3B B2 0A 24 86 9A FE FF 07 24 3B B0 20 00 +04 20 16 53 82 46 00 02 2B D3 18 92 12 02 08 23 +2B B3 06 23 30 41 E2 B2 28 00 FD 27 E2 B2 28 00 +FD 23 B2 40 24 02 60 01 E2 B2 28 00 FD 27 15 42 +70 01 05 11 05 11 05 11 82 45 02 02 05 11 82 45 +04 02 B2 80 1E 00 04 02 57 42 16 02 37 80 03 00 +05 11 05 11 17 53 FD 23 35 50 40 A5 82 45 2A 01 +35 42 B2 40 24 02 60 01 92 92 70 01 02 02 FC 2F +15 83 F7 23 09 43 7C 40 90 00 02 3C 7C 40 A0 00 +C2 43 07 02 C9 EC 12 02 19 E3 1B C3 55 42 07 02 +55 45 56 05 00 55 0C 2E 2E 2E 2E 2E 2E 2E 2E 1A +34 34 92 42 70 01 72 01 B2 50 0C 00 72 01 07 3C +1B B3 0B 20 82 43 62 01 92 B3 62 01 FD 27 E2 C3 +21 00 0A 3C 4C 11 F6 2B 1B E3 82 43 62 01 92 B3 +62 01 FD 27 E2 D3 21 00 92 52 02 02 72 01 D2 53 +07 02 F0 90 0C 00 61 FC D1 23 30 41 C2 43 09 02 +1B C3 55 42 09 02 55 45 BC 05 00 55 0C 56 56 56 +56 56 56 56 56 36 76 00 E2 B2 28 00 FD 23 92 42 +70 01 72 01 92 52 04 02 72 01 82 43 62 01 92 B3 +62 01 FD 27 E2 B2 28 00 1E 28 2B D3 1C 3C 4C 10 +1A 3C 82 43 62 01 92 B3 62 01 FD 27 E2 B2 28 00 +01 28 1B E3 1B B3 01 24 2B D3 C9 EC 12 02 19 E3 +0A 3C 82 43 62 01 92 B3 62 01 FD 27 E2 B2 28 00 +E6 2B 4C 10 1B E3 92 52 02 02 72 01 D2 53 09 02 +C0 3F 82 43 62 01 92 B3 62 01 FD 27 E2 B2 28 00 +01 2C 2B D3 30 41 +q +""" + +F4X_BSL = """@0220 +24 02 2E 02 31 40 20 02 2B D2 C0 43 EA FF 32 C2 +F2 C0 32 00 00 00 B2 40 80 5A 20 01 32 D0 40 00 +C2 43 50 00 F2 40 98 00 51 00 F2 C0 80 00 52 00 +D2 D3 21 00 D2 D3 22 00 D2 C3 26 00 E2 C3 22 00 +E2 C3 26 00 B2 40 10 A5 2C 01 B2 40 00 A5 28 01 +3B C0 3A 00 B0 12 DE 04 82 43 12 02 09 43 36 40 +0A 02 37 42 B0 12 B4 05 C6 4C 00 00 16 53 17 83 +F9 23 D2 92 0C 02 0D 02 28 20 55 42 0B 02 75 90 +12 00 80 24 75 90 10 00 6D 24 B0 12 A4 04 55 42 +0B 02 75 90 18 00 31 24 75 90 1E 00 B8 24 75 90 +20 00 17 24 2B B2 11 24 75 90 16 00 22 24 75 90 +14 00 B3 24 75 90 1A 00 18 24 75 90 1C 00 45 24 +04 3C B0 12 3E 05 BE 3F 21 53 B0 12 44 05 BA 3F +03 43 B0 12 3E 05 D2 42 0E 02 50 00 D2 42 0F 02 +51 00 D2 42 10 02 16 02 AD 3F B0 12 3E 05 10 42 +0E 02 16 42 0E 02 15 43 07 3C 36 40 FE FF B2 40 +06 A5 10 02 35 40 0C 00 B2 40 00 A5 2C 01 92 42 +10 02 28 01 B6 43 00 00 92 B3 2C 01 FD 23 15 83 +F3 23 36 90 FE FF CD 27 37 40 80 00 36 F0 80 FF +36 90 00 11 0E 28 07 57 36 F0 00 FF 36 90 00 12 +08 28 07 57 36 F0 00 FE 04 3C 16 42 0E 02 17 42 +10 02 35 43 75 96 03 20 17 83 FC 23 B2 3F 82 46 +00 02 B3 3F 36 40 E0 FF 37 40 20 00 B0 12 B4 05 +7C 96 01 24 2B D3 17 83 F9 23 2B C2 B0 12 A4 04 +2B D2 9F 3F 16 42 0E 02 17 42 10 02 2B B2 38 24 +3B D0 10 00 B0 12 B4 05 36 90 00 10 06 2C 36 90 +00 01 09 2C C6 4C 00 00 25 3C B2 40 00 A5 2C 01 +B2 40 40 A5 28 01 16 B3 03 20 C2 4C 14 02 1A 3C +C2 4C 15 02 86 9A FD FF 08 24 2B D3 3B B0 20 00 +04 20 3B D0 20 00 82 46 00 02 36 90 01 02 04 28 +3B D2 3B B0 10 00 02 24 3B C0 32 00 1A 42 14 02 +86 4A FF FF 16 53 17 83 CD 23 B0 12 A4 04 61 3F +B0 12 B4 05 17 83 FC 23 B0 12 A4 04 5E 3F B2 40 +F0 0F 0E 02 B2 40 10 00 10 02 B2 40 80 00 0A 02 +D2 42 10 02 0C 02 D2 42 10 02 0D 02 82 43 12 02 +09 43 36 40 0A 02 27 42 7C 46 B0 12 48 05 17 83 +FB 23 16 42 0E 02 17 42 10 02 36 90 00 01 0A 28 +B2 46 14 02 5C 42 14 02 B0 12 48 05 17 83 5C 42 +15 02 01 3C 7C 46 B0 12 48 05 17 83 EE 23 B2 E3 +12 02 5C 42 12 02 B0 12 48 05 5C 42 13 02 B0 12 +48 05 E0 3E 18 42 12 02 B0 12 B4 05 C2 4C 12 02 +B0 12 B4 05 C2 4C 13 02 38 E3 3B B2 0A 24 86 9A +FE FF 07 24 3B B0 20 00 04 20 16 53 82 46 00 02 +2B D3 18 92 12 02 08 23 2B B3 06 23 30 41 E2 B3 +20 00 FD 27 E2 B3 20 00 FD 23 B2 40 24 02 60 01 +E2 B3 20 00 FD 27 15 42 70 01 05 11 05 11 05 11 +82 45 02 02 05 11 82 45 04 02 B2 80 1E 00 04 02 +57 42 16 02 37 80 03 00 05 11 05 11 17 53 FD 23 +35 50 40 A5 82 45 2A 01 35 42 B2 40 24 02 60 01 +92 92 70 01 02 02 FC 2F 15 83 F7 23 09 43 7C 40 +90 00 02 3C 7C 40 A0 00 C2 43 07 02 C9 EC 12 02 +19 E3 1B C3 55 42 07 02 55 45 5E 05 00 55 0C 2E +2E 2E 2E 2E 2E 2E 2E 1A 34 34 92 42 70 01 72 01 +B2 50 0C 00 72 01 07 3C 1B B3 0B 20 82 43 62 01 +92 B3 62 01 FD 27 D2 C3 21 00 0A 3C 4C 11 F6 2B +1B E3 82 43 62 01 92 B3 62 01 FD 27 D2 D3 21 00 +92 52 02 02 72 01 D2 53 07 02 F0 90 0C 00 59 FC +D1 23 30 41 C2 43 09 02 1B C3 55 42 09 02 55 45 +C4 05 00 55 0C 56 56 56 56 56 56 56 56 36 76 00 +E2 B3 20 00 FD 23 92 42 70 01 72 01 92 52 04 02 +72 01 82 43 62 01 92 B3 62 01 FD 27 E2 B3 20 00 +1E 28 2B D3 1C 3C 4C 10 1A 3C 82 43 62 01 92 B3 +62 01 FD 27 E2 B3 20 00 01 28 1B E3 1B B3 01 24 +2B D3 C9 EC 12 02 19 E3 0A 3C 82 43 62 01 92 B3 +62 01 FD 27 E2 B3 20 00 E6 2B 4C 10 1B E3 92 52 +02 02 72 01 D2 53 09 02 C0 3F 82 43 62 01 92 B3 +62 01 FD 27 E2 B3 20 00 01 2C 2B D3 30 41 +q +""" + +CALIB_TABLES = """ +84 C0 16 FE FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF 10 08 80 00 00 01 +7E 27 0B 79 0D AA 7E 4D 06 DF 08 33 08 FE FF FF +FF FF FF FF FF FF 08 01 8F 95 8E 9A 8D 88 86 D1 +""" + +#cpu types for "change baudrate" +#use strings as ID so that they can be used in outputs too +F1x = "F1x family" +F2x = "F2x family" +F4x = "F4x family" + +#known device list +deviceids = { + 0xf149: F1x, + 0xf16c: F1x, #for GoodFET10 to '20 + 0xf112: F1x, + 0xf413: F4x, + 0xf123: F1x, + 0xf449: F4x, + 0x1232: F1x, + 0xf26f: F2x, #for GoodFET20 + 0xf227: F2x, #for GoodFET30 +} + +#GoodFET firmware +firmware = { + 0xf16c: "http://goodfet.sourceforge.net/dist/msp430x1612.hex", + 0xf26f: "http://goodfet.sourceforge.net/dist/msp430x2618.hex", + 0xf227: "http://goodfet.sourceforge.net/dist/msp430x2274.hex" +} + +class BSLException(Exception): + pass + +class LowLevel: + "lowlevel communication" + #Constants + MODE_SSP = 0 + MODE_BSL = 1 + + BSL_SYNC = 0x80 + BSL_TXPWORD = 0x10 + BSL_TXBLK = 0x12 #Transmit block to boot loader + BSL_UNLOCK_INFO = 0x12 #unlocks / locks info segment A Not working on msp430f2617 + BSL_RXBLK = 0x14 #Receive block from boot loader + BSL_ERASE = 0x16 #Erase one segment + BSL_MERAS = 0x18 #Erase complete FLASH memory + BSL_CHANGEBAUD = 0x20 #Change baudrate + BSL_LOADPC = 0x1A #Load PC and start execution + BSL_TXVERSION = 0x1E #Get BSL version + + #Upper limit of address range that might be modified by + #"BSL checksum bug". + BSL_CRITICAL_ADDR = 0x0A00 + + #Header Definitions + CMD_FAILED = 0x70 + DATA_FRAME = 0x80 + DATA_ACK = 0x90 + DATA_NAK = 0xA0 + + QUERY_POLL = 0xB0 + QUERY_RESPONSE = 0x50 + + OPEN_CONNECTION = 0xC0 + ACK_CONNECTION = 0x40 + + DEFAULT_TIMEOUT = 1 + DEFAULT_PROLONG = 10 + MAX_FRAME_SIZE = 256 + MAX_DATA_BYTES = 250 + MAX_DATA_WORDS = 125 + + MAX_FRAME_COUNT = 16 + + #Error messages + ERR_COM = "Unspecific error" + ERR_RX_NAK = "NAK received (wrong password?)" + #ERR_CMD_NOT_COMPLETED = "Command did not send ACK: indicates that it didn't complete correctly" + ERR_CMD_FAILED = "Command failed, is not defined or is not allowed" + ERR_BSL_SYNC = "Bootstrap loader synchronization error" + ERR_FRAME_NUMBER = "Frame sequence number error." + + def calcChecksum(self, data, length): + """Calculates a checksum of "data".""" + checksum = 0 + + for i in range(length/2): + checksum = checksum ^ (ord(data[i*2]) | (ord(data[i*2+1]) << 8)) #xor-ing + return 0xffff & (checksum ^ 0xffff) #inverting + + def __init__(self, aTimeout = None, aProlongFactor = None): + """init bsl object, don't connect yet""" + if aTimeout is None: + self.timeout = self.DEFAULT_TIMEOUT + else: + self.timeout = aTimeout + if aProlongFactor is None: + self.prolongFactor = self.DEFAULT_PROLONG + else: + self.prolongFactor = aProlongFactor + + #flags for inverted use of control pins + #used for some hardware + self.invertRST = 0 + self.invertTEST = 0 + self.swapRSTTEST = 0 + self.telosLatch = 0 + self.telosI2C = 0 + + self.z1 = 0 + + self.protocolMode = self.MODE_BSL + self.BSLMemAccessWarning = 0 #Default: no warning. + self.slowmode = 0 + + def comInit(self, port): + """Tries to open the serial port given and + initialises the port and variables. + The timeout and the number of allowed errors is multiplied by + 'aProlongFactor' after transmission of a command to give + plenty of time to the micro controller to finish the command. + Returns zero if the function is successful.""" + if DEBUG > 1: sys.stderr.write("* comInit()\n") + self.seqNo = 0 + self.reqNo = 0 + self.rxPtr = 0 + self.txPtr = 0 + # Startup-Baudrate: 9600,8,E,1, 1s timeout + self.serialport = serial.Serial( + port, + 9600, + parity = serial.PARITY_EVEN, + timeout = self.timeout + ) + if DEBUG: sys.stderr.write("using serial port %r\n" % self.serialport.portstr) + #self.SetRSTpin() #enable power + #self.SetTESTpin() #enable power + self.serialport.flushInput() + self.serialport.flushOutput() + + def comDone(self): + """Closes the used serial port. + This function must be called at the end of a program, + otherwise the serial port might not be released and can not be + used in other programs. + Returns zero if the function is successful.""" + if DEBUG > 1: sys.stderr.write("* comDone()") + self.SetRSTpin(1) #disable power + self.SetTESTpin(0) #disable power + self.serialport.close() + + def comRxHeader(self): + """receive header and split data""" + if DEBUG > 1: sys.stderr.write("* comRxHeader()\n") + + hdr = self.serialport.read(1) + if not hdr: raise BSLException("Timeout") + rxHeader = ord(hdr) & 0xf0; + rxNum = ord(hdr) & 0x0f; + + if self.protocolMode == self.MODE_BSL: + self.reqNo = 0 + self.seqNo = 0 + rxNum = 0 + if DEBUG > 1: sys.stderr.write("* comRxHeader() OK\n") + return rxHeader, rxNum + + def comRxFrame(self, rxNum): + if DEBUG > 1: sys.stderr.write("* comRxFrame()\n") + rxFrame = chr(self.DATA_FRAME | rxNum) + + if DEBUG > 2: sys.stderr.write(" comRxFrame() header...\n") + rxFramedata = self.serialport.read(3) + if len(rxFramedata) != 3: raise BSLException("Timeout") + rxFrame = rxFrame + rxFramedata + + if DEBUG > 3: sys.stderr.write(" comRxFrame() check header...\n") + if rxFrame[1] == chr(0) and rxFrame[2] == rxFrame[3]: #Add. header info. correct? + rxLengthCRC = ord(rxFrame[2]) + 2 #Add CRC-Bytes to length + if DEBUG > 2: sys.stderr.write(" comRxFrame() receiving data, size: %s\n" % rxLengthCRC) + + rxFramedata = self.serialport.read(rxLengthCRC) + if len(rxFramedata) != rxLengthCRC: raise BSLException("Timeout") + rxFrame = rxFrame + rxFramedata + #Check received frame: + if DEBUG > 3: sys.stderr.write(" comRxFrame() crc check\n") + #rxLength+4: Length with header but w/o CRC: + checksum = self.calcChecksum(rxFrame, ord(rxFrame[2]) + 4) + if rxFrame[ord(rxFrame[2])+4] == chr(0xff & checksum) and \ + rxFrame[ord(rxFrame[2])+5] == chr(0xff & (checksum >> 8)): #Checksum correct? + #Frame received correctly (=> send next frame) + if DEBUG > 2: sys.stderr.write("* comRxFrame() OK\n") + return rxFrame + else: + if DEBUG: sys.stderr.write(" comRxFrame() Checksum wrong\n") + else: + if DEBUG: sys.stderr.write(" comRxFrame() Header corrupt %r" % rxFrame) + raise BSLException(self.ERR_COM) #Frame has errors! + + def comTxHeader(self, txHeader): + """send header""" + if DEBUG > 1: sys.stderr.write("* txHeader()\n") + self.serialport.write(txHeader) + + def comTxRx(self, cmd, dataOut, length): + """Sends the command cmd with the data given in dataOut to the + microcontroller and expects either an acknowledge or a frame + with result from the microcontroller. The results are stored + in dataIn (if not a NULL pointer is passed). + In this routine all the necessary protocol stuff is handled. + Returns zero if the function was successful.""" + if DEBUG > 1: sys.stderr.write("* comTxRx()\n") + txFrame = [] + rxHeader = 0 + rxNum = 0 + + dataOut = list(dataOut) #convert to a list for simpler data fill in + #Transmitting part ---------------------------------------- + #Prepare data for transmit + if (length % 2) != 0: + #/* Fill with one byte to have even number of bytes to send */ + if self.protocolMode == self.MODE_BSL: + dataOut.append(0xFF) #fill with 0xFF + else: + dataOut.append(0) #fill with zero + + txFrame = "%c%c%c%c" % (self.DATA_FRAME | self.seqNo, cmd, len(dataOut), len(dataOut)) + + self.reqNo = (self.seqNo + 1) % self.MAX_FRAME_COUNT + + txFrame = txFrame + string.join(dataOut,'') + checksum = self.calcChecksum(txFrame, length + 4) + txFrame = txFrame + chr(checksum & 0xff) + txFrame = txFrame + chr((checksum >> 8) & 0xff) + + accessAddr = (0x0212 + (checksum^0xffff)) & 0xfffe #0x0212: Address of wCHKSUM + if self.BSLMemAccessWarning and accessAddr < self.BSL_CRITICAL_ADDR: + sys.stderr.write("WARNING: This command might change data at address %04x or %04x!\n" % (accessAddr, accessAddr + 1)) + + self.serialport.flushInput() #clear receiving queue + #TODO: Check after each transmitted character, + #TODO: if microcontroller did send a character (probably a NAK!). + for c in txFrame: + self.serialport.write(c) + if DEBUG > 3: sys.stderr.write("\ttx %02x" % ord(c)) + #if self.serialport.inWaiting(): break #abort when BSL replies, probably NAK + else: + if DEBUG > 1: sys.stderr.write( " comTxRx() transmit OK\n") + + #Receiving part ------------------------------------------- + rxHeader, rxNum = self.comRxHeader() #receive header + if DEBUG > 1: sys.stderr.write(" comTxRx() rxHeader=0x%02x, rxNum=%d, seqNo=%d, reqNo=%s\n" % (rxHeader, rxNum, self.seqNo, self.reqNo)) + if rxHeader == self.DATA_ACK: #acknowledge/OK + if DEBUG > 2: sys.stderr.write(" comTxRx() DATA_ACK\n") + if rxNum == self.reqNo: + self.seqNo = self.reqNo + if DEBUG > 2: sys.stderr.write("* comTxRx() DATA_ACK OK\n") + return #Acknowledge received correctly => next frame + raise BSLException(self.ERR_FRAME_NUMBER) + elif rxHeader == self.DATA_NAK: #not acknowledge/error + if DEBUG > 2: sys.stderr.write("* comTxRx() DATA_NAK\n") + raise BSLException(self.ERR_RX_NAK) + elif rxHeader == self.DATA_FRAME: #receive data + if DEBUG > 2: sys.stderr.write("* comTxRx() DATA_FRAME\n") + if rxNum == self.reqNo: + rxFrame = self.comRxFrame(rxNum) + return rxFrame + raise BSLException(self.ERR_FRAME_NUMBER) + elif rxHeader == self.CMD_FAILED: #Frame ok, but command failed. + if DEBUG > 2: sys.stderr.write("* comTxRx() CMD_FAILED\n") + raise BSLException(self.ERR_CMD_FAILED) + + raise BSLException("Unknown header 0x%02x\nAre you downloading to RAM into an old device that requires the patch? Try option -U" % rxHeader) + + def SetDTR(self, level, invert): + """Controls DTR pin (0: GND; 1: VCC; unless inverted flag is set)""" + #print 'fucking the dtr' + if invert: + self.serialport.setDTR(not level) + else: + self.serialport.setDTR(level) + if self.slowmode: + time.sleep(0.040) + + def SetRTS(self, level, invert): + """Controls RTS pin (0: GND; 1: VCC; unless inverted flag is set)""" + if invert: + self.serialport.setRTS(not level) + else: + self.serialport.setRTS(level) + if self.slowmode: + time.sleep(0.040) + + def SetRSTpin(self, level=1): + """Controls RST/NMI pin (0: GND; 1: VCC; unless inverted flag is set)""" + if self.swapRSTTEST: + self.SetRTS(level, self.invertRST) + else: + self.SetDTR(level, self.invertRST) + + def SetTESTpin(self, level=1): + """Controls TEST pin (inverted on board: 0: VCC; 1: GND; unless inverted flag is set)""" + if self.swapRSTTEST: + self.SetDTR(level, self.invertTEST) + else: + self.SetRTS(level, self.invertTEST) + + + def writepicROM(self, address, data): + ''' Writes data to @address''' + for i in range(7,-1,-1): + self.picROMclock((address >> i) & 0x01) + self.picROMclock(0) + recbuf = 0 + for i in range(7,-1,-1): + s = ((data >> i) & 0x01) + #print s + if i < 1: + r = not self.picROMclock(s, True) + else: + r = not self.picROMclock(s) + recbuf = (recbuf << 1) + r + + self.picROMclock(0, True) + #k = 1 + #while not self.serial.getCTS(): + # pass + #time.sleep(0.1) + return recbuf + + def readpicROM(self, address): + ''' reads a byte from @address''' + for i in range(7,-1,-1): + self.picROMclock((address >> i) & 0x01) + self.picROMclock(1) + recbuf = 0 + r = 0 + for i in range(7,-1,-1): + r = self.picROMclock(0) + recbuf = (recbuf << 1) + r + self.picROMclock(r) + #time.sleep(0.1) + return recbuf + + def picROMclock(self, masterout, slow = False): + #print "setting masterout to "+str(masterout) + self.serialport.setRTS(masterout) + self.serialport.setDTR(1) + #time.sleep(0.02) + self.serialport.setDTR(0) + if slow: + time.sleep(0.02) + return self.serialport.getCTS() + + def picROMfastclock(self, masterout): + #print "setting masterout to "+str(masterout) + self.serialport.setRTS(masterout) + self.serialport.setDTR(1) + self.serialport.setDTR(0) + time.sleep(0.02) + return self.serialport.getCTS() + + def bslResetZ1(self, invokeBSL=0): + ''' + Applies BSL entry sequence on RST/NMI and TEST/VPP pins + Parameters: + invokeBSL = 1: complete sequence + invokeBSL = 0: only RST/NMI pin accessed + + By now only BSL mode is accessed + ''' + + if DEBUG > 1: sys.stderr.write("* bslReset(invokeBSL=%s)\n" % invokeBSL) + if invokeBSL: + #sys.stderr.write("in Z1 bsl reset...\n") + time.sleep(0.1) + self.writepicROM(0xFF, 0xFF) + time.sleep(0.1) + #sys.stderr.write("z1 bsl reset done...\n") + else: + #sys.stderr.write("in Z1 reset...\n") + time.sleep(0.1) + self.writepicROM(0xFF, 0xFE) + time.sleep(0.1) + #sys.stderr.write("z1 reset done...\n") + + def telosSetSCL(self, level): + self.serialport.setRTS(not level) + + def telosSetSDA(self, level): + self.serialport.setDTR(not level) + + def telosI2CStart(self): + self.telosSetSDA(1) + self.telosSetSCL(1) + self.telosSetSDA(0) + + def telosI2CStop(self): + self.telosSetSDA(0) + self.telosSetSCL(1) + self.telosSetSDA(1) + + def telosI2CWriteBit(self, bit): + self.telosSetSCL(0) + self.telosSetSDA(bit) + time.sleep(2e-6) + self.telosSetSCL(1) + time.sleep(1e-6) + self.telosSetSCL(0) + + def telosI2CWriteByte(self, byte): + self.telosI2CWriteBit( byte & 0x80 ); + self.telosI2CWriteBit( byte & 0x40 ); + self.telosI2CWriteBit( byte & 0x20 ); + self.telosI2CWriteBit( byte & 0x10 ); + self.telosI2CWriteBit( byte & 0x08 ); + self.telosI2CWriteBit( byte & 0x04 ); + self.telosI2CWriteBit( byte & 0x02 ); + self.telosI2CWriteBit( byte & 0x01 ); + self.telosI2CWriteBit( 0 ); # "acknowledge" + + def telosI2CWriteCmd(self, addr, cmdbyte): + self.telosI2CStart() + self.telosI2CWriteByte( 0x90 | (addr << 1) ) + self.telosI2CWriteByte( cmdbyte ) + self.telosI2CStop() + + def telosBReset(self,invokeBSL=0): + # "BSL entry sequence at dedicated JTAG pins" + # rst !s0: 0 0 0 0 1 1 + # tck !s1: 1 0 1 0 0 1 + # s0|s1: 1 3 1 3 2 0 + + # "BSL entry sequence at shared JTAG pins" + # rst !s0: 0 0 0 0 1 1 + # tck !s1: 0 1 0 1 1 0 + # s0|s1: 3 1 3 1 0 2 + if invokeBSL: + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + self.telosI2CWriteCmd(0,0) + else: + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + self.telosI2CWriteCmd(0,0) + time.sleep(0.250) #give MSP430's oscillator time to stabilize + self.serialport.flushInput() #clear buffers + + def bslReset(self, invokeBSL=0): + """Applies BSL entry sequence on RST/NMI and TEST/VPP pins + Parameters: + invokeBSL = 1: complete sequence + invokeBSL = 0: only RST/NMI pin accessed + + RST is inverted twice on boot loader hardware + TEST is inverted (only once) + Need positive voltage on DTR, RTS for power-supply of hardware""" + + #print 'goint to reset!' + + if self.telosI2C: + self.telosBReset(invokeBSL) + return + + if self.z1: + if DEBUG > 1: sys.stderr.write("* entering bsl with z1\n") + self.bslResetZ1(invokeBSL) + return + + if DEBUG > 1: sys.stderr.write("* bslReset(invokeBSL=%s)\n" % invokeBSL) + self.SetRSTpin(1) #power suply + self.SetTESTpin(1) #power suply + time.sleep(0.250) #charge capacitor on boot loader hardware + + if self.telosLatch: + self.SetTESTpin(0) + self.SetRSTpin(0) + self.SetTESTpin(1) + + self.SetRSTpin(0) #RST pin: GND + if invokeBSL: + self.SetTESTpin(1) #TEST pin: GND + self.SetTESTpin(0) #TEST pin: Vcc + self.SetTESTpin(1) #TEST pin: GND + self.SetTESTpin(0) #TEST pin: Vcc + self.SetRSTpin (1) #RST pin: Vcc + self.SetTESTpin(1) #TEST pin: GND + else: + self.SetRSTpin(1) #RST pin: Vcc + time.sleep(0.250) #give MSP430's oscillator time to stabilize + + self.serialport.flushInput() #clear buffers + + def bslSync(self,wait=0): + """Transmits Synchronization character and expects to receive Acknowledge character + if wait is 0 it must work the first time. otherwise if wait is 1 + it is retried (forever). + """ + loopcnt = 5 #Max. tries to get synchronization + + if DEBUG > 1: sys.stderr.write("* bslSync(wait=%d)\n" % wait) + while wait or loopcnt: + loopcnt = loopcnt - 1 #count down tries + self.serialport.flushInput() #clear input, in case a prog is running + + self.serialport.write(chr(self.BSL_SYNC)) #Send synchronization byte + c = self.serialport.read(1) #read answer + if c == chr(self.DATA_ACK): #ACk + if DEBUG > 1: sys.stderr.write(" bslSync() OK\n") + return #Sync. successful + elif not c: #timeout + if loopcnt > 4: + if DEBUG > 1: + sys.stderr.write(" bslSync() timeout, retry ...\n") + elif loopcnt == 4: + #nmi may have caused the first reset to be ignored, try again + self.bslReset(0) + self.bslReset(1) + elif loopcnt > 0: + if DEBUG > 1: + sys.stderr.write(" bslSync() timeout, retry ...\n") + else : + if DEBUG > 1: + sys.stderr.write(" bslSync() timeout\n") + else: #garbage + if DEBUG > 1: sys.stderr.write(" bslSync() failed (0x%02x), retry ...\n" % ord(c)) + + raise BSLException(self.ERR_BSL_SYNC) #Sync. failed + + def bslTxRx(self, cmd, addr, length = 0, blkout = None, wait=0): + """Transmits a command (cmd) with its parameters: + start-address (addr), length (len) and additional + data (blkout) to boot loader. + wait specified if the bsl sync should be tried once or + repeated, forever + Parameters return by boot loader are passed via blkin. + """ + if DEBUG > 1: sys.stderr.write("* bslTxRx()\n") + + if cmd == self.BSL_TXBLK: + #Align to even start address + if (addr % 2) != 0: + addr = addr - 1 #Decrement address and + blkout = chr(0xFF) + blkOut #fill first byte of blkout with 0xFF + length = length + 1 + #Make sure that len is even + if (length % 2) != 0: + blkout = blkout + chr(0xFF) #Inc. len and fill last byte of blkout with 0xFF + length = length + 1 + + elif cmd == self.BSL_RXBLK: + #Align to even start address + if (addr % 2) != 0: + addr = addr - 1 #Decrement address but + length = length + 1 #request an additional byte + #Make sure that len is even + if (length % 2) != 0: + length = length + 1 + + #if cmd == self.BSL_TXBLK or cmd == self.BSL_TXPWORD: + # length = len + 4 + + #Add necessary information data to frame + dataOut = struct.pack("= 1: + #Read one line + l = file.readline() + if not l: break #EOF + l = l.strip() + if l[0] == 'q': break + elif l[0] == '@': #if @ => new address => send frame and set new addr. + #create a new segment + if segmentdata: + self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) + startAddr = int(l[1:],16) + segmentdata = [] + else: + for i in string.split(l): + segmentdata.append(chr(int(i,16))) + if segmentdata: + self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) + + def loadELF(self, file): + """load data from a (opened) file in ELF object format. + File must be seekable""" + import elf + obj = elf.ELFObject() + obj.fromFile(file) + if obj.e_type != elf.ELFObject.ET_EXEC: + raise Exception("No executable") + for section in obj.getSections(): + if DEBUG: + sys.stderr.write("ELF section %s at 0x%04x %d bytes\n" % (section.name, section.lma, len(section.data))) + if len(section.data): + self.segments.append( Segment(section.lma, section.data) ) + + def loadFile(self, filename): + """fill memory with the contents of a file. file type is determined from extension""" + #TODO: do a contents based detection + if filename[-4:].lower() == '.txt': + self.loadTIText(open(filename, "rb")) + elif filename[-4:].lower() in ('.a43', '.hex'): + self.loadIHex(open(filename, "rb")) + else: + self.loadELF(open(filename, "rb")) + + def getMemrange(self, fromadr, toadr): + """get a range of bytes from the memory. unavailable values are filled with 0xff.""" + res = '' + toadr = toadr + 1 #python indxes are excluding end, so include it + while fromadr < toadr: + #print "fromto: %04x %04x" % (fromadr, toadr) + for seg in self.segments: + #print seg + segend = seg.startaddress + len(seg.data) + if seg.startaddress <= fromadr and fromadr < segend: + #print "startok 0x%04x %d" % (seg.startaddress, len(seg.data)) + #print ("0x%04x "*3) % (segend, fromadr, toadr) + if toadr > segend: #not all data in segment + #print "out of segment" + catchlength = segend-fromadr + else: + catchlength = toadr-fromadr + #print toadr-fromadr + #print catchlength + res = res + seg.data[fromadr-seg.startaddress : fromadr-seg.startaddress+catchlength] + fromadr = fromadr + catchlength #adjust start + if len(res) >= toadr-fromadr: + break#return res + else: + res = res + chr(255) + fromadr = fromadr + 1 #adjust start + #print "fill FF" + #print "res: %r" % res + return res + + +class BootStrapLoader(LowLevel): + """higher level Bootstrap Loader functions.""" + + ERR_VERIFY_FAILED = "Error: verification failed" + ERR_ERASE_CHECK_FAILED = "Error: erase check failed" + + ACTION_PROGRAM = 0x01 #Mask: program data + ACTION_VERIFY = 0x02 #Mask: verify data + ACTION_ERASE_CHECK = 0x04 #Mask: erase check + + #Max. bytes sent within one frame if parsing a TI TXT file. + #( >= 16 and == n*16 and <= MAX_DATA_BYTES!) + MAXDATA = 240-16 + + + def __init__(self, *args, **kargs): + LowLevel.__init__(self, *args, **kargs) + self.byteCtr = 0 + self.meraseCycles = 1 + self.patchRequired = 0 + self.patchLoaded = 0 + self.bslVer = 0 + self.passwd = None + self.data = None + self.maxData = self.MAXDATA + self.cpu = None + self.pwdsent = False + + + def preparePatch(self): + """prepare to download patch""" + if DEBUG > 1: sys.stderr.write("* preparePatch()\n") + + if self.patchLoaded: + #Load PC with 0x0220. + #This will invoke the patched bootstrap loader subroutines. + self.bslTxRx(self.BSL_LOADPC, #Command: Load PC + 0x0220) #Address to load into PC + self.BSLMemAccessWarning = 0 #Error is removed within workaround code + return + + def postPatch(self): + """setup after the patch is loaded""" + if DEBUG > 1: sys.stderr.write("* postPatch()\n") + if self.patchLoaded: + self.BSLMemAccessWarning = 1 #Turn warning back on. + + + def verifyBlk(self, addr, blkout, action): + """verify memory against data or 0xff""" + if DEBUG > 1: sys.stderr.write("* verifyBlk()\n") + + if action & self.ACTION_VERIFY or action & self.ACTION_ERASE_CHECK: + if DEBUG: sys.stderr.write(" Check starting at 0x%04x, %d bytes ... \n" % (addr, len(blkout))) + + self.preparePatch() + blkin = self.bslTxRx(self.BSL_RXBLK, addr, len(blkout)) + self.postPatch() + + for i in range(len(blkout)): + if action & self.ACTION_VERIFY: + #Compare data in blkout and blkin + if blkin[i] != blkout[i]: + sys.stderr.write("Verification failed at 0x%04x (0x%02x, 0x%02x)\n" % (addr+i, ord(blkin[i]), ord(blkout[i]))) + sys.stderr.flush() + raise BSLException(self.ERR_VERIFY_FAILED) #Verify failed! + continue + elif action & self.ACTION_ERASE_CHECK: + #Compare data in blkin with erase pattern + if blkin[i] != chr(0xff): + sys.stderr.write("Erase Check failed at 0x%04x (0x%02x)\n" % (addr+i, ord(blkin[i]))) + sys.stderr.flush() + raise BSLException(self.ERR_ERASE_CHECK_FAILED) #Erase Check failed! + continue + def readBlk(self,adr,len): + """Read a block of memory.""" + blkin = self.bslTxRx(self.BSL_RXBLK, addr, len(blkout)) + + def programBlk(self, addr, blkout, action): + """program a memory block""" + if DEBUG > 1: sys.stderr.write("* programBlk()\n") + + #Check, if specified range is erased + self.verifyBlk(addr, blkout, action & self.ACTION_ERASE_CHECK) + + if action & self.ACTION_PROGRAM: + if DEBUG: sys.stderr.write(" Program starting at 0x%04x, %i bytes ...\n" % (addr, len(blkout))) + self.preparePatch() + #Program block + self.bslTxRx(self.BSL_TXBLK, addr, len(blkout), blkout) + self.postPatch() + + #Verify block + self.verifyBlk(addr, blkout, action & self.ACTION_VERIFY) + + #segments: + #list of tuples or lists: + #segements = [ (addr1, [d0,d1,d2,...]), (addr2, [e0,e1,e2,...])] + def programData(self, segments, action): + """programm or verify data""" + if DEBUG > 1: sys.stderr.write("* programData()\n") + for seg in segments: + currentAddr = seg.startaddress + pstart = 0 + while pstart len(seg.data): + length = len(seg.data) - pstart + self.programBlk(currentAddr, seg.data[pstart:pstart+length], action) + pstart = pstart + length + currentAddr = currentAddr + length + self.byteCtr = self.byteCtr + length #total sum + + def uploadData(self, startaddress, size, wait=0): + """upload a datablock""" + if DEBUG > 1: sys.stderr.write("* uploadData()\n") + data = '' + pstart = 0 + while pstart size: + length = size - pstart + data = data + self.bslTxRx(self.BSL_RXBLK, + pstart+startaddress, + length, + wait=wait)[:-2] #cut away checksum + pstart = pstart + length + return data + + def txPasswd(self, passwd=None, wait=0): + """transmit password, default if None is given.""" + if DEBUG > 1: sys.stderr.write("* txPassword(%r)\n" % passwd) + if passwd is None or self.pwdsent: + #Send "standard" password to get access to protected functions. + sys.stderr.write("Transmit default password ...\n") + sys.stderr.flush() + #Flash is completely erased, the contents of all Flash cells is 0xff + passwd = chr(0xff)*32 + else: + #sanity check of password + if len(passwd) != 32: + raise ValueError, "password has wrong length (%d)\n" % len(passwd) + sys.stderr.write('Transmit password ...\n') + sys.stderr.flush() + #send the password + self.bslTxRx(self.BSL_TXPWORD, #Command: Transmit Password + 0xffe0, #Address of interupt vectors + 0x0020, #Number of bytes + passwd, #password + wait=wait) #if wait is 1, try to sync forever + self.pwdsent = True + + + def getNewPassword(self): + print 'getting new password' + newpassword = self.bslTxRx(self.BSL_RXBLK, 0xffe0, 0x0020) + return newpassword + + + def writeCalibTables(self): + print 'writing new tables' + print CALIB_TABLES + calibtables = ["84C016FEFFFFFFFFFFFFFFFFFFFFFFFF", + "FFFFFFFFFFFFFFFFFFFF100880000001", + "7E270B790DAA7E4D06DF083308FEFFFF", + "FFFFFFFFFFFF08018F958E9A8D8886D1"] + self.programBlk(0x10C0, "84C016FEFFFFFFFFFFFFFFFFFFFFFFFF", self.ACTION_PROGRAM) + self.programBlk(0x10D0, "FFFFFFFFFFFFFFFFFFFF100880000001", self.ACTION_PROGRAM) + self.programBlk(0x10E0, "7E270B790DAA7E4D06DF083308FEFFFF", self.ACTION_PROGRAM) + self.programBlk(0x10F0, "FFFFFFFFFFFF08018F958E9A8D8886D1", self.ACTION_PROGRAM) + + def writeCalibTables2(self): + print 'writing new tables 2ond part' + #self.programBlk(0x10C0, "84C016FEFFFFFFFFFFFFFFFFFFFFFFFF", self.ACTION_PROGRAM) + #self.programBlk(0x10D0, "FFFFFFFFFFFFFFFFFFFF100880000001", self.ACTION_PROGRAM) + #self.programBlk(0x10E0, "7E270B790DAA7E4D06DF083308FEFFFF", self.ACTION_PROGRAM) + #self.programBlk(0x10F0, "FFFFFFFFFFFF08018F958E9A8D8886D1", self.ACTION_PROGRAM) + + def actionSecureInfoSegment(self): + print 'securing info segment' + self.programBlk(0xFFBE, "0000", self.ACTION_PROGRAM) + print 'info segment secured' + + #----------------------------------------------------------------- + + def actionMassErase(self): + """Erase the flash memory completely (with mass erase command)""" + sys.stderr.write("Mass Erase...\n") + sys.stderr.flush() + self.bslReset(1) #Invoke the boot loader. + for i in range(self.meraseCycles): + if i == 1: sys.stderr.write("Additional Mass Erase Cycles...\n") + self.bslTxRx(self.BSL_MERAS, #Command: Mass Erase + 0xff00, #Any address within flash memory. + 0xa506) #Required setting for mass erase! + self.passwd = None #No password file required! + #print "Mass Erase complete" + #Transmit password to get access to protected BSL functions. + self.txPasswd() + + def actionMainErase(self): + """Erase the main flash memory only""" + sys.stderr.write("Main Erase...\n") + sys.stderr.flush() + self.bslTxRx(self.BSL_ERASE, #Command: Segment Erase + 0xfffe, #Any address within flash memory. + 0xa504) #Required setting for main erase! + #self.passwd = None #Password gets erased WHY?? + + + + def actionStartBSL(self, usepatch=1, adjsp=1, replacementBSL=None, forceBSL=0, mayuseBSL=0, speed=None, bslreset=1): + """start BSL, download patch if desired and needed, adjust SP if desired""" + sys.stderr.write("Invoking BSL...\n") + sys.stderr.flush() + + #for '30, invertTEST=0, else =1 + if bslreset: + #detext if is z1? + self.bslReset(1) #Invoke the boot loader. + + + if(self.z1): + ''' recover password from pic''' + + self.txPasswd(self.passwd) #transmit password + + #Read actual bootstrap loader version. + #sys.stderr.write("Reading BSL version ...\n") + blkin = self.bslTxRx(self.BSL_RXBLK, #Command: Read/Receive Block + 0x0ff0, #Start address + 16) #No. of bytes to read + dev_id, bslVerHi, bslVerLo = struct.unpack(">H8xBB4x", blkin[:-2]) #cut away checksum and extract data + self.dev_id=dev_id; + + + if self.cpu is None: #cpy type forced? + if deviceids.has_key(dev_id): + self.cpu = deviceids[dev_id] #try to autodectect CPU type + + if DEBUG: + sys.stderr.write("Autodetect successful: %04x -> %s\n" % (dev_id, self.cpu)) + else: + sys.stderr.write("Autodetect failed! Unkown ID: %04x. Trying to continue anyway.\n" % dev_id) + self.cpu = F1x #assume something and try anyway.. + + sys.stderr.write("Current bootstrap loader version: %x.%x (Device ID: %04x)\n" % (bslVerHi, bslVerLo, dev_id)) + sys.stderr.flush() + self.bslVer = (bslVerHi << 8) | bslVerLo + + if self.bslVer <= 0x0110: #check if patch is needed + self.BSLMemAccessWarning = 1 + else: + self.BSLMemAccessWarning = 0 #Fixed in newer versions of BSL. + + if self.bslVer <= 0x0130 and adjsp: + #only do this on BSL where it's needed to prevent + #malfunction with F4xx devices/ newer ROM-BSLs + + #Execute function within bootstrap loader + #to prepare stack pointer for the following patch. + #This function will lock the protected functions again. + sys.stderr.write("Adjust SP. Load PC with 0x0C22 ...\n") + self.bslTxRx(self.BSL_LOADPC, #Command: Load PC + 0x0C22) #Address to load into PC + #Re-send password to re-gain access to protected functions. + self.txPasswd(self.passwd) + + #get internal BSL replacement if needed or forced by the user + #required if speed is set but an old BSL is in the device + #if a BSL is given by the user, that one is used and not the internal one + if ((mayuseBSL and speed and self.bslVer < 0x0150) or forceBSL) and replacementBSL is None: + replacementBSL = Memory() #File to program + if self.cpu == F4x: + if DEBUG: + sys.stderr.write("Using built in BSL replacement for F4x devices\n") + sys.stderr.flush() + replacementBSL.loadTIText(cStringIO.StringIO(F4X_BSL)) #parse embedded BSL + else: + if DEBUG: + sys.stderr.write("Using built in BSL replacement for F1x devices\n") + sys.stderr.flush() + replacementBSL.loadTIText(cStringIO.StringIO(F1X_BSL)) #parse embedded BSL + + #now download the new BSL, if allowed and needed (version lower than the + #the replacement) or forced + if replacementBSL is not None: + self.actionDownloadBSL(replacementBSL) + + #debug message with the real BSL version in use (may have changed after replacement BSL) + if DEBUG: + sys.stderr.write("Current bootstrap loader version: 0x%04x\n" % (self.bslVer,)) + sys.stderr.flush() + + #now apply workarounds or patches if BSL in use requires that + if self.bslVer <= 0x0110: #check if patch is needed + if usepatch: #test if patch is desired + sys.stderr.write("Patch for flash programming required!\n") + self.patchRequired = 1 + + sys.stderr.write("Load and verify patch ...\n") + sys.stderr.flush() + #Programming and verification is done in one pass. + #The patch file is only read and parsed once. + segments = Memory() #data to program + segments.loadTIText(cStringIO.StringIO(PATCH)) #parse embedded patch + #program patch + self.programData(segments, self.ACTION_PROGRAM | self.ACTION_VERIFY) + self.patchLoaded = 1 + else: + if DEBUG: + sys.stderr.write("Device needs patch, but not applied (usepatch is false).\n") #message if not patched + + #should the baudrate be changed? + if speed is not None: + self.actionChangeBaudrate(speed) #change baudrate + + def actionDownloadBSL(self, bslsegments): + sys.stderr.write("Load new BSL into RAM...\n") + sys.stderr.flush() + self.programData(bslsegments, self.ACTION_PROGRAM) + sys.stderr.write("Verify new BSL...\n") + sys.stderr.flush() + self.programData(bslsegments, self.ACTION_VERIFY) #File to verify + + #Read startvector of bootstrap loader + #blkin = self.bslTxRx(self.BSL_RXBLK, 0x0300, 2) + #blkin = self.bslTxRx(self.BSL_RXBLK, 0x0220, 2) + blkin = self.bslTxRx(self.BSL_RXBLK, bslsegments[0].startaddress, 2) + startaddr = struct.unpack("%s" % (firmware[self.dev_id],fn)) + + fw=Memory(fn); + #fw.loadIhex(open(fn,"rb")); + + sys.stderr.write("Program ...\n") + sys.stderr.flush() + self.programData(fw, self.ACTION_PROGRAM | self.ACTION_VERIFY) + sys.stderr.write("%i bytes programmed.\n" % self.byteCtr) + sys.stderr.flush() + + def actionVerify(self): + """Verify programmed data""" + if self.data is not None: + sys.stderr.write("Verify ...\n") + sys.stderr.flush() + self.programData(self.data, self.ACTION_VERIFY) + else: + raise BSLException, "verify without data not possible" + + def actionReset(self): + """perform a reset, start user programm""" + sys.stderr.write("Reset device ...\n") + sys.stderr.flush() + self.bslReset(0) #only reset + + def actionRun(self, address=0x220): + """start program at specified address""" + sys.stderr.write("Load PC with 0x%04x ...\n" % address) + sys.stderr.flush() + self.bslTxRx(self.BSL_LOADPC, #Command: Load PC + address) #Address to load into PC + + #table with values from slaa089a.pdf + bauratetable = { + F1x: { + 9600:[0x8580, 0x0000], + 19200:[0x86e0, 0x0001], + 38400:[0x87e0, 0x0002], + }, + F2x: { + 9600:[0x8580, 0x0000], + 19200:[0x8B00, 0x0001], + 38400:[0x8C80, 0x0002], + }, + F4x: { + 9600:[0x9800, 0x0000], + 19200:[0xb000, 0x0001], + 38400:[0xc800, 0x0002], + }, + } + def actionChangeBaudrate(self, baudrate=9600): + """change baudrate. first the command is sent, then the comm + port is reprogrammed. only possible with newer MSP430-BSL versions. + (ROM >=1.6, downloadable >=1.5)""" + try: + baudconfigs = self.bauratetable[self.cpu] + except KeyError: + raise ValueError, "unknown CPU type %s, can't switch baudrate" % self.cpu + try: + a,l = baudconfigs[baudrate] + except KeyError: + raise ValueError, "baudrate not valid. valid values are %r" % baudconfigs.keys() + + sys.stderr.write("Changing baudrate to %d ...\n" % baudrate) + sys.stderr.flush() + self.bslTxRx(self.BSL_CHANGEBAUD, #Command: change baudrate + a, l) #args are coded in adr and len + self.serialport.flush() + time.sleep(0.010) #recomended delay + self.serialport.baudrate = baudrate + + def actionReadBSLVersion(self): + """informational output of BSL version number. + (newer MSP430-BSLs only)""" + ans = self.bslTxRx(self.BSL_TXVERSION, 0) #Command: receive version info + #the following values are in big endian style!!! + family_type, bsl_version = struct.unpack(">H8xH4x", ans[:-2]) #cut away checksum and extract data + print "Device Type: 0x%04x\nBSL version: 0x%04x\n" % (family_type, bsl_version) + + def actionWriteNewPassword(self): + passwd = self.getNewPassword() + #print passwd + self.picWritePassword(passwd) + + def actionRecoverPassword(self): + p = self.picRecoverPassword() + #print p + self.passwd = p + + def picRecoverPassword(self): + ''' recovers password from picrom''' + print 'recovering pic password', + p = '' + + for i in range(0,32): + c = self.readpicROM(i) + print c, + p = p + chr(c) + + print 'done' + return p + + def picWritePassword(self, password): + ''' writes a new password to picrom''' + print 'writing new password', + for i in range(0,32): + c = ord(password[i]) + print c, + self.writepicROM(i, c) + print 'done' + + +def usage(): + """print some help message""" + sys.stderr.write(""" +USAGE: %s [options] [file] +Version: %s + +If "-" is specified as file the data is read from the stdinput. +A file ending with ".txt" is considered to be in TIText format, +'.a43' and '.hex' as IntelHex and all other filenames are +considered as ELF files. + +General options: + -h, --help Show this help screen. + -c, --comport=port Specify the communication port to be used. + (Default is 0) + 0->COM1 / ttyS0 + 1->COM2 / ttyS1 + etc. + -P, --password=file Specify a file with the interrupt vectors that + are used as password. This can be any file that + has previously been used to program the device. + (e.g. -P INT_VECT.TXT). + -f, --framesize=num Max. number of data bytes within one transmitted + frame (16 to 240 in steps of 16) (e.g. -f 240). + -m, --erasecycles=num Number of mass erase cycles (default is 1). Some + old F149 devices need additional erase cycles. + On newer devices it is no longer needed. (e.g. for + an old F149: -m20) + -U, --unpatched Do not download the BSL patch, even when it is + needed. This is used when a program is downloaded + into RAM and executed from there (and where flash + programming is not needed.) + -D, --debug Increase level of debug messages. This won't be + very useful for the average user... + -I, --intelhex Force fileformat to IntelHex + -T, --titext Force fileformat to be TIText + -N, --notimeout Don't use timeout on serial port (use with care) + -B, --bsl=bsl.txt Load and use new BSL from the TI Text file + -S, --speed=baud Reconfigure speed, only possible with newer + MSP403-BSL versions (>1.5, read slaa089a.pdf for + details). If the --bsl option is not used, an + internal BSL replacement will be loaded. + Needs a target with at least 2kB RAM! + Possible values are 9600, 19200, 38400 + (default 9600) + -1, --f1x Specify CPU family, in case autodetect fails + -2, --f2x Specify CPU family, in case autodetect fails + -4, --f4x Specify CPU family, in case autodetect fails + --F1x and --f2x are only needed when the "change + baudrate" feature is used and the autodetect feature + fails. If the device ID that is uploaded is known, it + has precedence to the command line option. + --invert-reset Invert signal on RST pin (used for some BSL hardware) + --invert-test Invert signal on TEST/TCK pin (used for some BSL + hardware) + --swap-reset-test Swap the RST and TEST pins (used for some BSL hardware) + --telos-latch Special twiddle in BSL reset for Telos hardware + --telos-i2c DTR/RTS map via an I2C switch to TCK/RST in Telos Rev.B + --telos Implies options --invert-reset, --invert-test, + --swap-reset-test, and --telos-latch + --telosb Implies options --swap-reset-test, --telos-i2c, + --no-BSL-download, and --speed=38400 + --goodfet10 + --goodfet20 + --goodfet30 + --tmote Identical operation to --telosb + --z1 Bootstrap a Z1 + --no-BSL-download Do not download replacement BSL (disable automatic) + --force-BSL-download Download replacement BSL even if not needed (the one + in the device would have the required features) + --slow Add delays when operating the conrol pins. Useful if + the pins/circuit has high capacitance. + +Program Flow Specifiers: + -e, --masserase Mass Erase (clear all flash memory) + -E, --erasecheck Erase Check by file + -p, --program Program file + -v, --verify Verify by file + +The order of the above options matters! The table is ordered by normal +execution order. For the options "Epv" a file must be specified. +Program flow specifiers default to "pvr" if a file is given. +Don't forget to specify "e" or "eE" when programming flash! + +Data retreiving: + -u, --upload=addr Upload a datablock (see also: -s). + -s, --size=num Size of the data block do upload. (Default is 2) + -x, --hex Show a hexadecimal display of the uploaded data. + (Default) + -b, --bin Get binary uploaded data. This can be used + to redirect the output into a file. + +Do before exit: + -g, --go=address Start programm execution at specified address. + This implies option --wait. + -r, --reset Reset connected MSP430. Starts application. + This is a normal device reset and will start + the programm that is specified in the reset + vector. (see also -g) + -w, --wait Wait for before closing serial port. + +If it says "NAK received" it's probably because you specified no or a +wrong password. +""" % (sys.argv[0], VERSION)) + +#add some arguments to a function, but don't call it yet, instead return +#a wrapper object for later invocation +class curry: + """create a callable with some arguments specified in advance""" + def __init__(self, fun, *args, **kwargs): + self.fun = fun + self.pending = args[:] + self.kwargs = kwargs.copy() + + def __call__(self, *args, **kwargs): + if kwargs and self.kwargs: + kw = self.kwargs.copy() + kw.update(kwargs) + else: + kw = kwargs or self.kwargs + return apply(self.fun, self.pending + args, kw) + + def __repr__(self): + #first try if it a function + try: + return "curry(%s, %r, %r)" % (self.fun.func_name, self.pending, self.kwargs) + except AttributeError: + #fallback for callable classes + return "curry(%s, %r, %r)" % (self.fun, self.pending, self.kwargs) + +def hexify(line, bytes, width=16): + return '%04x %s%s %s' % ( + line, + ('%02x '*len(bytes)) % tuple(bytes), + ' '* (width-len(bytes)), + ('%c'*len(bytes)) % tuple(map(lambda x: (x>=32 and x<127) and x or ord('.'), bytes)) + ) + +#Main: +def main(itest=1): + global DEBUG + import getopt + filetype = None + filename = None + comPort = None #Default setting. + speed = None + unpatched = 0 + reset = 0 + wait = 0 #wait at the end + goaddr = None + bsl = BootStrapLoader() + toinit = [] + todo = [] + startaddr = None + size = 2 + hexoutput = 1 + notimeout = 0 + bslrepl = None + mayuseBSL = 1 + forceBSL = 0 + dumpivt = 0 + dumpinfo = 0 + + bsl.invertRST = 1 + bsl.invertTEST = itest + + if comPort is None and os.environ.get("GOODFET")!=None: + glob_list = glob.glob(os.environ.get("GOODFET")); + if len(glob_list) > 0: + comPort = glob_list[0]; + if comPort is None: + glob_list = glob.glob("/dev/tty.usbserial*"); + if len(glob_list) > 0: + comPort = glob_list[0]; + if comPort is None: + glob_list = glob.glob("/dev/ttyUSB*"); + if len(glob_list) > 0: + comPort = glob_list[0]; + + + sys.stderr.write("MSP430 Bootstrap Loader Version: %s\n" % VERSION) + + try: + opts, args = getopt.getopt(sys.argv[1:], + "hc:P:wf:m:neEpvrg:UDudsxbITNB:S:V14", + ["help", "comport=", "password=", "wait", "framesize=", + "erasecycles=", "masserase", "erasecheck", "program", + "verify", "reset", "go=", "unpatched", "debug", + "upload=", "download=", "size=", "hex", "bin", + "intelhex", "titext", "notimeout", "bsl=", "speed=", + "bslversion", "f1x", "f2x", "f4x", "invert-reset", "invert-test", + "swap-reset-test", "telos-latch", "telos-i2c", "telos", "telosb", + "tmote","no-BSL-download", "force-BSL-download", "slow", + "dumpivt", "dumpinfo", "fromweb", + "goodfet30", "goodfet20", "goodfet10", "z1", "mainerase" + ] + ) + except getopt.GetoptError: + # print help information and exit: + usage() + sys.exit(2) + + for o, a in opts: + if o in ("-h", "--help"): + usage() + sys.exit() + elif o in ("-c", "--comport"): + try: + comPort = int(a) #try to convert decimal + except ValueError: + comPort = a #take the string and let serial driver decide + elif o in ("-P", "--password"): + #extract password from file + bsl.passwd = Memory(a).getMemrange(0xffe0, 0xffff) + elif o in ("-w", "--wait"): + wait = 1 + elif o in ("--dumpivt"): + dumpivt=1; + elif o in ("--dumpinfo"): + dumpinfo=1; + elif o in ("-f", "--framesize"): + try: + maxData = int(a) #try to convert decimal + except ValueError: + sys.stderr.write("framesize must be a valid number\n") + sys.exit(2) + #Make sure that conditions for maxData are met: + #( >= 16 and == n*16 and <= MAX_DATA_BYTES!) + if maxData > BootStrapLoader.MAX_DATA_BYTES: + maxData = BootStrapLoader.MAX_DATA_BYTES + elif maxData < 16: + maxData = 16 + bsl.maxData = maxData - (maxData % 16) + sys.stderr.write( "Max. number of data bytes within one frame set to %i.\n" % maxData) + elif o in ("-m", "--erasecycles"): + try: + meraseCycles = int(a) #try to convert decimal + except ValueError: + sys.stderr.write("erasecycles must be a valid number\n") + sys.exit(2) + #sanity check of value + if meraseCycles < 1: + sys.stderr.write("erasecycles must be a positive number\n") + sys.exit(2) + if meraseCycles > 20: + sys.stderr.write("warning: erasecycles set to a large number (>20): %d\n" % meraseCycles) + sys.stderr.write( "Number of mass erase cycles set to %i.\n" % meraseCycles) + bsl.meraseCycles = meraseCycles + elif o in ("-e", "--masserase"): + #toinit.append(bsl.actionMassErase) #Erase Flash + todo.append(bsl.actionMainErase) #Erase Flash + #todo.append(bsl.actionSecureInfoSegment) + elif o in ("-n", "--mainerase"): + #todo.append(bsl.actionMainErase) #Erase Flash + toinit.append(bsl.actionMassErase) #Erase Flash + elif o in ("-E", "--erasecheck"): + toinit.append(bsl.actionEraseCheck) #Erase Check (by file) + elif o in ("-p", "--program"): + #pass + todo.append(bsl.actionProgram) #Program file + if bsl.z1: + #todo.append(bsl.actionUnlockInfo) + #todo.append(bsl.writeCalibTables) + #todo.append(bsl.writeCalibTables2) + + todo.append(bsl.actionWriteNewPassword) + + pass + elif o in ("--fromweb"): + toinit.append(bsl.actionMassErase) #Erase Flash + todo.append(bsl.actionFromweb) #Program GoodFET code + elif o in ("-v", "--verify"): + todo.append(bsl.actionVerify) #Verify file + elif o in ("-r", "--reset"): + reset = 1 + elif o in ("-g", "--go"): + try: + goaddr = int(a) #try to convert decimal + except ValueError: + try: + goaddr = int(a[2:],16) #try to convert hex + except ValueError: + sys.stderr.write("go address must be a valid number\n") + sys.exit(2) + wait = 1 + elif o in ("-U", "--unpatched"): + unpatched = 1 + elif o in ("-D", "--debug"): + DEBUG = DEBUG + 1 + elif o in ("-u", "--upload"): + try: + startaddr = int(a) #try to convert decimal + except ValueError: + try: + startaddr = int(a,16) #try to convert hex + except ValueError: + sys.stderr.write("upload address must be a valid number\n") + sys.exit(2) + elif o in ("-s", "--size"): + try: + size = int(a) + except ValueError: + try: + size = int(a,16) + except ValueError: + sys.stderr.write("size must be a valid number\n") + sys.exit(2) + elif o in ("-x", "--hex"): + hexoutput = 1 + elif o in ("-b", "--bin"): + hexoutput = 0 + elif o in ("-I", "--intelhex"): + filetype = 0 + elif o in ("-T", "--titext"): + filetype = 1 + elif o in ("-N", "--notimeout"): + notimeout = 1 + elif o in ("-B", "--bsl"): + bslrepl = Memory() #File to program + bslrepl.loadFile(a) + elif o in ("-V", "--bslversion"): + todo.append(bsl.actionReadBSLVersion) #load replacement BSL as first item + elif o in ("-S", "--speed"): + try: + speed = int(a) #try to convert decimal + except ValueError: + sys.stderr.write("speed must be decimal number\n") + sys.exit(2) + elif o in ("-1", "--f1x"): + bsl.cpu = F1x + elif o in ("-2", "--f2x"): + bsl.cpu = F2x + elif o in ("-4", "--f4x"): + bsl.cpu = F4x + elif o in ("--invert-reset", ): + bsl.invertRST = 1 + elif o in ("--invert-test", ): + bsl.invertTEST = 1 + elif o in ("--swap-reset-test", ): + bsl.swapRSTTEST = 1 + elif o in ("--telos-latch", ): + bsl.telosLatch = 1 + elif o in ("--telos-i2c", ): + bsl.telosI2C = 1 + elif o in ("--telos", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + bsl.swapRSTTEST = 1 + bsl.telosLatch = 1 + elif o in ("--goodfet10", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + elif o in ("--goodfet20", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + elif o in ("--goodfet30", ): + bsl.invertRST = 1 + bsl.invertTEST = 0 + elif o in ("--telosb", ): + bsl.swapRSTTEST = 1 + bsl.telosI2C = 1 + mayuseBSL = 0 + speed = 38400 + elif o in ("--tmote", ): + bsl.swapRSTTEST = 1 + bsl.telosI2C = 1 + mayuseBSL = 0 + speed = 38400 + elif o in ("--z1", ): + bsl.z1 = 1 + speed = 38400 + toinit.append(bsl.actionRecoverPassword) + elif o in ("--no-BSL-download", ): + mayuseBSL = 0 + elif o in ("--force-BSL-download", ): + forceBSL = 1 + elif o in ("--slow", ): + bsl.slowmode = 1 + + if len(args) == 0: + sys.stderr.write("Use -h for help\n"); + sys.stderr.write("Use --fromweb to upgrade a GoodFET.\n") + elif len(args) == 1: #a filename is given + if not todo: #if there are no actions yet + todo.extend([ #add some useful actions... + bsl.actionProgram, + bsl.actionVerify, + ]) + filename = args[0] + else: #number of args is wrong + usage() + sys.exit(2) + + if DEBUG: #debug infos + sys.stderr.write("Debug level set to %d\n" % DEBUG) + sys.stderr.write("Python version: %s\n" % sys.version) + + #sanity check of options + if notimeout and goaddr is not None and startaddr is not None: + sys.stderr.write("Option --notimeout can not be used together with both --upload and --go\n") + sys.exit(1) + + if notimeout: + sys.stderr.write("Warning: option --notimeout can cause improper function in some cases!\n") + bsl.timeout = 0 + + if goaddr and reset: + sys.stderr.write("Warning: option --reset ignored as --go is specified!\n") + reset = 0 + + if startaddr and reset: + sys.stderr.write("Warning: option --reset ignored as --upload is specified!\n") + reset = 0 + + sys.stderr.flush() + + #prepare data to download + bsl.data = Memory() #prepare downloaded data + if filetype is not None: #if the filetype is given... + if filename is None: + raise ValueError("no filename but filetype specified") + if filename == '-': #get data from stdin + file = sys.stdin + else: + file = open(filename, "rb") #or from a file + if filetype == 0: #select load function + bsl.data.loadIHex(file) #intel hex + elif filetype == 1: + bsl.data.loadTIText(file) #TI's format + else: + raise ValueError("illegal filetype specified") + else: #no filetype given... + if filename == '-': #for stdin: + bsl.data.loadIHex(sys.stdin) #assume intel hex + elif filename: + bsl.data.loadFile(filename) #autodetect otherwise + + if DEBUG > 3: sys.stderr.write("File: %r" % filename) + + bsl.comInit(comPort) #init port + + #initialization list + if toinit: #erase and erase check + if DEBUG: sys.stderr.write("Preparing device ...\n") + #bsl.actionStartBSL(usepatch=0, adjsp=0) #no workarounds needed + #if speed: bsl.actionChangeBaudrate(speed) #change baud rate as fast as possible + for f in toinit: f() + + if todo or goaddr or startaddr: + if DEBUG: sys.stderr.write("Actions ...\n") + #connect to the BSL + bsl.actionStartBSL( + usepatch=not unpatched, + replacementBSL=bslrepl, + forceBSL=forceBSL, + mayuseBSL=mayuseBSL, + speed=speed, + ) + + #work list + if todo: + if DEBUG > 0: #debug + #show a nice list of sheduled actions + sys.stderr.write("TODO list:\n") + for f in todo: + try: + sys.stderr.write(" %s\n" % f.func_name) + except AttributeError: + sys.stderr.write(" %r\n" % f) + for f in todo: f() #work through todo list + + if reset: #reset device first if desired + bsl.actionReset() + if dumpivt: + bsl.txPasswd(); #default pass + data=bsl.uploadData(0xc00,1024); + hex=""; + for c in data: + hex+=("%02x "%ord(c)); + print hex; + if dumpinfo: + bsl.txPasswd(); #default pass + data=bsl.uploadData(0x1000,256); + hex="@1000\n"; + for c in data: + hex+=("%02x "%ord(c)); + hex+="\nq\n"; + print hex; + + if goaddr is not None: #start user programm at specified address + bsl.actionRun(goaddr) #load PC and execute + + #upload datablock and output + if startaddr is not None: + if goaddr: #if a program was started... + #don't restart BSL but wait for the device to enter it itself + sys.stderr.write("Waiting for device to reconnect for upload: ") + sys.stderr.flush() + bsl.txPasswd(bsl.passwd, wait=1) #synchronize, try forever... + data = bsl.uploadData(startaddr, size) #upload data + else: + data = bsl.uploadData(startaddr, size) #upload data + if hexoutput: #depending on output format + m = 0 + while m < len(data): #print a hex display + print hexify(startaddr+m, map(ord,data[m:m+16])) + m = m + 16 + else: + sys.stdout.write(data) #binary output w/o newline! + wait = 0 #wait makes no sense as after the upload the device is still in BSL + + if wait: #wait at the end if desired + sys.stderr.write("Press ...\n") #display a prompt + sys.stderr.flush() + raw_input() #wait for newline + + bsl.comDone() #Release serial communication port + +if __name__ == '__main__': + try: + main(1) + except SystemExit: + raise #let pass exit() calls + except KeyboardInterrupt: + if DEBUG: raise #show full trace in debug mode + sys.stderr.write("user abort.\n") #short messy in user mode + sys.exit(1) #set errorlevel for script usage + except Exception, msg: #every Exception is caught and displayed + if DEBUG: raise #show full trace in debug mode + #sys.stderr.write("\nAn error occoured:\n%s\n" % msg) #short messy in user mode + #sys.exit(1) #set errorlevel for script usage + main(0); diff --git a/tools/zolertia/z1-bsl-nopic b/tools/zolertia/z1-bsl-nopic new file mode 100755 index 000000000..8b5edd8f5 --- /dev/null +++ b/tools/zolertia/z1-bsl-nopic @@ -0,0 +1,1941 @@ +#!/usr/bin/env python2 +# Serial Bootstrap Loader software for the MSP430 embedded proccessor. +# +# (C) 2001-2003 Chris Liechti +# this is distributed under a free software license, see license-bsl.txt +# +# fixes from Colin Domoney +# +# based on the application note slas96b.pdf from Texas Instruments, Inc., +# Volker Rzehak +# additional infos from slaa089a.pdf +# +# Forked by Travis Goodspeed for use with the GoodFET +# JTAG programmer. + +import sys, time, string, cStringIO, struct +sys.path.append("/usr/lib/tinyos") +import serial, os, glob + +#forked from TinyOS Telos version. +VERSION = string.split("Revision: 1.39-goodfet-8 z1 fork")[1] + +DEBUG = 0 #disable debug messages by default + +#copy of the patch file provided by TI +#this part is (C) by Texas Instruments +PATCH = """@0220 +31 40 1A 02 09 43 B0 12 2A 0E B0 12 BA 0D 55 42 +0B 02 75 90 12 00 1F 24 B0 12 BA 02 55 42 0B 02 +75 90 16 00 16 24 75 90 14 00 11 24 B0 12 84 0E +06 3C B0 12 94 0E 03 3C 21 53 B0 12 8C 0E B2 40 +10 A5 2C 01 B2 40 00 A5 28 01 30 40 42 0C 30 40 +76 0D 30 40 AC 0C 16 42 0E 02 17 42 10 02 E2 B2 +08 02 14 24 B0 12 10 0F 36 90 00 10 06 28 B2 40 +00 A5 2C 01 B2 40 40 A5 28 01 D6 42 06 02 00 00 +16 53 17 83 EF 23 B0 12 BA 02 D3 3F B0 12 10 0F +17 83 FC 23 B0 12 BA 02 D0 3F 18 42 12 02 B0 12 +10 0F D2 42 06 02 12 02 B0 12 10 0F D2 42 06 02 +13 02 38 E3 18 92 12 02 BF 23 E2 B3 08 02 BC 23 +30 41 +q +""" + +#These BSL's are (C) by TI. They come with the application note slaa089a +F1X_BSL = """@0220 +24 02 2E 02 31 40 20 02 2B D2 C0 43 EA FF 32 C2 +F2 C0 32 00 00 00 B2 40 80 5A 20 01 F2 40 85 00 +57 00 F2 40 80 00 56 00 E2 D3 21 00 E2 D3 22 00 +E2 C3 26 00 E2 C2 2A 00 E2 C2 2E 00 B2 40 10 A5 +2C 01 B2 40 00 A5 28 01 3B C0 3A 00 B0 12 D6 04 +82 43 12 02 09 43 36 40 0A 02 37 42 B0 12 AC 05 +C6 4C 00 00 16 53 17 83 F9 23 D2 92 0C 02 0D 02 +28 20 55 42 0B 02 75 90 12 00 80 24 75 90 10 00 +6D 24 B0 12 9C 04 55 42 0B 02 75 90 18 00 31 24 +75 90 1E 00 B8 24 75 90 20 00 17 24 2B B2 11 24 +75 90 16 00 22 24 75 90 14 00 B3 24 75 90 1A 00 +18 24 75 90 1C 00 45 24 04 3C B0 12 36 05 BE 3F +21 53 B0 12 3C 05 BA 3F 03 43 B0 12 36 05 D2 42 +0E 02 56 00 D2 42 0F 02 57 00 D2 42 10 02 16 02 +AD 3F B0 12 36 05 10 42 0E 02 16 42 0E 02 15 43 +07 3C 36 40 FE FF B2 40 06 A5 10 02 35 40 0C 00 +B2 40 00 A5 2C 01 92 42 10 02 28 01 B6 43 00 00 +92 B3 2C 01 FD 23 15 83 F3 23 36 90 FE FF CD 27 +37 40 80 00 36 F0 80 FF 36 90 00 11 0E 28 07 57 +36 F0 00 FF 36 90 00 12 08 28 07 57 36 F0 00 FE +04 3C 16 42 0E 02 17 42 10 02 35 43 75 96 03 20 +17 83 FC 23 B2 3F 82 46 00 02 B3 3F 36 40 E0 FF +37 40 20 00 B0 12 AC 05 7C 96 01 24 2B D3 17 83 +F9 23 2B C2 B0 12 9C 04 2B D2 9F 3F 16 42 0E 02 +17 42 10 02 2B B2 38 24 3B D0 10 00 B0 12 AC 05 +36 90 00 10 06 2C 36 90 00 01 09 2C C6 4C 00 00 +25 3C B2 40 00 A5 2C 01 B2 40 40 A5 28 01 16 B3 +03 20 C2 4C 14 02 1A 3C C2 4C 15 02 86 9A FD FF +08 24 2B D3 3B B0 20 00 04 20 3B D0 20 00 82 46 +00 02 36 90 01 02 04 28 3B D2 3B B0 10 00 02 24 +3B C0 32 00 1A 42 14 02 86 4A FF FF 16 53 17 83 +CD 23 B0 12 9C 04 61 3F B0 12 AC 05 17 83 FC 23 +B0 12 9C 04 5E 3F B2 40 F0 0F 0E 02 B2 40 10 00 +10 02 B2 40 80 00 0A 02 D2 42 10 02 0C 02 D2 42 +10 02 0D 02 82 43 12 02 09 43 36 40 0A 02 27 42 +7C 46 B0 12 40 05 17 83 FB 23 16 42 0E 02 17 42 +10 02 36 90 00 01 0A 28 B2 46 14 02 5C 42 14 02 +B0 12 40 05 17 83 5C 42 15 02 01 3C 7C 46 B0 12 +40 05 17 83 EE 23 B2 E3 12 02 5C 42 12 02 B0 12 +40 05 5C 42 13 02 B0 12 40 05 E0 3E 18 42 12 02 +B0 12 AC 05 C2 4C 12 02 B0 12 AC 05 C2 4C 13 02 +38 E3 3B B2 0A 24 86 9A FE FF 07 24 3B B0 20 00 +04 20 16 53 82 46 00 02 2B D3 18 92 12 02 08 23 +2B B3 06 23 30 41 E2 B2 28 00 FD 27 E2 B2 28 00 +FD 23 B2 40 24 02 60 01 E2 B2 28 00 FD 27 15 42 +70 01 05 11 05 11 05 11 82 45 02 02 05 11 82 45 +04 02 B2 80 1E 00 04 02 57 42 16 02 37 80 03 00 +05 11 05 11 17 53 FD 23 35 50 40 A5 82 45 2A 01 +35 42 B2 40 24 02 60 01 92 92 70 01 02 02 FC 2F +15 83 F7 23 09 43 7C 40 90 00 02 3C 7C 40 A0 00 +C2 43 07 02 C9 EC 12 02 19 E3 1B C3 55 42 07 02 +55 45 56 05 00 55 0C 2E 2E 2E 2E 2E 2E 2E 2E 1A +34 34 92 42 70 01 72 01 B2 50 0C 00 72 01 07 3C +1B B3 0B 20 82 43 62 01 92 B3 62 01 FD 27 E2 C3 +21 00 0A 3C 4C 11 F6 2B 1B E3 82 43 62 01 92 B3 +62 01 FD 27 E2 D3 21 00 92 52 02 02 72 01 D2 53 +07 02 F0 90 0C 00 61 FC D1 23 30 41 C2 43 09 02 +1B C3 55 42 09 02 55 45 BC 05 00 55 0C 56 56 56 +56 56 56 56 56 36 76 00 E2 B2 28 00 FD 23 92 42 +70 01 72 01 92 52 04 02 72 01 82 43 62 01 92 B3 +62 01 FD 27 E2 B2 28 00 1E 28 2B D3 1C 3C 4C 10 +1A 3C 82 43 62 01 92 B3 62 01 FD 27 E2 B2 28 00 +01 28 1B E3 1B B3 01 24 2B D3 C9 EC 12 02 19 E3 +0A 3C 82 43 62 01 92 B3 62 01 FD 27 E2 B2 28 00 +E6 2B 4C 10 1B E3 92 52 02 02 72 01 D2 53 09 02 +C0 3F 82 43 62 01 92 B3 62 01 FD 27 E2 B2 28 00 +01 2C 2B D3 30 41 +q +""" + +F4X_BSL = """@0220 +24 02 2E 02 31 40 20 02 2B D2 C0 43 EA FF 32 C2 +F2 C0 32 00 00 00 B2 40 80 5A 20 01 32 D0 40 00 +C2 43 50 00 F2 40 98 00 51 00 F2 C0 80 00 52 00 +D2 D3 21 00 D2 D3 22 00 D2 C3 26 00 E2 C3 22 00 +E2 C3 26 00 B2 40 10 A5 2C 01 B2 40 00 A5 28 01 +3B C0 3A 00 B0 12 DE 04 82 43 12 02 09 43 36 40 +0A 02 37 42 B0 12 B4 05 C6 4C 00 00 16 53 17 83 +F9 23 D2 92 0C 02 0D 02 28 20 55 42 0B 02 75 90 +12 00 80 24 75 90 10 00 6D 24 B0 12 A4 04 55 42 +0B 02 75 90 18 00 31 24 75 90 1E 00 B8 24 75 90 +20 00 17 24 2B B2 11 24 75 90 16 00 22 24 75 90 +14 00 B3 24 75 90 1A 00 18 24 75 90 1C 00 45 24 +04 3C B0 12 3E 05 BE 3F 21 53 B0 12 44 05 BA 3F +03 43 B0 12 3E 05 D2 42 0E 02 50 00 D2 42 0F 02 +51 00 D2 42 10 02 16 02 AD 3F B0 12 3E 05 10 42 +0E 02 16 42 0E 02 15 43 07 3C 36 40 FE FF B2 40 +06 A5 10 02 35 40 0C 00 B2 40 00 A5 2C 01 92 42 +10 02 28 01 B6 43 00 00 92 B3 2C 01 FD 23 15 83 +F3 23 36 90 FE FF CD 27 37 40 80 00 36 F0 80 FF +36 90 00 11 0E 28 07 57 36 F0 00 FF 36 90 00 12 +08 28 07 57 36 F0 00 FE 04 3C 16 42 0E 02 17 42 +10 02 35 43 75 96 03 20 17 83 FC 23 B2 3F 82 46 +00 02 B3 3F 36 40 E0 FF 37 40 20 00 B0 12 B4 05 +7C 96 01 24 2B D3 17 83 F9 23 2B C2 B0 12 A4 04 +2B D2 9F 3F 16 42 0E 02 17 42 10 02 2B B2 38 24 +3B D0 10 00 B0 12 B4 05 36 90 00 10 06 2C 36 90 +00 01 09 2C C6 4C 00 00 25 3C B2 40 00 A5 2C 01 +B2 40 40 A5 28 01 16 B3 03 20 C2 4C 14 02 1A 3C +C2 4C 15 02 86 9A FD FF 08 24 2B D3 3B B0 20 00 +04 20 3B D0 20 00 82 46 00 02 36 90 01 02 04 28 +3B D2 3B B0 10 00 02 24 3B C0 32 00 1A 42 14 02 +86 4A FF FF 16 53 17 83 CD 23 B0 12 A4 04 61 3F +B0 12 B4 05 17 83 FC 23 B0 12 A4 04 5E 3F B2 40 +F0 0F 0E 02 B2 40 10 00 10 02 B2 40 80 00 0A 02 +D2 42 10 02 0C 02 D2 42 10 02 0D 02 82 43 12 02 +09 43 36 40 0A 02 27 42 7C 46 B0 12 48 05 17 83 +FB 23 16 42 0E 02 17 42 10 02 36 90 00 01 0A 28 +B2 46 14 02 5C 42 14 02 B0 12 48 05 17 83 5C 42 +15 02 01 3C 7C 46 B0 12 48 05 17 83 EE 23 B2 E3 +12 02 5C 42 12 02 B0 12 48 05 5C 42 13 02 B0 12 +48 05 E0 3E 18 42 12 02 B0 12 B4 05 C2 4C 12 02 +B0 12 B4 05 C2 4C 13 02 38 E3 3B B2 0A 24 86 9A +FE FF 07 24 3B B0 20 00 04 20 16 53 82 46 00 02 +2B D3 18 92 12 02 08 23 2B B3 06 23 30 41 E2 B3 +20 00 FD 27 E2 B3 20 00 FD 23 B2 40 24 02 60 01 +E2 B3 20 00 FD 27 15 42 70 01 05 11 05 11 05 11 +82 45 02 02 05 11 82 45 04 02 B2 80 1E 00 04 02 +57 42 16 02 37 80 03 00 05 11 05 11 17 53 FD 23 +35 50 40 A5 82 45 2A 01 35 42 B2 40 24 02 60 01 +92 92 70 01 02 02 FC 2F 15 83 F7 23 09 43 7C 40 +90 00 02 3C 7C 40 A0 00 C2 43 07 02 C9 EC 12 02 +19 E3 1B C3 55 42 07 02 55 45 5E 05 00 55 0C 2E +2E 2E 2E 2E 2E 2E 2E 1A 34 34 92 42 70 01 72 01 +B2 50 0C 00 72 01 07 3C 1B B3 0B 20 82 43 62 01 +92 B3 62 01 FD 27 D2 C3 21 00 0A 3C 4C 11 F6 2B +1B E3 82 43 62 01 92 B3 62 01 FD 27 D2 D3 21 00 +92 52 02 02 72 01 D2 53 07 02 F0 90 0C 00 59 FC +D1 23 30 41 C2 43 09 02 1B C3 55 42 09 02 55 45 +C4 05 00 55 0C 56 56 56 56 56 56 56 56 36 76 00 +E2 B3 20 00 FD 23 92 42 70 01 72 01 92 52 04 02 +72 01 82 43 62 01 92 B3 62 01 FD 27 E2 B3 20 00 +1E 28 2B D3 1C 3C 4C 10 1A 3C 82 43 62 01 92 B3 +62 01 FD 27 E2 B3 20 00 01 28 1B E3 1B B3 01 24 +2B D3 C9 EC 12 02 19 E3 0A 3C 82 43 62 01 92 B3 +62 01 FD 27 E2 B3 20 00 E6 2B 4C 10 1B E3 92 52 +02 02 72 01 D2 53 09 02 C0 3F 82 43 62 01 92 B3 +62 01 FD 27 E2 B3 20 00 01 2C 2B D3 30 41 +q +""" + +CALIB_TABLES = """ +84 C0 16 FE FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF 10 08 80 00 00 01 +7E 27 0B 79 0D AA 7E 4D 06 DF 08 33 08 FE FF FF +FF FF FF FF FF FF 08 01 8F 95 8E 9A 8D 88 86 D1 +""" + +#cpu types for "change baudrate" +#use strings as ID so that they can be used in outputs too +F1x = "F1x family" +F2x = "F2x family" +F4x = "F4x family" + +#known device list +deviceids = { + 0xf149: F1x, + 0xf16c: F1x, #for GoodFET10 to '20 + 0xf112: F1x, + 0xf413: F4x, + 0xf123: F1x, + 0xf449: F4x, + 0x1232: F1x, + 0xf26f: F2x, #for GoodFET20 + 0xf227: F2x, #for GoodFET30 +} + +#GoodFET firmware +firmware = { + 0xf16c: "http://goodfet.sourceforge.net/dist/msp430x1612.hex", + 0xf26f: "http://goodfet.sourceforge.net/dist/msp430x2618.hex", + 0xf227: "http://goodfet.sourceforge.net/dist/msp430x2274.hex" +} + +class BSLException(Exception): + pass + +class LowLevel: + "lowlevel communication" + #Constants + MODE_SSP = 0 + MODE_BSL = 1 + + BSL_SYNC = 0x80 + BSL_TXPWORD = 0x10 + BSL_TXBLK = 0x12 #Transmit block to boot loader + BSL_UNLOCK_INFO = 0x12 #unlocks / locks info segment A Not working on msp430f2617 + BSL_RXBLK = 0x14 #Receive block from boot loader + BSL_ERASE = 0x16 #Erase one segment + BSL_MERAS = 0x18 #Erase complete FLASH memory + BSL_CHANGEBAUD = 0x20 #Change baudrate + BSL_SETMEMOFFSET = 0x21 #Set memory offset + BSL_LOADPC = 0x1A #Load PC and start execution + BSL_TXVERSION = 0x1E #Get BSL version + + #Upper limit of address range that might be modified by + #"BSL checksum bug". + BSL_CRITICAL_ADDR = 0x0A00 + + #Header Definitions + CMD_FAILED = 0x70 + DATA_FRAME = 0x80 + DATA_ACK = 0x90 + DATA_NAK = 0xA0 + + QUERY_POLL = 0xB0 + QUERY_RESPONSE = 0x50 + + OPEN_CONNECTION = 0xC0 + ACK_CONNECTION = 0x40 + + DEFAULT_TIMEOUT = 1 + DEFAULT_PROLONG = 10 + MAX_FRAME_SIZE = 256 + MAX_DATA_BYTES = 250 + MAX_DATA_WORDS = 125 + + MAX_FRAME_COUNT = 16 + + #Error messages + ERR_COM = "Unspecific error" + ERR_RX_NAK = "NAK received (wrong password?)" + #ERR_CMD_NOT_COMPLETED = "Command did not send ACK: indicates that it didn't complete correctly" + ERR_CMD_FAILED = "Command failed, is not defined or is not allowed" + ERR_BSL_SYNC = "Bootstrap loader synchronization error" + ERR_FRAME_NUMBER = "Frame sequence number error." + + def calcChecksum(self, data, length): + """Calculates a checksum of "data".""" + checksum = 0 + + for i in range(length/2): + checksum = checksum ^ (ord(data[i*2]) | (ord(data[i*2+1]) << 8)) #xor-ing + return 0xffff & (checksum ^ 0xffff) #inverting + + def __init__(self, aTimeout = None, aProlongFactor = None): + """init bsl object, don't connect yet""" + if aTimeout is None: + self.timeout = self.DEFAULT_TIMEOUT + else: + self.timeout = aTimeout + if aProlongFactor is None: + self.prolongFactor = self.DEFAULT_PROLONG + else: + self.prolongFactor = aProlongFactor + + #flags for inverted use of control pins + #used for some hardware + self.invertRST = 0 + self.invertTEST = 0 + self.swapRSTTEST = 0 + self.telosLatch = 0 + self.telosI2C = 0 + + self.z1 = 0 + + self.protocolMode = self.MODE_BSL + self.BSLMemAccessWarning = 0 #Default: no warning. + self.slowmode = 0 + + def comInit(self, port): + """Tries to open the serial port given and + initialises the port and variables. + The timeout and the number of allowed errors is multiplied by + 'aProlongFactor' after transmission of a command to give + plenty of time to the micro controller to finish the command. + Returns zero if the function is successful.""" + if DEBUG > 1: sys.stderr.write("* comInit()\n") + self.seqNo = 0 + self.reqNo = 0 + self.rxPtr = 0 + self.txPtr = 0 + # Startup-Baudrate: 9600,8,E,1, 1s timeout + self.serialport = serial.Serial( + port, + 9600, + parity = serial.PARITY_EVEN, + timeout = self.timeout + ) + if DEBUG: sys.stderr.write("using serial port %r\n" % self.serialport.portstr) + #self.SetRSTpin() #enable power + #self.SetTESTpin() #enable power + self.serialport.flushInput() + self.serialport.flushOutput() + + def comDone(self): + """Closes the used serial port. + This function must be called at the end of a program, + otherwise the serial port might not be released and can not be + used in other programs. + Returns zero if the function is successful.""" + if DEBUG > 1: sys.stderr.write("* comDone()") + self.SetRSTpin(1) #disable power + self.SetTESTpin(0) #disable power + self.serialport.close() + + def comRxHeader(self): + """receive header and split data""" + if DEBUG > 1: sys.stderr.write("* comRxHeader()\n") + + hdr = self.serialport.read(1) + if not hdr: raise BSLException("Timeout") + rxHeader = ord(hdr) & 0xf0; + rxNum = ord(hdr) & 0x0f; + + if self.protocolMode == self.MODE_BSL: + self.reqNo = 0 + self.seqNo = 0 + rxNum = 0 + if DEBUG > 1: sys.stderr.write("* comRxHeader() OK\n") + return rxHeader, rxNum + + def comRxFrame(self, rxNum): + if DEBUG > 1: sys.stderr.write("* comRxFrame()\n") + rxFrame = chr(self.DATA_FRAME | rxNum) + + if DEBUG > 2: sys.stderr.write(" comRxFrame() header...\n") + rxFramedata = self.serialport.read(3) + if len(rxFramedata) != 3: raise BSLException("Timeout") + rxFrame = rxFrame + rxFramedata + + if DEBUG > 3: sys.stderr.write(" comRxFrame() check header...\n") + if rxFrame[1] == chr(0) and rxFrame[2] == rxFrame[3]: #Add. header info. correct? + rxLengthCRC = ord(rxFrame[2]) + 2 #Add CRC-Bytes to length + if DEBUG > 2: sys.stderr.write(" comRxFrame() receiving data, size: %s\n" % rxLengthCRC) + + rxFramedata = self.serialport.read(rxLengthCRC) + if len(rxFramedata) != rxLengthCRC: raise BSLException("Timeout") + rxFrame = rxFrame + rxFramedata + #Check received frame: + if DEBUG > 3: sys.stderr.write(" comRxFrame() crc check\n") + #rxLength+4: Length with header but w/o CRC: + checksum = self.calcChecksum(rxFrame, ord(rxFrame[2]) + 4) + if rxFrame[ord(rxFrame[2])+4] == chr(0xff & checksum) and \ + rxFrame[ord(rxFrame[2])+5] == chr(0xff & (checksum >> 8)): #Checksum correct? + #Frame received correctly (=> send next frame) + if DEBUG > 2: sys.stderr.write("* comRxFrame() OK\n") + return rxFrame + else: + if DEBUG: sys.stderr.write(" comRxFrame() Checksum wrong\n") + else: + if DEBUG: sys.stderr.write(" comRxFrame() Header corrupt %r" % rxFrame) + raise BSLException(self.ERR_COM) #Frame has errors! + + def comTxHeader(self, txHeader): + """send header""" + if DEBUG > 1: sys.stderr.write("* txHeader()\n") + self.serialport.write(txHeader) + + def comTxRx(self, cmd, dataOut, length): + """Sends the command cmd with the data given in dataOut to the + microcontroller and expects either an acknowledge or a frame + with result from the microcontroller. The results are stored + in dataIn (if not a NULL pointer is passed). + In this routine all the necessary protocol stuff is handled. + Returns zero if the function was successful.""" + if DEBUG > 1: sys.stderr.write("* comTxRx()\n") + txFrame = [] + rxHeader = 0 + rxNum = 0 + + dataOut = list(dataOut) #convert to a list for simpler data fill in + #Transmitting part ---------------------------------------- + #Prepare data for transmit + if (length % 2) != 0: + #/* Fill with one byte to have even number of bytes to send */ + if self.protocolMode == self.MODE_BSL: + dataOut.append(0xFF) #fill with 0xFF + else: + dataOut.append(0) #fill with zero + + txFrame = "%c%c%c%c" % (self.DATA_FRAME | self.seqNo, cmd, len(dataOut), len(dataOut)) + + self.reqNo = (self.seqNo + 1) % self.MAX_FRAME_COUNT + + txFrame = txFrame + string.join(dataOut,'') + checksum = self.calcChecksum(txFrame, length + 4) + txFrame = txFrame + chr(checksum & 0xff) + txFrame = txFrame + chr((checksum >> 8) & 0xff) + + accessAddr = (0x0212 + (checksum^0xffff)) & 0xfffe #0x0212: Address of wCHKSUM + if self.BSLMemAccessWarning and accessAddr < self.BSL_CRITICAL_ADDR: + sys.stderr.write("WARNING: This command might change data at address %04x or %04x!\n" % (accessAddr, accessAddr + 1)) + + self.serialport.flushInput() #clear receiving queue + #TODO: Check after each transmitted character, + #TODO: if microcontroller did send a character (probably a NAK!). + for c in txFrame: + self.serialport.write(c) + if DEBUG > 3: sys.stderr.write("\ttx %02x" % ord(c)) + #if self.serialport.inWaiting(): break #abort when BSL replies, probably NAK + else: + if DEBUG > 1: sys.stderr.write( " comTxRx() transmit OK\n") + + #Receiving part ------------------------------------------- + rxHeader, rxNum = self.comRxHeader() #receive header + if DEBUG > 1: sys.stderr.write(" comTxRx() rxHeader=0x%02x, rxNum=%d, seqNo=%d, reqNo=%s\n" % (rxHeader, rxNum, self.seqNo, self.reqNo)) + if rxHeader == self.DATA_ACK: #acknowledge/OK + if DEBUG > 2: sys.stderr.write(" comTxRx() DATA_ACK\n") + if rxNum == self.reqNo: + self.seqNo = self.reqNo + if DEBUG > 2: sys.stderr.write("* comTxRx() DATA_ACK OK\n") + return #Acknowledge received correctly => next frame + raise BSLException(self.ERR_FRAME_NUMBER) + elif rxHeader == self.DATA_NAK: #not acknowledge/error + if DEBUG > 2: sys.stderr.write("* comTxRx() DATA_NAK\n") + raise BSLException(self.ERR_RX_NAK) + elif rxHeader == self.DATA_FRAME: #receive data + if DEBUG > 2: sys.stderr.write("* comTxRx() DATA_FRAME\n") + if rxNum == self.reqNo: + rxFrame = self.comRxFrame(rxNum) + return rxFrame + raise BSLException(self.ERR_FRAME_NUMBER) + elif rxHeader == self.CMD_FAILED: #Frame ok, but command failed. + if DEBUG > 2: sys.stderr.write("* comTxRx() CMD_FAILED\n") + raise BSLException(self.ERR_CMD_FAILED) + + raise BSLException("Unknown header 0x%02x\nAre you downloading to RAM into an old device that requires the patch? Try option -U" % rxHeader) + + def SetDTR(self, level, invert): + """Controls DTR pin (0: GND; 1: VCC; unless inverted flag is set)""" + #print 'fucking the dtr' + if invert: + self.serialport.setDTR(not level) + else: + self.serialport.setDTR(level) + if self.slowmode: + time.sleep(0.040) + + def SetRTS(self, level, invert): + """Controls RTS pin (0: GND; 1: VCC; unless inverted flag is set)""" + if invert: + self.serialport.setRTS(not level) + else: + self.serialport.setRTS(level) + if self.slowmode: + time.sleep(0.040) + + def SetRSTpin(self, level=1): + """Controls RST/NMI pin (0: GND; 1: VCC; unless inverted flag is set)""" + if self.swapRSTTEST: + self.SetRTS(level, self.invertRST) + else: + self.SetDTR(level, self.invertRST) + + def SetTESTpin(self, level=1): + """Controls TEST pin (inverted on board: 0: VCC; 1: GND; unless inverted flag is set)""" + if self.swapRSTTEST: + self.SetDTR(level, self.invertTEST) + else: + self.SetRTS(level, self.invertTEST) + + + def writepicROM(self, address, data): + ''' Writes data to @address''' + for i in range(7,-1,-1): + self.picROMclock((address >> i) & 0x01) + self.picROMclock(0) + recbuf = 0 + for i in range(7,-1,-1): + s = ((data >> i) & 0x01) + #print s + if i < 1: + r = not self.picROMclock(s, True) + else: + r = not self.picROMclock(s) + recbuf = (recbuf << 1) + r + + self.picROMclock(0, True) + #k = 1 + #while not self.serial.getCTS(): + # pass + #time.sleep(0.1) + return recbuf + + def readpicROM(self, address): + ''' reads a byte from @address''' + for i in range(7,-1,-1): + self.picROMclock((address >> i) & 0x01) + self.picROMclock(1) + recbuf = 0 + r = 0 + for i in range(7,-1,-1): + r = self.picROMclock(0) + recbuf = (recbuf << 1) + r + self.picROMclock(r) + #time.sleep(0.1) + return recbuf + + def picROMclock(self, masterout, slow = False): + #print "setting masterout to "+str(masterout) + self.serialport.setRTS(masterout) + self.serialport.setDTR(1) + #time.sleep(0.02) + self.serialport.setDTR(0) + if slow: + time.sleep(0.02) + return self.serialport.getCTS() + + def picROMfastclock(self, masterout): + #print "setting masterout to "+str(masterout) + self.serialport.setRTS(masterout) + self.serialport.setDTR(1) + self.serialport.setDTR(0) + time.sleep(0.02) + return self.serialport.getCTS() + + def bslResetZ1(self, invokeBSL=0): + ''' + Applies BSL entry sequence on RST/NMI and TEST/VPP pins + Parameters: + invokeBSL = 1: complete sequence + invokeBSL = 0: only RST/NMI pin accessed + + By now only BSL mode is accessed + ''' + + if DEBUG > 1: sys.stderr.write("* bslReset(invokeBSL=%s)\n" % invokeBSL) + if invokeBSL: + #sys.stderr.write("in Z1 bsl reset...\n") + time.sleep(0.1) + self.writepicROM(0xFF, 0xFF) + time.sleep(0.1) + #sys.stderr.write("z1 bsl reset done...\n") + else: + #sys.stderr.write("in Z1 reset...\n") + time.sleep(0.1) + self.writepicROM(0xFF, 0xFE) + time.sleep(0.1) + #sys.stderr.write("z1 reset done...\n") + + def telosSetSCL(self, level): + self.serialport.setRTS(not level) + + def telosSetSDA(self, level): + self.serialport.setDTR(not level) + + def telosI2CStart(self): + self.telosSetSDA(1) + self.telosSetSCL(1) + self.telosSetSDA(0) + + def telosI2CStop(self): + self.telosSetSDA(0) + self.telosSetSCL(1) + self.telosSetSDA(1) + + def telosI2CWriteBit(self, bit): + self.telosSetSCL(0) + self.telosSetSDA(bit) + time.sleep(2e-6) + self.telosSetSCL(1) + time.sleep(1e-6) + self.telosSetSCL(0) + + def telosI2CWriteByte(self, byte): + self.telosI2CWriteBit( byte & 0x80 ); + self.telosI2CWriteBit( byte & 0x40 ); + self.telosI2CWriteBit( byte & 0x20 ); + self.telosI2CWriteBit( byte & 0x10 ); + self.telosI2CWriteBit( byte & 0x08 ); + self.telosI2CWriteBit( byte & 0x04 ); + self.telosI2CWriteBit( byte & 0x02 ); + self.telosI2CWriteBit( byte & 0x01 ); + self.telosI2CWriteBit( 0 ); # "acknowledge" + + def telosI2CWriteCmd(self, addr, cmdbyte): + self.telosI2CStart() + self.telosI2CWriteByte( 0x90 | (addr << 1) ) + self.telosI2CWriteByte( cmdbyte ) + self.telosI2CStop() + + def telosBReset(self,invokeBSL=0): + # "BSL entry sequence at dedicated JTAG pins" + # rst !s0: 0 0 0 0 1 1 + # tck !s1: 1 0 1 0 0 1 + # s0|s1: 1 3 1 3 2 0 + + # "BSL entry sequence at shared JTAG pins" + # rst !s0: 0 0 0 0 1 1 + # tck !s1: 0 1 0 1 1 0 + # s0|s1: 3 1 3 1 0 2 + if invokeBSL: + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + self.telosI2CWriteCmd(0,0) + else: + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + self.telosI2CWriteCmd(0,0) + time.sleep(0.250) #give MSP430's oscillator time to stabilize + self.serialport.flushInput() #clear buffers + + def bslReset(self, invokeBSL=0): + """Applies BSL entry sequence on RST/NMI and TEST/VPP pins + Parameters: + invokeBSL = 1: complete sequence + invokeBSL = 0: only RST/NMI pin accessed + + RST is inverted twice on boot loader hardware + TEST is inverted (only once) + Need positive voltage on DTR, RTS for power-supply of hardware""" + + #print 'goint to reset!' + + if self.telosI2C: + self.telosBReset(invokeBSL) + return + + if self.z1: + if DEBUG > 1: sys.stderr.write("* entering bsl with z1\n") + self.bslResetZ1(invokeBSL) + return + + if DEBUG > 1: sys.stderr.write("* bslReset(invokeBSL=%s)\n" % invokeBSL) + self.SetRSTpin(1) #power suply + self.SetTESTpin(1) #power suply + time.sleep(0.250) #charge capacitor on boot loader hardware + + if self.telosLatch: + self.SetTESTpin(0) + self.SetRSTpin(0) + self.SetTESTpin(1) + + self.SetRSTpin(0) #RST pin: GND + if invokeBSL: + self.SetTESTpin(1) #TEST pin: GND + self.SetTESTpin(0) #TEST pin: Vcc + self.SetTESTpin(1) #TEST pin: GND + self.SetTESTpin(0) #TEST pin: Vcc + self.SetRSTpin (1) #RST pin: Vcc + self.SetTESTpin(1) #TEST pin: GND + else: + self.SetRSTpin(1) #RST pin: Vcc + time.sleep(0.250) #give MSP430's oscillator time to stabilize + + self.serialport.flushInput() #clear buffers + + def bslSync(self,wait=0): + """Transmits Synchronization character and expects to receive Acknowledge character + if wait is 0 it must work the first time. otherwise if wait is 1 + it is retried (forever). + """ + loopcnt = 5 #Max. tries to get synchronization + + if DEBUG > 1: sys.stderr.write("* bslSync(wait=%d)\n" % wait) + while wait or loopcnt: + loopcnt = loopcnt - 1 #count down tries + self.serialport.flushInput() #clear input, in case a prog is running + + self.serialport.write(chr(self.BSL_SYNC)) #Send synchronization byte + c = self.serialport.read(1) #read answer + if c == chr(self.DATA_ACK): #ACk + if DEBUG > 1: sys.stderr.write(" bslSync() OK\n") + return #Sync. successful + elif not c: #timeout + if loopcnt > 4: + if DEBUG > 1: + sys.stderr.write(" bslSync() timeout, retry ...\n") + elif loopcnt == 4: + #nmi may have caused the first reset to be ignored, try again + self.bslReset(0) + self.bslReset(1) + elif loopcnt > 0: + if DEBUG > 1: + sys.stderr.write(" bslSync() timeout, retry ...\n") + else : + if DEBUG > 1: + sys.stderr.write(" bslSync() timeout\n") + else: #garbage + if DEBUG > 1: sys.stderr.write(" bslSync() failed (0x%02x), retry ...\n" % ord(c)) + + raise BSLException(self.ERR_BSL_SYNC) #Sync. failed + + def bslTxRx(self, cmd, addr, length = 0, blkout = None, wait=0): + """Transmits a command (cmd) with its parameters: + start-address (addr), length (len) and additional + data (blkout) to boot loader. + wait specified if the bsl sync should be tried once or + repeated, forever + Parameters return by boot loader are passed via blkin. + """ + if DEBUG > 1: sys.stderr.write("* bslTxRx()\n") + + if cmd == self.BSL_TXBLK: + #Align to even start address + if (addr % 2) != 0: + addr = addr - 1 #Decrement address and + blkout = chr(0xFF) + blkOut #fill first byte of blkout with 0xFF + length = length + 1 + #Make sure that len is even + if (length % 2) != 0: + blkout = blkout + chr(0xFF) #Inc. len and fill last byte of blkout with 0xFF + length = length + 1 + + elif cmd == self.BSL_RXBLK: + #Align to even start address + if (addr % 2) != 0: + addr = addr - 1 #Decrement address but + length = length + 1 #request an additional byte + #Make sure that len is even + if (length % 2) != 0: + length = length + 1 + + #if cmd == self.BSL_TXBLK or cmd == self.BSL_TXPWORD: + # length = len + 4 + + #Add necessary information data to frame + dataOut = struct.pack("= 1: + #Read one line + l = file.readline() + if not l: break #EOF + l = l.strip() + if l[0] == 'q': break + elif l[0] == '@': #if @ => new address => send frame and set new addr. + #create a new segment + if segmentdata: + self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) + startAddr = int(l[1:],16) + segmentdata = [] + else: + for i in string.split(l): + segmentdata.append(chr(int(i,16))) + if segmentdata: + self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) + + def loadELF(self, file): + """load data from a (opened) file in ELF object format. + File must be seekable""" + import elf + obj = elf.ELFObject() + obj.fromFile(file) + if obj.e_type != elf.ELFObject.ET_EXEC: + raise Exception("No executable") + for section in obj.getSections(): + if DEBUG: + sys.stderr.write("ELF section %s at 0x%04x %d bytes\n" % (section.name, section.lma, len(section.data))) + if len(section.data): + self.segments.append( Segment(section.lma, section.data) ) + + def loadFile(self, filename): + """fill memory with the contents of a file. file type is determined from extension""" + #TODO: do a contents based detection + if filename[-4:].lower() == '.txt': + self.loadTIText(open(filename, "rb")) + elif filename[-4:].lower() in ('.a43', '.hex'): + self.loadIHex(open(filename, "rb")) + else: + self.loadELF(open(filename, "rb")) + + def getMemrange(self, fromadr, toadr): + """get a range of bytes from the memory. unavailable values are filled with 0xff.""" + res = '' + toadr = toadr + 1 #python indxes are excluding end, so include it + while fromadr < toadr: + #print "fromto: %04x %04x" % (fromadr, toadr) + for seg in self.segments: + #print seg + segend = seg.startaddress + len(seg.data) + if seg.startaddress <= fromadr and fromadr < segend: + #print "startok 0x%04x %d" % (seg.startaddress, len(seg.data)) + #print ("0x%04x "*3) % (segend, fromadr, toadr) + if toadr > segend: #not all data in segment + #print "out of segment" + catchlength = segend-fromadr + else: + catchlength = toadr-fromadr + #print toadr-fromadr + #print catchlength + res = res + seg.data[fromadr-seg.startaddress : fromadr-seg.startaddress+catchlength] + fromadr = fromadr + catchlength #adjust start + if len(res) >= toadr-fromadr: + break#return res + else: + res = res + chr(255) + fromadr = fromadr + 1 #adjust start + #print "fill FF" + #print "res: %r" % res + return res + + +class BootStrapLoader(LowLevel): + """higher level Bootstrap Loader functions.""" + + ERR_VERIFY_FAILED = "Error: verification failed" + ERR_ERASE_CHECK_FAILED = "Error: erase check failed" + + ACTION_PROGRAM = 0x01 #Mask: program data + ACTION_VERIFY = 0x02 #Mask: verify data + ACTION_ERASE_CHECK = 0x04 #Mask: erase check + + #Max. bytes sent within one frame if parsing a TI TXT file. + #( >= 16 and == n*16 and <= MAX_DATA_BYTES!) + MAXDATA = 240-16 + + + def __init__(self, *args, **kargs): + LowLevel.__init__(self, *args, **kargs) + self.byteCtr = 0 + self.meraseCycles = 1 + self.patchRequired = 0 + self.patchLoaded = 0 + self.bslVer = 0 + self.passwd = None + self.data = None + self.maxData = self.MAXDATA + self.cpu = None + self.pwdsent = False + + + def preparePatch(self): + """prepare to download patch""" + if DEBUG > 1: sys.stderr.write("* preparePatch()\n") + + if self.patchLoaded: + #Load PC with 0x0220. + #This will invoke the patched bootstrap loader subroutines. + self.bslTxRx(self.BSL_LOADPC, #Command: Load PC + 0x0220) #Address to load into PC + self.BSLMemAccessWarning = 0 #Error is removed within workaround code + return + + def postPatch(self): + """setup after the patch is loaded""" + if DEBUG > 1: sys.stderr.write("* postPatch()\n") + if self.patchLoaded: + self.BSLMemAccessWarning = 1 #Turn warning back on. + + + def verifyBlk(self, addr, blkout, action): + """verify memory against data or 0xff""" + if DEBUG > 1: sys.stderr.write("* verifyBlk()\n") + + if action & self.ACTION_VERIFY or action & self.ACTION_ERASE_CHECK: + if DEBUG: sys.stderr.write(" Check starting at 0x%04x, %d bytes ... \n" % (addr, len(blkout))) + + self.preparePatch() + blkin = self.bslTxRx(self.BSL_RXBLK, addr, len(blkout)) + self.postPatch() + + for i in range(len(blkout)): + if action & self.ACTION_VERIFY: + #Compare data in blkout and blkin + if blkin[i] != blkout[i]: + sys.stderr.write("Verification failed at 0x%04x (0x%02x, 0x%02x)\n" % (addr+i, ord(blkin[i]), ord(blkout[i]))) + sys.stderr.flush() + raise BSLException(self.ERR_VERIFY_FAILED) #Verify failed! + continue + elif action & self.ACTION_ERASE_CHECK: + #Compare data in blkin with erase pattern + if blkin[i] != chr(0xff): + sys.stderr.write("Erase Check failed at 0x%04x (0x%02x)\n" % (addr+i, ord(blkin[i]))) + sys.stderr.flush() + raise BSLException(self.ERR_ERASE_CHECK_FAILED) #Erase Check failed! + continue + def readBlk(self,adr,len): + """Read a block of memory.""" + blkin = self.bslTxRx(self.BSL_RXBLK, addr, len(blkout)) + + def programBlk(self, addr, blkout, action): + """program a memory block""" + if DEBUG > 1: sys.stderr.write("* programBlk()\n") + + #Check, if specified range is erased + self.verifyBlk(addr, blkout, action & self.ACTION_ERASE_CHECK) + + if action & self.ACTION_PROGRAM: + if DEBUG: sys.stderr.write(" Program starting at 0x%04x, %i bytes ...\n" % (addr, len(blkout))) + self.preparePatch() + #Program block + self.bslTxRx(self.BSL_TXBLK, addr, len(blkout), blkout) + self.postPatch() + + #Verify block + self.verifyBlk(addr, blkout, action & self.ACTION_VERIFY) + + #segments: + #list of tuples or lists: + #segements = [ (addr1, [d0,d1,d2,...]), (addr2, [e0,e1,e2,...])] + def programData(self, segments, action): + """programm or verify data""" + if DEBUG > 1: sys.stderr.write("* programData()\n") + for seg in segments: + currentAddr = seg.startaddress + offsetAddr = 0 + if (seg.startaddress > 0xFFFF): + offsetAddr = seg.startaddress >> 16 + self.bslTxRx(self.BSL_SETMEMOFFSET, 0, offsetAddr) + currentAddr = currentAddr - (offsetAddr << 16) + pstart = 0 + while pstart len(seg.data): + length = len(seg.data) - pstart + self.programBlk(currentAddr, seg.data[pstart:pstart+length], action) + pstart = pstart + length + currentAddr = currentAddr + length + self.byteCtr = self.byteCtr + length #total sum + + def uploadData(self, startaddress, size, wait=0): + """upload a datablock""" + if DEBUG > 1: sys.stderr.write("* uploadData()\n") + data = '' + pstart = 0 + while pstart size: + length = size - pstart + data = data + self.bslTxRx(self.BSL_RXBLK, + pstart+startaddress, + length, + wait=wait)[:-2] #cut away checksum + pstart = pstart + length + return data + + def txPasswd(self, passwd=None, wait=0): + """transmit password, default if None is given.""" + if DEBUG > 1: sys.stderr.write("* txPassword(%r)\n" % passwd) + if passwd is None or self.pwdsent: + #Send "standard" password to get access to protected functions. + sys.stderr.write("Transmit default password ...\n") + sys.stderr.flush() + #Flash is completely erased, the contents of all Flash cells is 0xff + passwd = chr(0xff)*32 + else: + #sanity check of password + if len(passwd) != 32: + raise ValueError, "password has wrong length (%d)\n" % len(passwd) + sys.stderr.write('Transmit password ...\n') + sys.stderr.flush() + #send the password + self.bslTxRx(self.BSL_TXPWORD, #Command: Transmit Password + 0xffe0, #Address of interupt vectors + 0x0020, #Number of bytes + passwd, #password + wait=wait) #if wait is 1, try to sync forever + self.pwdsent = True + + + def getNewPassword(self): + print 'getting new password' + newpassword = self.bslTxRx(self.BSL_RXBLK, 0xffe0, 0x0020) + return newpassword + + + def writeCalibTables(self): + print 'writing new tables' + print CALIB_TABLES + calibtables = ["84C016FEFFFFFFFFFFFFFFFFFFFFFFFF", + "FFFFFFFFFFFFFFFFFFFF100880000001", + "7E270B790DAA7E4D06DF083308FEFFFF", + "FFFFFFFFFFFF08018F958E9A8D8886D1"] + self.programBlk(0x10C0, "84C016FEFFFFFFFFFFFFFFFFFFFFFFFF", self.ACTION_PROGRAM) + self.programBlk(0x10D0, "FFFFFFFFFFFFFFFFFFFF100880000001", self.ACTION_PROGRAM) + self.programBlk(0x10E0, "7E270B790DAA7E4D06DF083308FEFFFF", self.ACTION_PROGRAM) + self.programBlk(0x10F0, "FFFFFFFFFFFF08018F958E9A8D8886D1", self.ACTION_PROGRAM) + + def writeCalibTables2(self): + print 'writing new tables 2ond part' + #self.programBlk(0x10C0, "84C016FEFFFFFFFFFFFFFFFFFFFFFFFF", self.ACTION_PROGRAM) + #self.programBlk(0x10D0, "FFFFFFFFFFFFFFFFFFFF100880000001", self.ACTION_PROGRAM) + #self.programBlk(0x10E0, "7E270B790DAA7E4D06DF083308FEFFFF", self.ACTION_PROGRAM) + #self.programBlk(0x10F0, "FFFFFFFFFFFF08018F958E9A8D8886D1", self.ACTION_PROGRAM) + + + #----------------------------------------------------------------- + + def actionMassErase(self): + """Erase the flash memory completely (with mass erase command)""" + sys.stderr.write("Mass Erase...\n") + sys.stderr.flush() + self.bslReset(1) #Invoke the boot loader. + for i in range(self.meraseCycles): + if i == 1: sys.stderr.write("Additional Mass Erase Cycles...\n") + self.bslTxRx(self.BSL_MERAS, #Command: Mass Erase + 0xff00, #Any address within flash memory. + 0xa506) #Required setting for mass erase! + self.passwd = None #No password file required! + #print "Mass Erase complete" + #Transmit password to get access to protected BSL functions. + self.txPasswd() + + def actionMainErase(self): + """Erase the main flash memory only""" + sys.stderr.write("Main Erase...\n") + sys.stderr.flush() + self.bslTxRx(self.BSL_ERASE, #Command: Segment Erase + 0xfffe, #Any address within flash memory. + 0xa504) #Required setting for main erase! + #self.passwd = None #Password gets erased WHY?? + + + + def actionStartBSL(self, usepatch=1, adjsp=1, replacementBSL=None, forceBSL=0, mayuseBSL=0, speed=None, bslreset=1): + """start BSL, download patch if desired and needed, adjust SP if desired""" + sys.stderr.write("Invoking BSL...\n") + sys.stderr.flush() + + #for '30, invertTEST=0, else =1 + if bslreset: + #detext if is z1? + self.bslReset(1) #Invoke the boot loader. + + + if(self.z1): + ''' recover password from pic''' + + self.txPasswd(self.passwd) #transmit password + + #Read actual bootstrap loader version. + #sys.stderr.write("Reading BSL version ...\n") + blkin = self.bslTxRx(self.BSL_RXBLK, #Command: Read/Receive Block + 0x0ff0, #Start address + 16) #No. of bytes to read + dev_id, bslVerHi, bslVerLo = struct.unpack(">H8xBB4x", blkin[:-2]) #cut away checksum and extract data + self.dev_id=dev_id; + + + if self.cpu is None: #cpy type forced? + if deviceids.has_key(dev_id): + self.cpu = deviceids[dev_id] #try to autodectect CPU type + + if DEBUG: + sys.stderr.write("Autodetect successful: %04x -> %s\n" % (dev_id, self.cpu)) + else: + sys.stderr.write("Autodetect failed! Unkown ID: %04x. Trying to continue anyway.\n" % dev_id) + self.cpu = F1x #assume something and try anyway.. + + sys.stderr.write("Current bootstrap loader version: %x.%x (Device ID: %04x)\n" % (bslVerHi, bslVerLo, dev_id)) + sys.stderr.flush() + self.bslVer = (bslVerHi << 8) | bslVerLo + + if self.bslVer <= 0x0110: #check if patch is needed + self.BSLMemAccessWarning = 1 + else: + self.BSLMemAccessWarning = 0 #Fixed in newer versions of BSL. + + if self.bslVer <= 0x0130 and adjsp: + #only do this on BSL where it's needed to prevent + #malfunction with F4xx devices/ newer ROM-BSLs + + #Execute function within bootstrap loader + #to prepare stack pointer for the following patch. + #This function will lock the protected functions again. + sys.stderr.write("Adjust SP. Load PC with 0x0C22 ...\n") + self.bslTxRx(self.BSL_LOADPC, #Command: Load PC + 0x0C22) #Address to load into PC + #Re-send password to re-gain access to protected functions. + self.txPasswd(self.passwd) + + #get internal BSL replacement if needed or forced by the user + #required if speed is set but an old BSL is in the device + #if a BSL is given by the user, that one is used and not the internal one + if ((mayuseBSL and speed and self.bslVer < 0x0150) or forceBSL) and replacementBSL is None: + replacementBSL = Memory() #File to program + if self.cpu == F4x: + if DEBUG: + sys.stderr.write("Using built in BSL replacement for F4x devices\n") + sys.stderr.flush() + replacementBSL.loadTIText(cStringIO.StringIO(F4X_BSL)) #parse embedded BSL + else: + if DEBUG: + sys.stderr.write("Using built in BSL replacement for F1x devices\n") + sys.stderr.flush() + replacementBSL.loadTIText(cStringIO.StringIO(F1X_BSL)) #parse embedded BSL + + #now download the new BSL, if allowed and needed (version lower than the + #the replacement) or forced + if replacementBSL is not None: + self.actionDownloadBSL(replacementBSL) + + #debug message with the real BSL version in use (may have changed after replacement BSL) + if DEBUG: + sys.stderr.write("Current bootstrap loader version: 0x%04x\n" % (self.bslVer,)) + sys.stderr.flush() + + #now apply workarounds or patches if BSL in use requires that + if self.bslVer <= 0x0110: #check if patch is needed + if usepatch: #test if patch is desired + sys.stderr.write("Patch for flash programming required!\n") + self.patchRequired = 1 + + sys.stderr.write("Load and verify patch ...\n") + sys.stderr.flush() + #Programming and verification is done in one pass. + #The patch file is only read and parsed once. + segments = Memory() #data to program + segments.loadTIText(cStringIO.StringIO(PATCH)) #parse embedded patch + #program patch + self.programData(segments, self.ACTION_PROGRAM | self.ACTION_VERIFY) + self.patchLoaded = 1 + else: + if DEBUG: + sys.stderr.write("Device needs patch, but not applied (usepatch is false).\n") #message if not patched + + #should the baudrate be changed? + if speed is not None: + self.actionChangeBaudrate(speed) #change baudrate + + def actionDownloadBSL(self, bslsegments): + sys.stderr.write("Load new BSL into RAM...\n") + sys.stderr.flush() + self.programData(bslsegments, self.ACTION_PROGRAM) + sys.stderr.write("Verify new BSL...\n") + sys.stderr.flush() + self.programData(bslsegments, self.ACTION_VERIFY) #File to verify + + #Read startvector of bootstrap loader + #blkin = self.bslTxRx(self.BSL_RXBLK, 0x0300, 2) + #blkin = self.bslTxRx(self.BSL_RXBLK, 0x0220, 2) + blkin = self.bslTxRx(self.BSL_RXBLK, bslsegments[0].startaddress, 2) + startaddr = struct.unpack("%s" % (firmware[self.dev_id],fn)) + + fw=Memory(fn); + #fw.loadIhex(open(fn,"rb")); + + sys.stderr.write("Program ...\n") + sys.stderr.flush() + self.programData(fw, self.ACTION_PROGRAM | self.ACTION_VERIFY) + sys.stderr.write("%i bytes programmed.\n" % self.byteCtr) + sys.stderr.flush() + + def actionVerify(self): + """Verify programmed data""" + if self.data is not None: + sys.stderr.write("Verify ...\n") + sys.stderr.flush() + self.programData(self.data, self.ACTION_VERIFY) + else: + raise BSLException, "verify without data not possible" + + def actionReset(self): + """perform a reset, start user programm""" + sys.stderr.write("Reset device ...\n") + sys.stderr.flush() + self.bslReset(0) #only reset + + def actionRun(self, address=0x220): + """start program at specified address""" + sys.stderr.write("Load PC with 0x%04x ...\n" % address) + sys.stderr.flush() + self.bslTxRx(self.BSL_LOADPC, #Command: Load PC + address) #Address to load into PC + + #table with values from slaa089a.pdf + bauratetable = { + F1x: { + 9600:[0x8580, 0x0000], + 19200:[0x86e0, 0x0001], + 38400:[0x87e0, 0x0002], + }, + F2x: { + 9600:[0x8580, 0x0000], + 19200:[0x8B00, 0x0001], + 38400:[0x8C80, 0x0002], + }, + F4x: { + 9600:[0x9800, 0x0000], + 19200:[0xb000, 0x0001], + 38400:[0xc800, 0x0002], + }, + } + def actionChangeBaudrate(self, baudrate=9600): + """change baudrate. first the command is sent, then the comm + port is reprogrammed. only possible with newer MSP430-BSL versions. + (ROM >=1.6, downloadable >=1.5)""" + try: + baudconfigs = self.bauratetable[self.cpu] + except KeyError: + raise ValueError, "unknown CPU type %s, can't switch baudrate" % self.cpu + try: + a,l = baudconfigs[baudrate] + except KeyError: + raise ValueError, "baudrate not valid. valid values are %r" % baudconfigs.keys() + + sys.stderr.write("Changing baudrate to %d ...\n" % baudrate) + sys.stderr.flush() + self.bslTxRx(self.BSL_CHANGEBAUD, #Command: change baudrate + a, l) #args are coded in adr and len + self.serialport.flush() + time.sleep(0.010) #recomended delay + self.serialport.baudrate = baudrate + + def actionReadBSLVersion(self): + """informational output of BSL version number. + (newer MSP430-BSLs only)""" + ans = self.bslTxRx(self.BSL_TXVERSION, 0) #Command: receive version info + #the following values are in big endian style!!! + family_type, bsl_version = struct.unpack(">H8xH4x", ans[:-2]) #cut away checksum and extract data + print "Device Type: 0x%04x\nBSL version: 0x%04x\n" % (family_type, bsl_version) + + def actionWriteNewPassword(self): + passwd = self.getNewPassword() + #print passwd + self.picWritePassword(passwd) + + def actionRecoverPassword(self): + p = self.picRecoverPassword() + #print p + self.passwd = p + + def picRecoverPassword(self): + ''' recovers password from picrom''' + print 'recovering pic password', + p = '' + + for i in range(0,32): + c = self.readpicROM(i) + print c, + p = p + chr(c) + + print 'done' + return p + + def picWritePassword(self, password): + ''' writes a new password to picrom''' + print 'writing new password', + for i in range(0,32): + c = ord(password[i]) + print c, + self.writepicROM(i, c) + print 'done' + + +def usage(): + """print some help message""" + sys.stderr.write(""" +USAGE: %s [options] [file] +Version: %s + +If "-" is specified as file the data is read from the stdinput. +A file ending with ".txt" is considered to be in TIText format, +'.a43' and '.hex' as IntelHex and all other filenames are +considered as ELF files. + +General options: + -h, --help Show this help screen. + -c, --comport=port Specify the communication port to be used. + (Default is 0) + 0->COM1 / ttyS0 + 1->COM2 / ttyS1 + etc. + -P, --password=file Specify a file with the interrupt vectors that + are used as password. This can be any file that + has previously been used to program the device. + (e.g. -P INT_VECT.TXT). + -f, --framesize=num Max. number of data bytes within one transmitted + frame (16 to 240 in steps of 16) (e.g. -f 240). + -m, --erasecycles=num Number of mass erase cycles (default is 1). Some + old F149 devices need additional erase cycles. + On newer devices it is no longer needed. (e.g. for + an old F149: -m20) + -U, --unpatched Do not download the BSL patch, even when it is + needed. This is used when a program is downloaded + into RAM and executed from there (and where flash + programming is not needed.) + -D, --debug Increase level of debug messages. This won't be + very useful for the average user... + -I, --intelhex Force fileformat to IntelHex + -T, --titext Force fileformat to be TIText + -N, --notimeout Don't use timeout on serial port (use with care) + -B, --bsl=bsl.txt Load and use new BSL from the TI Text file + -S, --speed=baud Reconfigure speed, only possible with newer + MSP403-BSL versions (>1.5, read slaa089a.pdf for + details). If the --bsl option is not used, an + internal BSL replacement will be loaded. + Needs a target with at least 2kB RAM! + Possible values are 9600, 19200, 38400 + (default 9600) + -1, --f1x Specify CPU family, in case autodetect fails + -2, --f2x Specify CPU family, in case autodetect fails + -4, --f4x Specify CPU family, in case autodetect fails + --F1x and --f2x are only needed when the "change + baudrate" feature is used and the autodetect feature + fails. If the device ID that is uploaded is known, it + has precedence to the command line option. + --invert-reset Invert signal on RST pin (used for some BSL hardware) + --invert-test Invert signal on TEST/TCK pin (used for some BSL + hardware) + --swap-reset-test Swap the RST and TEST pins (used for some BSL hardware) + --telos-latch Special twiddle in BSL reset for Telos hardware + --telos-i2c DTR/RTS map via an I2C switch to TCK/RST in Telos Rev.B + --telos Implies options --invert-reset, --invert-test, + --swap-reset-test, and --telos-latch + --telosb Implies options --swap-reset-test, --telos-i2c, + --no-BSL-download, and --speed=38400 + --goodfet10 + --goodfet20 + --goodfet30 + --tmote Identical operation to --telosb + --z1 Bootstrap a Z1 + --no-BSL-download Do not download replacement BSL (disable automatic) + --force-BSL-download Download replacement BSL even if not needed (the one + in the device would have the required features) + --slow Add delays when operating the conrol pins. Useful if + the pins/circuit has high capacitance. + +Program Flow Specifiers: + -e, --masserase Mass Erase (clear all flash memory) + -E, --erasecheck Erase Check by file + -p, --program Program file + -v, --verify Verify by file + +The order of the above options matters! The table is ordered by normal +execution order. For the options "Epv" a file must be specified. +Program flow specifiers default to "pvr" if a file is given. +Don't forget to specify "e" or "eE" when programming flash! + +Data retreiving: + -u, --upload=addr Upload a datablock (see also: -s). + -s, --size=num Size of the data block do upload. (Default is 2) + -x, --hex Show a hexadecimal display of the uploaded data. + (Default) + -b, --bin Get binary uploaded data. This can be used + to redirect the output into a file. + +Do before exit: + -g, --go=address Start programm execution at specified address. + This implies option --wait. + -r, --reset Reset connected MSP430. Starts application. + This is a normal device reset and will start + the programm that is specified in the reset + vector. (see also -g) + -w, --wait Wait for before closing serial port. + +If it says "NAK received" it's probably because you specified no or a +wrong password. +""" % (sys.argv[0], VERSION)) + +#add some arguments to a function, but don't call it yet, instead return +#a wrapper object for later invocation +class curry: + """create a callable with some arguments specified in advance""" + def __init__(self, fun, *args, **kwargs): + self.fun = fun + self.pending = args[:] + self.kwargs = kwargs.copy() + + def __call__(self, *args, **kwargs): + if kwargs and self.kwargs: + kw = self.kwargs.copy() + kw.update(kwargs) + else: + kw = kwargs or self.kwargs + return apply(self.fun, self.pending + args, kw) + + def __repr__(self): + #first try if it a function + try: + return "curry(%s, %r, %r)" % (self.fun.func_name, self.pending, self.kwargs) + except AttributeError: + #fallback for callable classes + return "curry(%s, %r, %r)" % (self.fun, self.pending, self.kwargs) + +def hexify(line, bytes, width=16): + return '%04x %s%s %s' % ( + line, + ('%02x '*len(bytes)) % tuple(bytes), + ' '* (width-len(bytes)), + ('%c'*len(bytes)) % tuple(map(lambda x: (x>=32 and x<127) and x or ord('.'), bytes)) + ) + +#Main: +def main(itest=1): + global DEBUG + import getopt + filetype = None + filename = None + comPort = None #Default setting. + speed = None + unpatched = 0 + reset = 0 + wait = 0 #wait at the end + goaddr = None + bsl = BootStrapLoader() + toinit = [] + todo = [] + startaddr = None + size = 2 + hexoutput = 1 + notimeout = 0 + bslrepl = None + mayuseBSL = 1 + forceBSL = 0 + dumpivt = 0 + dumpinfo = 0 + + bsl.invertRST = 1 + bsl.invertTEST = itest + + if comPort is None and os.environ.get("GOODFET")!=None: + glob_list = glob.glob(os.environ.get("GOODFET")); + if len(glob_list) > 0: + comPort = glob_list[0]; + if comPort is None: + glob_list = glob.glob("/dev/tty.usbserial*"); + if len(glob_list) > 0: + comPort = glob_list[0]; + if comPort is None: + glob_list = glob.glob("/dev/ttyUSB*"); + if len(glob_list) > 0: + comPort = glob_list[0]; + + + sys.stderr.write("MSP430 Bootstrap Loader Version: %s\n" % VERSION) + + try: + opts, args = getopt.getopt(sys.argv[1:], + "hc:P:wf:m:neEpvrg:UDudsxbITNB:S:V14", + ["help", "comport=", "password=", "wait", "framesize=", + "erasecycles=", "masserase", "erasecheck", "program", + "verify", "reset", "go=", "unpatched", "debug", + "upload=", "download=", "size=", "hex", "bin", + "intelhex", "titext", "notimeout", "bsl=", "speed=", + "bslversion", "f1x", "f2x", "f4x", "invert-reset", "invert-test", + "swap-reset-test", "telos-latch", "telos-i2c", "telos", "telosb", + "tmote","no-BSL-download", "force-BSL-download", "slow", + "dumpivt", "dumpinfo", "fromweb", + "goodfet30", "goodfet20", "goodfet10", "z1", "mainerase" + ] + ) + except getopt.GetoptError: + # print help information and exit: + usage() + sys.exit(2) + + for o, a in opts: + if o in ("-h", "--help"): + usage() + sys.exit() + elif o in ("-c", "--comport"): + try: + comPort = int(a) #try to convert decimal + except ValueError: + comPort = a #take the string and let serial driver decide + elif o in ("-P", "--password"): + #extract password from file + bsl.passwd = Memory(a).getMemrange(0xffe0, 0xffff) + elif o in ("-w", "--wait"): + wait = 1 + elif o in ("--dumpivt"): + dumpivt=1; + elif o in ("--dumpinfo"): + dumpinfo=1; + elif o in ("-f", "--framesize"): + try: + maxData = int(a) #try to convert decimal + except ValueError: + sys.stderr.write("framesize must be a valid number\n") + sys.exit(2) + #Make sure that conditions for maxData are met: + #( >= 16 and == n*16 and <= MAX_DATA_BYTES!) + if maxData > BootStrapLoader.MAX_DATA_BYTES: + maxData = BootStrapLoader.MAX_DATA_BYTES + elif maxData < 16: + maxData = 16 + bsl.maxData = maxData - (maxData % 16) + sys.stderr.write( "Max. number of data bytes within one frame set to %i.\n" % maxData) + elif o in ("-m", "--erasecycles"): + try: + meraseCycles = int(a) #try to convert decimal + except ValueError: + sys.stderr.write("erasecycles must be a valid number\n") + sys.exit(2) + #sanity check of value + if meraseCycles < 1: + sys.stderr.write("erasecycles must be a positive number\n") + sys.exit(2) + if meraseCycles > 20: + sys.stderr.write("warning: erasecycles set to a large number (>20): %d\n" % meraseCycles) + sys.stderr.write( "Number of mass erase cycles set to %i.\n" % meraseCycles) + bsl.meraseCycles = meraseCycles + elif o in ("-e", "--masserase"): + toinit.append(bsl.actionMassErase) #Erase Flash + #todo.append(bsl.actionMainErase) #Erase Flash + elif o in ("-n", "--mainerase"): + todo.append(bsl.actionMainErase) #Erase Flash + #toinit.append(bsl.actionMassErase) #Erase Flash + elif o in ("-E", "--erasecheck"): + toinit.append(bsl.actionEraseCheck) #Erase Check (by file) + elif o in ("-p", "--program"): + #pass + todo.append(bsl.actionProgram) #Program file + if bsl.z1: + #todo.append(bsl.actionUnlockInfo) + #todo.append(bsl.writeCalibTables) + #todo.append(bsl.writeCalibTables2) + + #todo.append(bsl.actionWriteNewPassword) + pass + elif o in ("--fromweb"): + toinit.append(bsl.actionMassErase) #Erase Flash + todo.append(bsl.actionFromweb) #Program GoodFET code + elif o in ("-v", "--verify"): + todo.append(bsl.actionVerify) #Verify file + elif o in ("-r", "--reset"): + reset = 1 + elif o in ("-g", "--go"): + try: + goaddr = int(a) #try to convert decimal + except ValueError: + try: + goaddr = int(a[2:],16) #try to convert hex + except ValueError: + sys.stderr.write("go address must be a valid number\n") + sys.exit(2) + wait = 1 + elif o in ("-U", "--unpatched"): + unpatched = 1 + elif o in ("-D", "--debug"): + DEBUG = DEBUG + 1 + elif o in ("-u", "--upload"): + try: + startaddr = int(a) #try to convert decimal + except ValueError: + try: + startaddr = int(a,16) #try to convert hex + except ValueError: + sys.stderr.write("upload address must be a valid number\n") + sys.exit(2) + elif o in ("-s", "--size"): + try: + size = int(a) + except ValueError: + try: + size = int(a,16) + except ValueError: + sys.stderr.write("size must be a valid number\n") + sys.exit(2) + elif o in ("-x", "--hex"): + hexoutput = 1 + elif o in ("-b", "--bin"): + hexoutput = 0 + elif o in ("-I", "--intelhex"): + filetype = 0 + elif o in ("-T", "--titext"): + filetype = 1 + elif o in ("-N", "--notimeout"): + notimeout = 1 + elif o in ("-B", "--bsl"): + bslrepl = Memory() #File to program + bslrepl.loadFile(a) + elif o in ("-V", "--bslversion"): + todo.append(bsl.actionReadBSLVersion) #load replacement BSL as first item + elif o in ("-S", "--speed"): + try: + speed = int(a) #try to convert decimal + except ValueError: + sys.stderr.write("speed must be decimal number\n") + sys.exit(2) + elif o in ("-1", "--f1x"): + bsl.cpu = F1x + elif o in ("-2", "--f2x"): + bsl.cpu = F2x + elif o in ("-4", "--f4x"): + bsl.cpu = F4x + elif o in ("--invert-reset", ): + bsl.invertRST = 1 + elif o in ("--invert-test", ): + bsl.invertTEST = 1 + elif o in ("--swap-reset-test", ): + bsl.swapRSTTEST = 1 + elif o in ("--telos-latch", ): + bsl.telosLatch = 1 + elif o in ("--telos-i2c", ): + bsl.telosI2C = 1 + elif o in ("--telos", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + bsl.swapRSTTEST = 1 + bsl.telosLatch = 1 + elif o in ("--goodfet10", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + elif o in ("--goodfet20", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + elif o in ("--goodfet30", ): + bsl.invertRST = 1 + bsl.invertTEST = 0 + elif o in ("--telosb", ): + bsl.swapRSTTEST = 1 + bsl.telosI2C = 1 + mayuseBSL = 0 + speed = 38400 + elif o in ("--tmote", ): + bsl.swapRSTTEST = 1 + bsl.telosI2C = 1 + mayuseBSL = 0 + speed = 38400 + elif o in ("--z1", ): + bsl.z1 = 1 + speed = 38400 + #toinit.append(bsl.actionRecoverPassword) + elif o in ("--no-BSL-download", ): + mayuseBSL = 0 + elif o in ("--force-BSL-download", ): + forceBSL = 1 + elif o in ("--slow", ): + bsl.slowmode = 1 + + if len(args) == 0: + sys.stderr.write("Use -h for help\n"); + sys.stderr.write("Use --fromweb to upgrade a GoodFET.\n") + elif len(args) == 1: #a filename is given + if not todo: #if there are no actions yet + todo.extend([ #add some useful actions... + bsl.actionProgram, + bsl.actionVerify, + ]) + filename = args[0] + else: #number of args is wrong + usage() + sys.exit(2) + + if DEBUG: #debug infos + sys.stderr.write("Debug level set to %d\n" % DEBUG) + sys.stderr.write("Python version: %s\n" % sys.version) + + #sanity check of options + if notimeout and goaddr is not None and startaddr is not None: + sys.stderr.write("Option --notimeout can not be used together with both --upload and --go\n") + sys.exit(1) + + if notimeout: + sys.stderr.write("Warning: option --notimeout can cause improper function in some cases!\n") + bsl.timeout = 0 + + if goaddr and reset: + sys.stderr.write("Warning: option --reset ignored as --go is specified!\n") + reset = 0 + + if startaddr and reset: + sys.stderr.write("Warning: option --reset ignored as --upload is specified!\n") + reset = 0 + + sys.stderr.flush() + + #prepare data to download + bsl.data = Memory() #prepare downloaded data + if filetype is not None: #if the filetype is given... + if filename is None: + raise ValueError("no filename but filetype specified") + if filename == '-': #get data from stdin + file = sys.stdin + else: + file = open(filename, "rb") #or from a file + if filetype == 0: #select load function + bsl.data.loadIHex(file) #intel hex + elif filetype == 1: + bsl.data.loadTIText(file) #TI's format + else: + raise ValueError("illegal filetype specified") + else: #no filetype given... + if filename == '-': #for stdin: + bsl.data.loadIHex(sys.stdin) #assume intel hex + elif filename: + bsl.data.loadFile(filename) #autodetect otherwise + + if DEBUG > 3: sys.stderr.write("File: %r" % filename) + + bsl.comInit(comPort) #init port + + #initialization list + if toinit: #erase and erase check + if DEBUG: sys.stderr.write("Preparing device ...\n") + #bsl.actionStartBSL(usepatch=0, adjsp=0) #no workarounds needed + #if speed: bsl.actionChangeBaudrate(speed) #change baud rate as fast as possible + for f in toinit: f() + + if todo or goaddr or startaddr: + if DEBUG: sys.stderr.write("Actions ...\n") + #connect to the BSL + bsl.actionStartBSL( + usepatch=not unpatched, + replacementBSL=bslrepl, + forceBSL=forceBSL, + mayuseBSL=mayuseBSL, + speed=speed, + ) + + #work list + if todo: + if DEBUG > 0: #debug + #show a nice list of sheduled actions + sys.stderr.write("TODO list:\n") + for f in todo: + try: + sys.stderr.write(" %s\n" % f.func_name) + except AttributeError: + sys.stderr.write(" %r\n" % f) + for f in todo: f() #work through todo list + + if reset: #reset device first if desired + bsl.actionReset() + if dumpivt: + bsl.txPasswd(); #default pass + data=bsl.uploadData(0xc00,1024); + hex=""; + for c in data: + hex+=("%02x "%ord(c)); + print hex; + if dumpinfo: + bsl.txPasswd(); #default pass + data=bsl.uploadData(0x1000,256); + hex="@1000\n"; + for c in data: + hex+=("%02x "%ord(c)); + hex+="\nq\n"; + print hex; + + if goaddr is not None: #start user programm at specified address + bsl.actionRun(goaddr) #load PC and execute + + #upload datablock and output + if startaddr is not None: + if goaddr: #if a program was started... + #don't restart BSL but wait for the device to enter it itself + sys.stderr.write("Waiting for device to reconnect for upload: ") + sys.stderr.flush() + bsl.txPasswd(bsl.passwd, wait=1) #synchronize, try forever... + data = bsl.uploadData(startaddr, size) #upload data + else: + data = bsl.uploadData(startaddr, size) #upload data + if hexoutput: #depending on output format + m = 0 + while m < len(data): #print a hex display + print hexify(startaddr+m, map(ord,data[m:m+16])) + m = m + 16 + else: + sys.stdout.write(data) #binary output w/o newline! + wait = 0 #wait makes no sense as after the upload the device is still in BSL + + if wait: #wait at the end if desired + sys.stderr.write("Press ...\n") #display a prompt + sys.stderr.flush() + raw_input() #wait for newline + + bsl.comDone() #Release serial communication port + +if __name__ == '__main__': + try: + main(1) + except SystemExit: + raise #let pass exit() calls + except KeyboardInterrupt: + if DEBUG: raise #show full trace in debug mode + sys.stderr.write("user abort.\n") #short messy in user mode + sys.exit(1) #set errorlevel for script usage + except Exception, msg: #every Exception is caught and displayed + if DEBUG: raise #show full trace in debug mode + #sys.stderr.write("\nAn error occoured:\n%s\n" % msg) #short messy in user mode + #sys.exit(1) #set errorlevel for script usage + main(0);