//***************************************************************************** // // Poll the IRQ status register and return. // //***************************************************************************** uint32_t SHA2WaitForIRQFlags(uint32_t irqFlags) { uint32_t irqTrigger = 0; // Wait for the DMA operation to complete. Add a delay to make sure we are // not flooding the bus with requests too much. do { CPUdelay(1); } while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & irqFlags & (CRYPTO_IRQSTAT_DMA_IN_DONE_M | CRYPTO_IRQSTAT_RESULT_AVAIL_M))); // Save the IRQ trigger source irqTrigger = HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT); // Clear IRQ flags HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = irqFlags; while(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & irqFlags & (CRYPTO_IRQSTAT_DMA_IN_DONE_M | CRYPTO_IRQSTAT_RESULT_AVAIL_M)); return irqTrigger; }
//***************************************************************************** // //! Write the key into the Key Ram. // //***************************************************************************** uint32_t CRYPTOAesLoadKey(uint32_t *pui32AesKey, uint32_t ui32KeyLocation) { // // Check the arguments. // ASSERT((ui32KeyLocation == CRYPTO_KEY_AREA_0) | (ui32KeyLocation == CRYPTO_KEY_AREA_1) | (ui32KeyLocation == CRYPTO_KEY_AREA_2) | (ui32KeyLocation == CRYPTO_KEY_AREA_3) | (ui32KeyLocation == CRYPTO_KEY_AREA_4) | (ui32KeyLocation == CRYPTO_KEY_AREA_5) | (ui32KeyLocation == CRYPTO_KEY_AREA_6) | (ui32KeyLocation == CRYPTO_KEY_AREA_7)); // // Set current operating state of the Crypto module. // g_ui32CurrentAesOp = CRYPTO_AES_KEYL0AD; // // Disable the external interrupt to stop the interrupt form propagating // from the module to the CM3. // IntDisable(INT_CRYPTO); // // Enable internal interrupts. // HWREG(CRYPTO_BASE + CRYPTO_O_IRQTYPE) = CRYPTO_INT_LEVEL; HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN) = CRYPTO_IRQEN_DMA_IN_DONE | CRYPTO_IRQEN_RESULT_AVAIL; // // Configure master control module. // HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) &= (~CRYPTO_ALGSEL_KEY_STORE); HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) |= CRYPTO_ALGSEL_KEY_STORE; // // Clear any outstanding events. // HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = (CRYPTO_IRQCLR_DMA_IN_DONE | CRYPTO_IRQCLR_RESULT_AVAIL); // // Configure key store module for 128 bit operation. // HWREG(CRYPTO_BASE + CRYPTO_O_KEYSIZE) &= ~CRYPTO_KEYSIZE_SIZE_M; HWREG(CRYPTO_BASE + CRYPTO_O_KEYSIZE) |= KEY_STORE_SIZE_128; // // Enable keys to write (e.g. Key 0). // HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITEAREA) = (0x00000001 << ui32KeyLocation); // // Enable Crypto DMA channel 0. // HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0CTL) |= CRYPTO_DMACH0CTL_EN; // // Base address of the key in ext. memory. // HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32AesKey; // // Total key length in bytes (e.g. 16 for 1 x 128-bit key). // Writing the length of the key enables the DMA operation. // HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = KEY_BLENGTH; // // Wait for the DMA operation to complete. // do { CPUdelay(1); } while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & 0x00000001)); // // Check for errors in DMA and key store. // if((HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & (CRYPTO_IRQSTAT_DMA_BUS_ERR | CRYPTO_IRQSTAT_KEY_ST_WR_ERR)) == 0) { // // Acknowledge/clear the interrupt and disable the master control. // HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = (CRYPTO_IRQCLR_DMA_IN_DONE | CRYPTO_IRQCLR_RESULT_AVAIL); HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000; // // Check status, if error return error code. // if(HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITTENAREA) != (0x00000001 << ui32KeyLocation)) { g_ui32CurrentAesOp = CRYPTO_AES_NONE; return (AES_KEYSTORE_READ_ERROR); } } // // Return success. // g_ui32CurrentAesOp = CRYPTO_AES_NONE; return (AES_SUCCESS); }
//***************************************************************************** // //! Start an AES-ECB operation (encryption or decryption). // //***************************************************************************** uint32_t CRYPTOAesEcb(uint32_t *pui32MsgIn, uint32_t *pui32MsgOut, uint32_t ui32KeyLocation, bool bEncrypt, bool bIntEnable) { // // Set current operating state of the Crypto module. // g_ui32CurrentAesOp = CRYPTO_AES_ECB; // // Enable internal interrupts. // HWREG(CRYPTO_BASE + CRYPTO_O_IRQTYPE) = CRYPTO_INT_LEVEL; HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN) = CRYPTO_IRQEN_RESULT_AVAIL; // // Clear any outstanding interrupts. // HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = (CRYPTO_IRQCLR_DMA_IN_DONE | CRYPTO_IRQCLR_RESULT_AVAIL); // // If using interrupts clear any pending interrupts and enable interrupts // for the Crypto module. // if(bIntEnable) { IntPendClear(INT_CRYPTO); IntEnable(INT_CRYPTO); } // // Configure Master Control module. // HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = CRYPTO_ALGSEL_AES; // // // HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation; // //Wait until key is loaded to the AES module. // do { CPUdelay(1); } while((HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) & CRYPTO_KEYREADAREA_BUSY)); // // Check for Key store Read error. // if((HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT)& CRYPTO_KEY_ST_RD_ERR)) { return (AES_KEYSTORE_READ_ERROR); } // // Configure AES engine (program AES-ECB-128 encryption and no // initialization vector - IV). // if(bEncrypt) { HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = CRYPTO_AES128_ENCRYPT; } else { HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = CRYPTO_AES128_DECRYPT; } // // Write the length of the data. // HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = AES_ECB_LENGTH; HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0; // // Enable Crypto DMA channel 0. // HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0CTL) |= CRYPTO_DMACH0CTL_EN; // // Base address of the input data in ext. memory. // HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32MsgIn; // // Input data length in bytes, equal to the message. // HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = AES_ECB_LENGTH; // // Enable Crypto DMA channel 1. // HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1CTL) |= CRYPTO_DMACH1CTL_EN; // // Setup the address and length of the output data. // HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1EXTADDR) = (uint32_t)pui32MsgOut; HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = AES_ECB_LENGTH; // // Return success // return AES_SUCCESS; }
//***************************************************************************** // //! Start CCM operation // //***************************************************************************** uint32_t CRYPTOCcmAuthEncrypt(bool bEncrypt, uint32_t ui32AuthLength , uint32_t *pui32Nonce, uint32_t *pui32PlainText, uint32_t ui32PlainTextLength, uint32_t *pui32Header, uint32_t ui32HeaderLength, uint32_t ui32KeyLocation, uint32_t ui32FieldLength, bool bIntEnable) { uint8_t ui8InitVec[16]; uint32_t ui32CtrlVal; uint32_t i; uint32_t *pui32CipherText; // // Input address for the encryption engine is the same as the output. // pui32CipherText = pui32PlainText; // // Set current operating state of the Crypto module. // g_ui32CurrentAesOp = CRYPTO_AES_CCM; // // Disable global interrupt, enable local interrupt and clear any pending // interrupts. // IntDisable(INT_CRYPTO); HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = (CRYPTO_IRQCLR_DMA_IN_DONE | CRYPTO_IRQCLR_RESULT_AVAIL); // // Enable internal interrupts. // HWREG(CRYPTO_BASE + CRYPTO_O_IRQTYPE) = CRYPTO_INT_LEVEL; HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN) = CRYPTO_IRQEN_DMA_IN_DONE | CRYPTO_IRQCLR_RESULT_AVAIL; // // Configure master control module for AES operation. // HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = CRYPTO_ALGSEL_AES; // // Enable keys to read (e.g. Key 0). // HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation; // // Wait until key is loaded to the AES module. // do { CPUdelay(1); } while((HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) & CRYPTO_KEYREADAREA_BUSY)); // // Check for Key store Read error. // if((HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT)& CRYPTO_KEY_ST_RD_ERR)) { return (AES_KEYSTORE_READ_ERROR); } // // Prepare the initialization vector (IV), // Length of Nonce l(n) = 15 - ui32FieldLength. // ui8InitVec[0] = ui32FieldLength - 1; for(i = 0; i < 12; i++) { ui8InitVec[i + 1] = ((uint8_t*)pui32Nonce)[i]; } if(ui32FieldLength == 2) { ui8InitVec[13] = ((uint8_t*)pui32Nonce)[12]; } else { ui8InitVec[13] = 0; } ui8InitVec[14] = 0; ui8InitVec[15] = 0; // // Write initialization vector. // HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ((uint32_t *)&ui8InitVec)[0]; HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ((uint32_t *)&ui8InitVec)[1]; HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ((uint32_t *)&ui8InitVec)[2]; HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = ((uint32_t *)&ui8InitVec)[3]; // // Configure AES engine. // ui32CtrlVal = ((ui32FieldLength - 1) << CRYPTO_AESCTL_CCM_L_S); if ( ui32AuthLength >= 2 ) { ui32CtrlVal |= ((( ui32AuthLength - 2 ) >> 1 ) << CRYPTO_AESCTL_CCM_M_S ); }
int main(void) { uint8_t payload[ADVLEN]; //Disable JTAG to allow for Standby AONWUCJtagPowerOff(); //Force AUX on powerEnableAuxForceOn(); powerEnableRFC(); powerEnableXtalInterface(); // Divide INF clk to save Idle mode power (increases interrupt latency) powerDivideInfClkDS(PRCM_INFRCLKDIVDS_RATIO_DIV32); initRTC(); powerEnablePeriph(); powerEnableGPIOClockRunMode(); /* Wait for domains to power on */ while((PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON)); sensorsInit(); ledInit(); //Config IOID4 for external interrupt on rising edge and wake up //IOCPortConfigureSet(BOARD_IOID_KEY_RIGHT, IOC_PORT_GPIO, IOC_IOMODE_NORMAL | IOC_FALLING_EDGE | IOC_INT_ENABLE | IOC_IOPULL_UP | IOC_INPUT_ENABLE | IOC_WAKE_ON_LOW); // Config reedSwitch as input IOCPortConfigureSet(BOARD_IOID_DP0, IOC_PORT_GPIO, IOC_IOMODE_NORMAL | IOC_RISING_EDGE | IOC_INT_ENABLE | IOC_IOPULL_DOWN | IOC_INPUT_ENABLE | IOC_WAKE_ON_HIGH); //Set device to wake MCU from standby on PIN 4 (BUTTON1) HWREG(AON_EVENT_BASE + AON_EVENT_O_MCUWUSEL) = AON_EVENT_MCUWUSEL_WU0_EV_PAD; //Does not work with AON_EVENT_MCUWUSEL_WU0_EV_PAD4 --> WHY?? IntEnable(INT_EDGE_DETECT); powerDisablePeriph(); //Disable clock for GPIO in CPU run mode HWREGBITW(PRCM_BASE + PRCM_O_GPIOCLKGR, PRCM_GPIOCLKGR_CLK_EN_BITN) = 0; // Load clock settings HWREGBITW(PRCM_BASE + PRCM_O_CLKLOADCTL, PRCM_CLKLOADCTL_LOAD_BITN) = 1; initInterrupts(); initRadio(); // baek: before while powerEnablePeriph(); powerEnableGPIOClockRunMode(); /* Wait for domains to power on */ while((PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON)); // CRASH !!!!!!!!!!!!!! sensorsInit(); ledInit(); // end baek: // Turn off FLASH in idle mode powerDisableFlashInIdle(); // Cache retention must be enabled in Idle if flash domain is turned off (to avoid cache corruption) powerEnableCacheRetention(); //AUX - request to power down (takes no effect since force on is set) powerEnableAUXPdReq(); powerDisableAuxRamRet(); //Clear payload buffer memset(payload, 0, ADVLEN); while(1) { //if((g_count& 0x04)== 1){ rfBootDone = 0; rfSetupDone = 0; rfAdvertisingDone = 0; select_bmp_280(); // activates I2C for bmp-sensor enable_bmp_280(1); // works //Wait until RF Core PD is ready before accessing radio waitUntilRFCReady(); initRadioInts(); runRadio(); //Wait until AUX is ready before configuring oscillators waitUntilAUXReady(); //Enable 24MHz XTAL OSCHF_TurnOnXosc(); //IDLE until BOOT_DONE interrupt from RFCore is triggered while( ! rfBootDone) { powerDisableCPU(); PRCMDeepSleep(); } //This code runs after BOOT_DONE interrupt has woken up the CPU again // -> //Request radio to keep on system bus radioCmdBusRequest(true); //Patch CM0 - no RFE patch needed for TX only radioPatch(); //Start radio timer radioCmdStartRAT(); //Enable Flash access while doing radio setup powerEnableFlashInIdle(); //Switch to XTAL while( !OSCHF_AttemptToSwitchToXosc()) {} /* baek: before while powerEnablePeriph(); powerEnableGPIOClockRunMode(); /* Wait for domains to power on */ /* while((PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON)); // CRASH !!!!!!!!!!!!!! sensorsInit(); ledInit(); */ /*****************************************************************************************/ // Read sensor values uint32_t pressure = 0; // only 3 Bytes used //uint32_t temp = 0; select_bmp_280(); // activates I2C for bmp-sensor enable_bmp_280(1); // works do{ pressure = value_bmp_280(BMP_280_SENSOR_TYPE_PRESS); // read and converts in pascal (96'000 Pa) //temp = value_bmp_280(BMP_280_SENSOR_TYPE_TEMP); }while(pressure == 0x80000000); if(pressure == 0x80000000){ CPUdelay(100); pressure = value_bmp_280(BMP_280_SENSOR_TYPE_PRESS); // read and converts in pascal (96'000 Pa) } //Start Temp measurement uint16_t temperature; enable_tmp_007(1); //Wait for, read and calc temperature { int count = 0; do{ temperature = value_tmp_007(TMP_007_SENSOR_TYPE_AMBIENT); //g_count++; }while( ((temperature == 0x80000000) || (temperature == 0)) && (count <=5) ); count++; count--; } enable_tmp_007(0); char char_temp[2]; //start hum measurement configure_hdc_1000(); start_hdc_1000(); // //Wait for, read and calc humidity while(!read_data_hdc_1000()); int humidity = value_hdc_1000(HDC_1000_SENSOR_TYPE_HUMIDITY); // char char_hum[5]; //END read sensor values /*****************************************************************************************/ powerDisablePeriph(); // Disable clock for GPIO in CPU run mode HWREGBITW(PRCM_BASE + PRCM_O_GPIOCLKGR, PRCM_GPIOCLKGR_CLK_EN_BITN) = 0; // Load clock settings HWREGBITW(PRCM_BASE + PRCM_O_CLKLOADCTL, PRCM_CLKLOADCTL_LOAD_BITN) = 1; /*****************************************************************************************/ // Set payload and transmit uint8_t p; p = 0; /*jedes 5.te mal senden*/ payload[p++] = ADVLEN-1; /* len */ payload[p++] = 0x03; payload[p++] = 0xde; payload[p++] = 0xba; payload[p++] =(sequenceNumber >> 8); // laufnummer payload[p++] = sequenceNumber; // Speed payload[p++] = g_diff >> 24; // higher seconds payload[p++] = g_diff >> 16; // lower seconds payload[p++] = g_diff >> 8; // higher subseconds payload[p++] = g_diff; // lower subseconds //pressure payload[p++] = 0; payload[p++] = 0; //(pressure >> 16); payload[p++] = 0; //(pressure >> 8); payload[p++] = 0; //pressure; //temperature payload[p++] = 0; payload[p++] = 0; // char_temp[2]; payload[p++] = 0;//temperature >> 8; // char_temp[1]; payload[p++] = 0; //temperature; //char_temp[0]; // huminity payload[p++] = 0; payload[p++] = 0;//char_hum[0]; payload[p++] = 0;//char_hum[1]; payload[p++] = 0;//char_hum[2]; payload[p++] = 0; payload[p++] = 0; //Start radio setup and linked advertisment radioUpdateAdvData(ADVLEN, payload); //Start radio setup and linked advertisment radioSetupAndTransmit(); //} //END: Transmit /*****************************************************************************************/ //Wait in IDLE for CMD_DONE interrupt after radio setup. ISR will disable radio interrupts while( ! rfSetupDone) { powerDisableCPU(); PRCMDeepSleep(); } //Disable flash in IDLE after CMD_RADIO_SETUP is done (radio setup reads FCFG trim values) powerDisableFlashInIdle(); //Wait in IDLE for LAST_CMD_DONE after 3 adv packets while( ! rfAdvertisingDone) { powerDisableCPU(); PRCMDeepSleep(); } //Request radio to not force on system bus any more radioCmdBusRequest(false); // } // end if // g_count++; // // Standby procedure // powerDisableXtal(); // Turn off radio powerDisableRFC(); // Switch to RCOSC_HF OSCHfSourceSwitch(); // Allow AUX to turn off again. No longer need oscillator interface powerDisableAuxForceOn(); // Goto Standby. MCU will now request to be powered down on DeepSleep powerEnableMcuPdReq(); // Disable cache and retention powerDisableCache(); powerDisableCacheRetention(); //Calculate next recharge SysCtrlSetRechargeBeforePowerDown(XOSC_IN_HIGH_POWER_MODE); // Synchronize transactions to AON domain to ensure AUX has turned off SysCtrlAonSync(); // // Enter Standby // powerDisableCPU(); PRCMDeepSleep(); SysCtrlAonUpdate(); SysCtrlAdjustRechargeAfterPowerDown(); SysCtrlAonSync(); // // Wakeup from RTC, code starts execution from here // powerEnableRFC(); powerEnableAuxForceOn(); //Re-enable cache and retention powerEnableCache(); powerEnableCacheRetention(); //MCU will not request to be powered down on DeepSleep -> System goes only to IDLE powerDisableMcuPdReq(); } }