static void mdelay(unsigned int ms) { int32_t count, count_end; count = Get_system_register(AVR32_COUNT); count_end = count + ((sysclk_get_cpu_hz() + 999) / 1000) * ms; while ((count_end - count) > 0) count = Get_system_register(AVR32_COUNT); }
void wait_10_ms(void) { Set_system_register(AVR32_COUNT, 0); #if (defined AVR32_PM_RCOSC_FREQUENCY) while ((U32)Get_system_register(AVR32_COUNT) < (AVR32_PM_RCOSC_FREQUENCY * 10 + 999) / 1000); #elif (defined AVR32_SCIF_RCOSC_FREQUENCY) while ((U32)Get_system_register(AVR32_COUNT) < (AVR32_SCIF_RCOSC_FREQUENCY * 10 + 999) / 1000); #else #error Unknow RCOSC frequency value #endif }
/*! \brief Waits during at least the specified delay before returning. * * \param ck Number of HSB clock cycles to wait. */ static void sdramc_ck_delay(unsigned long ck) { // Use the CPU cycle counter (CPU and HSB clocks are the same). unsigned long delay_start_cycle = Get_system_register(AVR32_COUNT); unsigned long delay_end_cycle = delay_start_cycle + ck; // To be safer, the end of wait is based on an inequality test, so CPU cycle // counter wrap around is checked. if (delay_start_cycle > delay_end_cycle) { while ((unsigned long)Get_system_register(AVR32_COUNT) > delay_end_cycle); } while ((unsigned long)Get_system_register(AVR32_COUNT) < delay_end_cycle); }
__inline void watchdog(void) { #ifdef DVRPTR if (Get_system_register(AVR32_COUNT)&0x01000000) { gpio1_set(WATCHDOG_PIN); // toggle external Watchdog in slow freq. } else { gpio1_clr(WATCHDOG_PIN); } #else if (Get_system_register(AVR32_COUNT)&0x01000000) { gpio0_set(WATCHDOG_PIN); // toggle external Watchdog in slow freq. } else { gpio0_clr(WATCHDOG_PIN); } #endif }
// Pause for half an I2C bus clock cycle static void I2CDELAY() { // Code stolen from sdramc.c::sdramc_ck_delay() // Use the CPU cycle counter (CPU and HSB clocks are the same). u32 delay_start_cycle = Get_system_register(AVR32_COUNT); u32 delay_end_cycle = delay_start_cycle + i2c_delay; // To be safer, the end of wait is based on an inequality test, so CPU cycle // counter wrap around is checked. if (delay_start_cycle > delay_end_cycle) { while ((unsigned long)Get_system_register(AVR32_COUNT) > delay_end_cycle); } while ((unsigned long)Get_system_register(AVR32_COUNT) < delay_end_cycle); }
/** * @brief get system's internal tick count. * Used for time reference. * @return current tick count. **/ unsigned long inv_get_tick_count(void) { const long cpu_hz = 12000000; long count, ms; count = Get_system_register(AVR32_COUNT); ms = cpu_cy_2_ms(count,cpu_hz); return ms; }
static void prvScheduleNextTick(void) { unsigned long lCycles, lCount; lCycles = Get_system_register(AVR32_COMPARE); lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ); // If lCycles ends up to be 0, make it 1 so that the COMPARE and exception // generation feature does not get disabled. if(0 == lCycles) { lCycles++; } lCount = Get_system_register(AVR32_COUNT); if( lCycles < lCount ) { // We missed a tick, recover for the next. lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ); } Set_system_register(AVR32_COMPARE, lCycles); }
/*! \brief Toggle LED */ int32_t toggle_led(uint32_t number_of_toggles) { volatile uint32_t start_count, end_count; int32_t result = 0; start_count = Get_system_register(AVR32_COUNT); for (uint32_t i = 0; i < number_of_toggles; i++) { LED_Toggle(LED0); } end_count = Get_system_register(AVR32_COUNT); result = end_count - start_count; print(EXAMPLE_USART, " - Number of cycles: "); print_ulong(EXAMPLE_USART, result); print(EXAMPLE_USART, "\r\n"); return result; }
static void prvScheduleFirstTick(void) { unsigned long lCycles; lCycles = Get_system_register(AVR32_COUNT); lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ); // If lCycles ends up to be 0, make it 1 so that the COMPARE and exception // generation feature does not get disabled. if(0 == lCycles) { lCycles++; } Set_system_register(AVR32_COMPARE, lCycles); }
static void record_events(void) { uint16_t i=0; while(1) { while (!main_events) { sleepmgr_enter_sleep(); \ } if (i < NB_EVENTS) { // Register events irqflags_t flags = cpu_irq_save(); list_event[i].event = main_events; list_event[i++].timestamp = cpu_cy_2_us(Get_system_register(AVR32_COUNT),sysclk_get_cpu_hz()); main_events=0; cpu_irq_restore(flags); } } }
/** \brief This function returns the current timestamp counter value. * * The timestamp facility is implemented in terms of the XMEGA or UC3 * timer and clock function APIs. * * \return The current counter value (microseconds). */ uint32_t sensor_timestamp(void) { uint32_t tsc = 0; #if UC3 /** \todo * * Implement this interface in terms of XMEGA and UC3 timer/counter (TC) * facilities exposed through ASF drivers. A free running counter with * microsecond resolution is desirable. Ideally, the counter value * should be updated without using interrupts and attached to a clock *that * will be available while the MCU is in lower power modes. */ tsc = cpu_cy_2_us(Get_system_register(AVR32_COUNT), sysclk_get_cpu_hz()); #endif return tsc; }
clock_t uc3_clock (void) { static U32 last_time=0; static U32 overflow=0; clock_t time; // Get the current time. U32 curr_time=Get_system_register(AVR32_COUNT); // Track overflow situation. We made the assumtion here that we can detect 1 overflow situation. // This is true if the function is called faster than the overflow time. // For example, with a CPU at 66 MHz, you must call the function before (1<<32)/66 MHz; i.e. // 65 seconds since the last function call. if( curr_time<last_time ) overflow++; // Convert the current time into absolute UC3_CLOCKS_PER_SEC ticks, given the known overflow // situations. time = (U64)(( ((U64)overflow<<32) | curr_time) * UC3_CLOCKS_PER_SEC) / get_cpu_hz(); // Save the time for the next function call. last_time = curr_time; return time; }
// handle_serial_paket() // verarbeitet "paket" mit len optionalen Daten (Header NICHT mitgerechnet). __inline void handle_pc_paket(int len) { answer.head.len = 0; // no answer. last_pc_activity = Get_system_register(AVR32_COUNT); switch (rxdatapacket.head.cmd) { // Kommando-Byte case RPTR_GET_STATUS: if (len==1) { // request update_status(); answer.data[PKT_PARAM_IDX+0] = status_control; answer.data[PKT_PARAM_IDX+1] = status_state; answer.data[PKT_PARAM_IDX+2] = rptr_tx_state; answer.data[PKT_PARAM_IDX+3] = VoiceRxBufSize; answer.data[PKT_PARAM_IDX+4] = VoiceTxBufSize; answer.data[PKT_PARAM_IDX+5] = rptr_get_unsend(); // unsend frames left (incl. gaps) answer.head.len = 7; } else if (len==2) { // enable/disable U8 new_control = (status_control & 0xF0) | (rxdatapacket.data[PKT_PARAM_IDX] & 0x0F); if ((new_control^status_control) & STA_RXENABLE_MASK) { if (new_control & STA_RXENABLE_MASK) { trx_receive(); // set receiving rptr_receive(); // enable receiving } else { idle_timer_start(); // disable receiving } } // fi sw RX if ( (new_control^status_control) & STA_TXENABLE_MASK) { // Enable / Disable selected output of modulation DAC dac_power_ctrl(new_control&STA_TXENABLE_MASK); // Enable / Disable Reference-DAC MAX5820 set_dac_power_mode((new_control&STA_TXENABLE_MASK)?TWI_DAC_POWERUP:TWI_DAC_POWERDOWN); } // fi sw TX status_control = new_control; pc_send_byte(ACK); } else { // invalid - more than one parameter byte pc_send_byte(NAK); } break; case RPTR_GET_VERSION: answer.data[PKT_PARAM_IDX+0] = FIRMWAREVERSION & 0xFF; answer.data[PKT_PARAM_IDX+1] = FIRMWAREVERSION >> 8; memcpy(answer.data+PKT_PARAM_IDX+2, VERSION_IDENT, sizeof(VERSION_IDENT)); answer.head.len = sizeof(VERSION_IDENT)+3-1; // cut String-Terminator /0 break; case RPTR_GET_SERIAL: memcpy(answer.data+PKT_PARAM_IDX, (void *)SERIALNUMBER_ADDRESS, 4); answer.head.len = 5; break; case RPTR_GET_CONFIG: if (len==1) { // request all config char *nextblock = cfg_read_c0(answer.data+PKT_PARAM_IDX); nextblock = cfg_read_c1(nextblock); //... answer.head.len = nextblock - answer.data - 3; } else if (len==2) { // request a single block switch(rxdatapacket.data[PKT_PARAM_IDX]) { case 0xC0: cfg_read_c0(answer.data+PKT_PARAM_IDX); answer.head.len = sizeof(CONFIG_C0)+3; break; case 0xC1: cfg_read_c1(answer.data+PKT_PARAM_IDX); answer.head.len = CONFIG_C1_SIZE+3; break; default: pc_send_byte(NAK); break; } } else { pc_send_byte(NAK); } break; case RPTR_SET_CONFIG: if (config_setup(rxdatapacket.data+PKT_PARAM_IDX, len-1)) { pc_send_byte(ACK); } else { pc_send_byte(NAK); } break; case RPTR_START: // early Turn-On xmitter, if configured a long TXD if ((status_control & STA_TXENABLE_MASK) && (len==3)) { if (rxdatapacket.data[PKT_PARAM_IDX] != current_txid) { rptr_transmit_preamble(); // PTTon, wait for a header to start TX if (rptr_tx_state <= RPTRTX_preamble) // starts w/o interrupting a running transmission current_txid = rxdatapacket.data[PKT_PARAM_IDX]; } } else pc_send_byte(NAK); break; case RPTR_HEADER: // start transmitting TXDelay-Preamble-Start-Header if (rptr_tx_state != RPTRTX_header) // update only, if not transmitting just this moment rptr_init_header((tds_header *)&rxdatapacket.data[PKT_PARAM_IDX+4]); if (status_control & STA_TXENABLE_MASK) { if ((rptr_tx_state <= RPTRTX_preamble) || (rxdatapacket.data[PKT_PARAM_IDX] != current_txid)) { rptr_transmit(); // Turn on Xmitter current_txid = rxdatapacket.data[PKT_PARAM_IDX]; } // fi // -> ignore a HEADER msg with same TXID while sending add_icom_voice_reset(); } else pc_send_byte(NAK); // keep 2 bytes for future use, keep layout identical to RX break; case RPTR_RXSYNC: // start transmitting TXDelay-Preamble-Start-Header if (rptr_tx_state != RPTRTX_header) // update only, if not transmitting just this moment rptr_replacement_header(); if (status_control & STA_TXENABLE_MASK) { if ((rptr_tx_state <= RPTRTX_preamble) || (rxdatapacket.data[PKT_PARAM_IDX] != current_txid)) { rptr_transmit(); // Turn on Xmitter only if PTT off current_txid = rxdatapacket.data[PKT_PARAM_IDX]; } // if idle // (transmission use last header) add_icom_voice_reset(); } else pc_send_byte(NAK); break; case RPTR_DATA: // transmit data (voice and slowdata or sync) if (rxdatapacket.data[PKT_PARAM_IDX] == current_txid) add_icom_voice_2_rptr(rxdatapacket.data[PKT_PARAM_IDX+1], &rxdatapacket.data[PKT_PARAM_IDX+4]); //add_multi_voice_2_rptr(len); break; case RPTR_EOT: // end transmission with EOT tail if (len == 3) { if (rxdatapacket.data[PKT_PARAM_IDX] == current_txid) rptr_endtransmit(rxdatapacket.data[PKT_PARAM_IDX+1]); } else rptr_endtransmit(0xFF); // stop after buffer is empty break; case RPTR_SET_SPECIALFUNCT: handle_special_func_cmd(len); break; default: pc_send_byte(NAK); break; } // hctiws if ((answer.head.len > 0)&&(answer.head.len<(PAKETBUFFERSIZE-4))) { U32 anslen = answer.head.len+5; answer.head.id = FRAMESTARTID; answer.head.cmd = 0x80|rxdatapacket.head.cmd; answer.head.len = swap16(answer.head.len); append_crc_ccitt(answer.data, anslen); data_transmit(answer.data, anslen); } // fi send }
// // test if we're in supervisor mode // more specifically if we're not in user mode // int widget_is_supervisor(void) { return (Get_system_register(AVR32_SR) & (7 << 22)) != 0; }
__attribute__((__noinline__)) static void prvClearCcInt(void) { Set_system_register(AVR32_COMPARE, Get_system_register(AVR32_COMPARE)); }
static void prvClearCcInt(void) { Set_system_register(AVR32_COMPARE, Get_system_register(AVR32_COMPARE)); }
/*! * Setup a register A and B * \param region_number: MPU entry region number (0..7). * \param register_select: register A: '0' -- B: '1' * \param right_access: R/W/X see doc32002.pdf (Table 5-3. Access permissions implied by the APn bits) */ void set_access_permissions(unsigned int region_number, unsigned int register_select, unsigned int right_access) { avr32_mpuapra_t mpu_regA; avr32_mpuaprb_t mpu_regB; *(U32 *)&mpu_regA = (U32) Get_system_register(AVR32_MPUAPRA); *(U32 *)&mpu_regB = (U32) Get_system_register(AVR32_MPUAPRB); /* Region entry */ if (register_select==0) //Register A { switch ( region_number & 0x7 ) { default: case 0: mpu_regA.ap0 = (right_access); break; case 1: mpu_regA.ap1 = (right_access); break; case 2: mpu_regA.ap2 = (right_access); break; case 3: mpu_regA.ap3 = (right_access); break; case 4: mpu_regA.ap4 = (right_access); break; case 5: mpu_regA.ap5 = (right_access); break; case 6: mpu_regA.ap6 = (right_access); break; case 7: mpu_regA.ap7 = (right_access); break; } /* Set permissions */ Set_system_register(AVR32_MPUAPRA, *((unsigned int *)&mpu_regA)); } else //Register B { switch ( region_number & 0x7 ) { default: case 0: mpu_regB.ap0 = (right_access); break; case 1: mpu_regB.ap1 = (right_access); break; case 2: mpu_regB.ap2 = (right_access); break; case 3: mpu_regB.ap3 = (right_access); break; case 4: mpu_regB.ap4 = (right_access); break; case 5: mpu_regB.ap5 = (right_access); break; case 6: mpu_regB.ap6 = (right_access); break; case 7: mpu_regB.ap7 = (right_access); break; } /* Set permissions */ Set_system_register(AVR32_MPUAPRB, *((unsigned int *)&mpu_regB)); } }
//! 1) Configure two DMACA channels: //! - RAM -> AES //! - AES -> RAM //! 2) Set the AES cryptographic key and init vector. //! 3) Start the process //! 4) Check the result on the first 16 Words. void test_ram_aes_ram(unsigned short int u16BufferSize, unsigned int *pSrcBuf, unsigned int *pDstBuf) { unsigned int i; unsigned char TestResult = true; //==================== // Configure the DMACA. //==================== // Enable the DMACA AVR32_DMACA.dmacfgreg = 1 << AVR32_DMACA_DMACFGREG_DMA_EN_OFFSET; //* //* Configure the DMA RAM -> AES channel. //* // ------------+--------+------+------------+--------+-------+---------------- // Transfer | Source | Dest | Flow | Width | Chunk | Buffer // type | | | controller | (bits) | size | Size // ------------+--------+------+------------+--------+-------+---------------- // | | | | | | // Mem-to-Per | RAM | AES | DMACA | 32 | 4 | u16BufferSize // | | | | | | // ------------+--------+------+------------+--------+-------+---------------- // NOTE: We arbitrarily choose to use channel 0 for this datapath // Src Address: the InputData[] array AVR32_DMACA.sar0 = (unsigned long)pSrcBuf; // Dst Address: the AES_IDATAXR registers. AVR32_DMACA.dar0 = (AVR32_AES_ADDRESS | AVR32_AES_IDATA1R); // Linked list ptrs: not used. AVR32_DMACA.llp0 = 0x00000000; // Channel 0 Ctrl register low AVR32_DMACA.ctl0l = (0 << AVR32_DMACA_CTL0L_INT_EN_OFFSET) | // Do not enable interrupts (2 << AVR32_DMACA_CTL0L_DST_TR_WIDTH_OFFSET) | // Dst transfer width: 32 bits (2 << AVR32_DMACA_CTL0L_SRC_TR_WIDTH_OFFSET) | // Src transfer width: 32 bits (2 << AVR32_DMACA_CTL0L_DINC_OFFSET) | // Dst address increment: none (0 << AVR32_DMACA_CTL0L_SINC_OFFSET) | // Src address increment: increment (1 << AVR32_DMACA_CTL0L_DST_MSIZE_OFFSET) | // Dst burst transaction len: 4 data items (1 << AVR32_DMACA_CTL0L_SRC_MSIZE_OFFSET) | // Src burst transaction len: 4 data items (0 << AVR32_DMACA_CTL0L_S_GATH_EN_OFFSET) | // Source gather: disabled (0 << AVR32_DMACA_CTL0L_D_SCAT_EN_OFFSET) | // Destination scatter: disabled (1 << AVR32_DMACA_CTL0L_TT_FC_OFFSET) | // transfer type:M2P, flow controller: DMACA (0 << AVR32_DMACA_CTL0L_DMS_OFFSET) | // Dest master: HSB master 1 (1 << AVR32_DMACA_CTL0L_SMS_OFFSET) | // Source master: HSB master 2 (0 << AVR32_DMACA_CTL0L_LLP_D_EN_OFFSET) | // Not used (0 << AVR32_DMACA_CTL0L_LLP_S_EN_OFFSET) // Not used ; // Channel 0 Ctrl register high AVR32_DMACA.ctl0h = (u16BufferSize << AVR32_DMACA_CTL0H_BLOCK_TS_OFFSET) | // Block transfer size (0 << AVR32_DMACA_CTL0H_DONE_OFFSET) // Not done ; // Channel 0 Config register low AVR32_DMACA.cfg0l = (0 << AVR32_DMACA_CFG0L_HS_SEL_DST_OFFSET) | // Destination handshaking: hw handshaking (0 << AVR32_DMACA_CFG0L_HS_SEL_SRC_OFFSET) // Source handshaking: ignored because the src is memory. ; // All other bits set to 0. // Channel 0 Config register high AVR32_DMACA.cfg0h = (AVR32_DMACA_CH_AES_TX << AVR32_DMACA_CFG0H_DEST_PER_OFFSET) | // Dest hw handshaking itf: (0 << AVR32_DMACA_CFG0H_SRC_PER_OFFSET) // Source hw handshaking itf: ignored because the src is memory. ; // All other bits set to 0. //* //* Configure the DMA AES -> RAM channel. //* // ------------+--------+------+------------+--------+-------+---------------- // Transfer | Source | Dest | Flow | Width | Chunk | Buffer // type | | | controller | (bits) | size | Size // ------------+--------+------+------------+--------+-------+---------------- // | | | | | | // Per-to-Mem | AES | RAM | DMACA | 32 | 4 | u16BufferSize // | | | | | | // ------------+--------+------+------------+--------+-------+---------------- // NOTE: We arbitrarily choose to use channel 1 for this datapath // Src Address: the AES_ODATAXR registers. AVR32_DMACA.sar1 = (AVR32_AES_ADDRESS | AVR32_AES_ODATA1R); // Dst Address: the OutputData[] array. AVR32_DMACA.dar1 = (unsigned long)pDstBuf; // Linked list ptrs: not used. AVR32_DMACA.llp1 = 0x00000000; // Channel 1 Ctrl register low AVR32_DMACA.ctl1l = (0 << AVR32_DMACA_CTL1L_INT_EN_OFFSET) | // Do not enable interrupts (2 << AVR32_DMACA_CTL1L_DST_TR_WIDTH_OFFSET) | // Dst transfer width: 32 bits (2 << AVR32_DMACA_CTL1L_SRC_TR_WIDTH_OFFSET) | // Src transfer width: 32 bits (0 << AVR32_DMACA_CTL1L_DINC_OFFSET) | // Dst address increment: increment (2 << AVR32_DMACA_CTL1L_SINC_OFFSET) | // Src address increment: none (1 << AVR32_DMACA_CTL1L_DST_MSIZE_OFFSET) | // Dst burst transaction len: 4 data items (1 << AVR32_DMACA_CTL1L_SRC_MSIZE_OFFSET) | // Src burst transaction len: 4 data items (0 << AVR32_DMACA_CTL1L_S_GATH_EN_OFFSET) | // Source gather: disabled (0 << AVR32_DMACA_CTL1L_D_SCAT_EN_OFFSET) | // Destination scatter: disabled (2 << AVR32_DMACA_CTL1L_TT_FC_OFFSET) | // transfer type:P2M, flow controller: DMACA (1 << AVR32_DMACA_CTL1L_DMS_OFFSET) | // Dest master: HSB master 2 (0 << AVR32_DMACA_CTL1L_SMS_OFFSET) | // Source master: HSB master 1 (0 << AVR32_DMACA_CTL1L_LLP_D_EN_OFFSET) | // Not used (0 << AVR32_DMACA_CTL1L_LLP_S_EN_OFFSET) // Not used ; // Channel 1 Ctrl register high AVR32_DMACA.ctl1h = (u16BufferSize << AVR32_DMACA_CTL1H_BLOCK_TS_OFFSET) | // Block transfer size (0 << AVR32_DMACA_CTL1H_DONE_OFFSET) // Not done ; // Channel 1 Config register low AVR32_DMACA.cfg1l = (0 << AVR32_DMACA_CFG1L_HS_SEL_DST_OFFSET) | // Destination handshaking: hw handshaking (0 << AVR32_DMACA_CFG1L_HS_SEL_SRC_OFFSET) // Source handshaking: ignored because the src is memory. ; // All other bits set to 0. // Channel 1 Config register high AVR32_DMACA.cfg1h = (0 << AVR32_DMACA_CFG1H_DEST_PER_OFFSET) | // Dest hw handshaking itf: ignored because the dst is memory. (AVR32_DMACA_CH_AES_RX << AVR32_DMACA_CFG1H_SRC_PER_OFFSET) // Source hw handshaking itf: ; // All other bits set to 0. //* //* Set the AES cryptographic key and init vector. //* // Set the cryptographic key. aes_set_key(&AVR32_AES, CipherKey); // Set the initialization vector. aes_set_initvector(&AVR32_AES, InitVector); //* //* Start the process //* ccountt0 = Get_system_register(AVR32_COUNT); // Enable Channel 0 & 1 : start the process. AVR32_DMACA.chenreg = ((3<<AVR32_DMACA_CHENREG_CH_EN_OFFSET) | (3<<AVR32_DMACA_CHENREG_CH_EN_WE_OFFSET)); // Wait for the end of the AES->RAM transfer (channel 1). while(AVR32_DMACA.chenreg & (2<<AVR32_DMACA_CHENREG_CH_EN_OFFSET)); ccountt1 = Get_system_register(AVR32_COUNT); // Check the results of the encryption. for(i=0; i<DMACA_AES_EVAL_REFBUF_SIZE; i++) { if(OutputData[i] != RefOutputData[i]) { TestResult = false; break; } } if(false == TestResult) print(DMACA_AES_EVAL_USART, "KO!!!\r\n"); else { print(DMACA_AES_EVAL_USART, "OK!!! Nb of cycles: "); print_ulong(DMACA_AES_EVAL_USART, ccountt1 - ccountt0); } }
uint32_t time_tick_get(void) { return Get_system_register(AVR32_COUNT); }