void eeprom_init(void) { if(erb(EE_MAGIC_OFFSET) != VERSION_1 || erb(EE_MAGIC_OFFSET+1) != VERSION_2) eeprom_factory_reset(0); led_mode = erb(EE_LED); #ifdef XLED switch (led_mode) { case 0: xled_pattern = 0; break; case 1: xled_pattern = 0xffff; break; case 2: xled_pattern = 0xff00; break; case 3: xled_pattern = 0xa000; break; case 4: xled_pattern = 0xaa00; break; } #endif #ifdef HAS_SLEEP sleep_time = erb(EE_SLEEPTIME); #endif }
void rf_router_init() { rf_router_myid = erb(EE_RF_ROUTER_ID); rf_router_target = erb(EE_RF_ROUTER_ROUTER); if(rf_router_target) { tx_report = 0x21; set_txrestore(); } }
void fht_init(void) { fht_hc0 = erb(EE_FHTID); fht_hc1 = erb(EE_FHTID+1); #ifdef HAS_FHT_8v for(uint8_t i = 0; i < FHT_8V_NUM; i++) fht8v_buf[2*i] = FHT_8V_DISABLED; #endif #ifdef HAS_FHT_80b fht80b_reset_state(); fht80b_initbuf(); #endif }
void lcd_switch(uint8_t hb) { if(hb) { LCD_BL_DDR |= _BV(LCD_BL_PIN); // Switch on, init #ifdef LCD_BL_PWM LCD_BL_PWM = erb((uint8_t*)EE_BRIGHTNESS); #else LCD_BL_PORT |= _BV(LCD_BL_PIN); #endif lcd_init(); lcd_on = 1; } else { #ifdef LCD_BL_PWM LCD_BL_PWM = 0; my_delay_ms(1); // else the dpy is still on. #endif LCD_BL_PORT &= ~_BV(LCD_BL_PIN); // Switch off the display lcd_sendcmd (LCD_CMD_SLEEPIN); lcd_on = 0; } }
void lcd_brightness(uint8_t hb) { int16_t brightness = erb((uint8_t*)EE_BRIGHTNESS); if(hb == 0xFE) { brightness += 0x20; } else if (hb == 0xFD) { brightness -= 0x20; } else if (hb == 0xFC) { //keep the eeprom value } else { brightness = hb; } if(brightness < 0) brightness = 0; if(brightness > 255) brightness = 255; ewb((uint8_t*)EE_BRIGHTNESS, brightness); LCD_BL_PWM = brightness; DS_P( PSTR("Brightns:") ); DU(brightness*100/255, 3); DC('%'); DNL(); }
void lcd_contrast(uint8_t hb) { uint8_t contrast = erb((uint8_t*)EE_CONTRAST); if(hb == 0xFE) { contrast--; } else if (hb == 0xFD) { contrast++; } else if (hb == 0xFC) { //keep the eeprom value } else { contrast = hb; } if(contrast < 40) contrast = 40; if(contrast > 80) contrast = 80; ewb((uint8_t*)EE_CONTRAST, contrast); lcd_sendcmd (LCD_CMD_SETCON); lcd_senddata (contrast); DS_P( PSTR("Contrast:") ); DU(100-(contrast-40)*100/40, 3); DC('%'); DNL(); }
void ccInitChip(uint8_t *cfg) { #ifdef HAS_MORITZ moritz_on = 0; //loading this configuration overwrites moritz cfg #endif #ifdef ARM AT91C_BASE_AIC->AIC_IDCR = 1 << CC1100_IN_PIO_ID; CC1100_CS_BASE->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup CC1100_CS_BASE->PIO_OER = _BV(CC1100_CS_PIN); //Enable output CC1100_CS_BASE->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif CC1100_DEASSERT; // Toggle chip select signal my_delay_us(30); CC1100_ASSERT; my_delay_us(30); CC1100_DEASSERT; my_delay_us(45); ccStrobe( CC1100_SRES ); // Send SRES command my_delay_us(100); CC1100_ASSERT; // load configuration cc1100_sendbyte( 0 | CC1100_WRITE_BURST ); for(uint8_t i = 0; i < EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(erb(cfg++)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; ccStrobe( CC1100_SCAL ); my_delay_ms(1); }
static void display_ee_bytes(uint8_t *a, uint8_t cnt) { while(cnt--) { DH2(erb(a++)); if(cnt) DC(':'); } }
static void display_ee_ip4(uint8_t *a) { uint8_t cnt = 4; while(cnt--) { DU(erb(a++),1); if(cnt) DC('.'); } }
void read_eeprom(char *in) { uint8_t hb[2], d; uint16_t addr; #ifdef HAS_ETHERNET if(in[1] == 'i') { if(in[2] == 'm') { display_ee_mac(EE_MAC_ADDR); } else if(in[2] == 'd') { DH2(erb(EE_USE_DHCP)); } else if(in[2] == 'a') { display_ee_ip4(EE_IP4_ADDR); } else if(in[2] == 'n') { display_ee_ip4(EE_IP4_NETMASK); } else if(in[2] == 'g') { display_ee_ip4(EE_IP4_GATEWAY); } else if(in[2] == 'N') { display_ee_ip4(EE_IP4_NTPSERVER); } else if(in[2] == 'o') { DH2(erb(EE_IP4_NTPOFFSET)); } else if(in[2] == 'p') { DU(eeprom_read_word((uint16_t *)EE_IP4_TCPLINK_PORT), 0); } } else #endif if(in[1] == 'M') { display_ee_mac(EE_DUDETTE_MAC); } else if(in[1] == 'P') { display_ee_bytes(EE_DUDETTE_PUBL, 16); } else { hb[0] = hb[1] = 0; d = fromhex(in+1, hb, 2); if(d == 2) addr = (hb[0] << 8) | hb[1]; else addr = hb[0]; d = erb((uint8_t *)addr); DC('R'); // prefix DH(addr,4); // register number DS_P( PSTR(" = ") ); DH2(d); // result, hex DS_P( PSTR(" / ") ); DU(d,2); // result, decimal } DNL(); }
static void it_tunein(void) { int8_t i; #ifdef ARM AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_PIOA; // disable INT - we'll poll... AT91C_BASE_PIOA->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup AT91C_BASE_PIOA->PIO_OER = _BV(CC1100_CS_PIN); //Enable output AT91C_BASE_PIOA->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif CC1100_DEASSERT; // Toggle chip select signal my_delay_us(30); CC1100_ASSERT; my_delay_us(30); CC1100_DEASSERT; my_delay_us(45); ccStrobe( CC1100_SRES ); // Send SRES command my_delay_us(100); CC1100_ASSERT; // load configuration cc1100_sendbyte( 0 | CC1100_WRITE_BURST ); for(uint8_t i = 0; i < 13; i++) { cc1100_sendbyte(__LPM(CC1100_ITCFG+i)); } // Tune to standard IT-Frequency cc1100_sendbyte(it_frequency[0]); // Modify Freq. for 433.92MHZ, or whatever cc1100_sendbyte(it_frequency[1]); cc1100_sendbyte(it_frequency[2]); for (i = 16; i<EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(__LPM(CC1100_ITCFG+i)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; ccStrobe( CC1100_SCAL ); my_delay_ms(1); cc_on = 1; // Set CC_ON }
void it_tunein(void) { int8_t i; #ifdef USE_HAL hal_CC_GDO_init(CC_INSTANCE,INIT_MODE_OUT_CS_IN); hal_enable_CC_GDOin_int(CC_INSTANCE,FALSE); // disable INT - we'll poll... #else EIMSK &= ~_BV(CC1100_INT); SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif CC1100_DEASSERT; // Toggle chip select signal my_delay_us(30); CC1100_ASSERT; my_delay_us(30); CC1100_DEASSERT; my_delay_us(45); ccStrobe( CC1100_SRES ); // Send SRES command my_delay_us(100); CC1100_ASSERT; // load configuration cc1100_sendbyte( 0 | CC1100_WRITE_BURST ); for(uint8_t i = 0; i < 13; i++) { cc1100_sendbyte(__LPM(CC1100_ITCFG+i)); } // Tune to standard IT-Frequency cc1100_sendbyte(it_frequency[0]); // Modify Freq. for 433.92MHZ, or whatever cc1100_sendbyte(it_frequency[1]); cc1100_sendbyte(it_frequency[2]); for (i = 16; i<EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(__LPM(CC1100_ITCFG+i)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; ccStrobe( CC1100_SCAL ); my_delay_ms(1); #ifndef USE_RF_MODE cc_on = 1; // Set CC_ON #endif }
void ntp_init(void) { uip_ipaddr_t ipaddr; ntp_gmtoff = erb(EE_IP4_NTPOFFSET); erip(ipaddr, EE_IP4_NTPSERVER); if(ipaddr[0] == 0 && ipaddr[1] == 0) erip(ipaddr, EE_IP4_GATEWAY); ntp_conn = uip_udp_new(&ipaddr, HTONS(NTP_PORT)); if(ntp_conn == NULL) return; uip_udp_bind(ntp_conn, HTONS(NTP_PORT)); //ntp_sendpacket(); }
void ethernet_reset(void) { char buf[21]; uint16_t serial = 0; buf[1] = 'i'; buf[2] = 'd'; strcpy_P(buf+3, PSTR("1")); write_eeprom(buf);//DHCP buf[2] = 'a'; strcpy_P(buf+3, PSTR("192.168.0.244")); write_eeprom(buf);//IP buf[2] = 'n'; strcpy_P(buf+3, PSTR("255.255.255.0")); write_eeprom(buf); buf[2] = 'g'; strcpy_P(buf+3, PSTR("192.168.0.1")); write_eeprom(buf);//GW buf[2] = 'p'; strcpy_P(buf+3, PSTR("2323")); write_eeprom(buf); buf[2] = 'N'; strcpy_P(buf+3, PSTR("0.0.0.0")); write_eeprom(buf);//==GW buf[2] = 'o'; strcpy_P(buf+3, PSTR("00")); write_eeprom(buf);//GMT #ifdef EE_DUDETTE_MAC // check for mac stored during manufacture uint8_t *ee = EE_DUDETTE_MAC; if (erb( ee++ ) == 0xa4) if (erb( ee++ ) == 0x50) if (erb( ee++ ) == 0x55) { buf[2] = 'm'; strcpy_P(buf+3, PSTR("A45055")); // busware.de OUI range tohex(erb( ee++ ), (uint8_t*)buf+9); tohex(erb( ee++ ), (uint8_t*)buf+11); tohex(erb( ee++ ), (uint8_t*)buf+13); buf[15] = 0; write_eeprom(buf); return; } #endif // Generate a "unique" MAC address from the unique serial number buf[2] = 'm'; strcpy_P(buf+3, PSTR("A45055")); // busware.de OUI range #define bsbg boot_signature_byte_get // tohex(bsbg(0x0e)+bsbg(0x0f), (uint8_t*)buf+9); // tohex(bsbg(0x10)+bsbg(0x11), (uint8_t*)buf+11); // tohex(bsbg(0x12)+bsbg(0x13), (uint8_t*)buf+13); for (uint8_t i = 0x00; i < 0x20; i++) serial += bsbg(i); tohex(0, (uint8_t*)buf+9); tohex((serial>>8) & 0xff, (uint8_t*)buf+11); tohex(serial & 0xff, (uint8_t*)buf+13); buf[15] = 0; write_eeprom(buf); }
void ethernet_init(void) { // reset Ethernet ENC28J60_RESET_DDR |= _BV( ENC28J60_RESET_BIT ); ENC28J60_RESET_PORT &= ~_BV( ENC28J60_RESET_BIT ); my_delay_ms( 200 ); // unreset Ethernet ENC28J60_RESET_PORT |= _BV( ENC28J60_RESET_BIT ); my_delay_ms( 200 ); network_init(); mac.addr[0] = erb(EE_MAC_ADDR+0); mac.addr[1] = erb(EE_MAC_ADDR+1); mac.addr[2] = erb(EE_MAC_ADDR+2); mac.addr[3] = erb(EE_MAC_ADDR+3); mac.addr[4] = erb(EE_MAC_ADDR+4); mac.addr[5] = erb(EE_MAC_ADDR+5); network_set_MAC(mac.addr); uip_setethaddr(mac); uip_init(); ntp_conn = 0; // setup two periodic timers timer_set(&periodic_timer, CLOCK_SECOND / 4); timer_set(&arp_timer, CLOCK_SECOND * 10); if(erb(EE_USE_DHCP)) { network_set_led(0x4A6);// LED A: Link Status LED B: Blink slow dhcpc_init(&mac); dhcp_state = PT_WAITING; } else { dhcp_state = PT_ENDED; set_eeprom_addr(); } }
/*---------------------------------------------------------------------------*/ void network_init(void) { Dm9161 *pDm = &gDm9161; MacAddress.addr[0] = erb(EE_MAC_ADDR+0); MacAddress.addr[1] = erb(EE_MAC_ADDR+1); MacAddress.addr[2] = erb(EE_MAC_ADDR+2); MacAddress.addr[3] = erb(EE_MAC_ADDR+3); MacAddress.addr[4] = erb(EE_MAC_ADDR+4); MacAddress.addr[5] = erb(EE_MAC_ADDR+5); // Display MAC & IP settings TRACE_INFO(" - MAC %x:%x:%x:%x:%x:%x\n\r", MacAddress.addr[0], MacAddress.addr[1], MacAddress.addr[2], MacAddress.addr[3], MacAddress.addr[4], MacAddress.addr[5]); // clear PHY power down mode PIO_Configure(emacPwrDn, 1); // Init EMAC driver structure EMAC_Init(AT91C_ID_EMAC, MacAddress.addr, EMAC_CAF_ENABLE, EMAC_NBC_DISABLE); // Setup EMAC buffers and interrupts AIC_ConfigureIT(AT91C_ID_EMAC, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ISR_Emac); AIC_EnableIT(AT91C_ID_EMAC); // Init DM9161 driver DM9161_Init(pDm, EMAC_PHY_ADDR); // PHY initialize //if (!DM9161_InitPhy(pDm, BOARD_MCK, // emacRstPins, PIO_LISTSIZE(emacRstPins), // emacPins, PIO_LISTSIZE(emacPins))) { if (!DM9161_InitPhy(pDm, BOARD_MCK, 0, 0, emacPins, PIO_LISTSIZE(emacPins))) { TRACE_INFO("P: PHY Initialize ERROR!\n\r"); return; } }
void rf_asksin_init(void) { #ifdef ARM #ifndef CC_ID AT91C_BASE_AIC->AIC_IDCR = 1 << CC1100_IN_PIO_ID; // disable INT - we'll poll... #endif CC1100_CS_BASE->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup CC1100_CS_BASE->PIO_OER = _BV(CC1100_CS_PIN); //Enable output CC1100_CS_BASE->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); // disable INT - we'll poll... SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif CC1100_DEASSERT; // Toggle chip select signal my_delay_us(30); CC1100_ASSERT; my_delay_us(30); CC1100_DEASSERT; my_delay_us(45); CCSTROBE( CC1100_SRES ); // Send SRES command my_delay_us(100); #ifdef CC_ID CC1100_ASSERT; uint8_t *cfg = EE_CC1100_CFG; for(uint8_t i = 0; i < EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(erb(cfg++)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; #endif // load configuration for (uint8_t i = 0; i < sizeof(ASKSIN_CFG); i += 2) { CC1100_WRITEREG( pgm_read_byte(&ASKSIN_CFG[i]), pgm_read_byte(&ASKSIN_CFG[i+1]) ); } #ifdef HAS_ASKSIN_FUP if (asksin_update_mode) { for (uint8_t i = 0; i < sizeof(ASKSIN_UPDATE_CFG); i += 2) { cc1100_writeReg( pgm_read_byte(&ASKSIN_UPDATE_CFG[i]), pgm_read_byte(&ASKSIN_UPDATE_CFG[i+1]) ); } } #endif CCSTROBE( CC1100_SCAL ); my_delay_ms(4); // enable RX, but don't enable the interrupt do { CCSTROBE(CC1100_SRX); } while (CC1100_READREG(CC1100_MARCSTATE) != MARCSTATE_RX); }
void kopp_fc_init(void) { #ifdef ARM AT91C_BASE_AIC->AIC_IDCR = 1 << CC1100_IN_PIO_ID; // disable INT - we'll poll... CC1100_CS_BASE->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup CC1100_CS_BASE->PIO_OER = _BV(CC1100_CS_PIN); //Enable output CC1100_CS_BASE->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); // disable INT - we'll poll... SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif // Toggle chip select signal (why?) CC1100_DEASSERT; // Chip Select InActiv my_delay_us(30); CC1100_ASSERT; // Chip Select Activ my_delay_us(30); CC1100_DEASSERT; // Chip Select InActiv my_delay_us(45); ccStrobe( CC1100_SRES ); // Send SRES command (Reset CC110x) my_delay_us(100); // load configuration (CC1100_Kopp_CFG[EE_CC1100_CFG_SIZE]) CC1100_ASSERT; // Chip Select Activ cc1100_sendbyte( 0 | CC1100_WRITE_BURST ); for(uint8_t i = 0; i < EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(__LPM(CC1100_Kopp_CFG+i)); } CC1100_DEASSERT; // Chip Select InActiv // If I don't missunderstand the code, in module cc1100.c the pa table is defined as // 00 and C2 what means power off and max. power. // so following code (setup PA table) is not needed ? // did a trial, but does not work // setup PA table (-> Remove as soon as transmitting ok?), table see cc1100.c // this initializes the PA table with the table defined at EE_Prom // which table will be taken depends on command "x00 .... x09" // x00 means -10dbm pa ramping // x09 means +10dBm no pa ramping (see cc1100.c) and commandref.html #ifdef PrintOn // DS_P(PSTR("PA Table values: ")); #endif uint8_t *pa = EE_CC1100_PA; // EE_CC1100_PA+32 means max power??? CC1100_ASSERT; cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST); for (uint8_t i = 0; i < 8; i++) { #ifdef PrintOn // DU(erb(pa),0); // ### Claus, mal sehen was im PA Table steht DS_P(PSTR(" ")); #endif cc1100_sendbyte(erb(pa++)); // fncollection.c "erb()"gibt einen EEPROM Wert zurück } #ifdef PrintOn DS_P(PSTR("\r\n")); #endif CC1100_DEASSERT; // Set CC_ON ccStrobe( CC1100_SCAL); // Calibrate Synthesizer and turn it of. ##Claus brauchen wir das my_delay_ms(1); cc_on = 1; kopp_fc_on = 1; //##Claus may be not needed in future (Tx Only) checkFrequency(); }
int main(void) { //ewb((uint8_t*)0x80, erb((uint8_t*)0x80)+1); wdt_enable(WDTO_2S); // Avoid an early reboot clock_prescale_set(clock_div_1); // Disable Clock Division:1->8MHz #ifdef HAS_XRAM init_memory_mapped(); // First initialize the RAM #endif // if we had been restarted by watchdog check the REQ BootLoader byte in the // EEPROM if(bit_is_set(MCUSR,WDRF) && erb(EE_REQBL)) { ewb( EE_REQBL, 0 ); // clear flag start_bootloader(); } while(tx_report); // reboot if the bss is not initialized // Setup the timers. Are needed for watchdog-reset OCR0A = 249; // Timer0: 0.008s = 8MHz/256/250 TCCR0B = _BV(CS02); TCCR0A = _BV(WGM01); TIMSK0 = _BV(OCIE0A); TCCR1A = 0; TCCR1B = _BV(CS11) | _BV(WGM12); // Timer1: 1us = 8MHz/8 MCUSR &= ~(1 << WDRF); // Enable the watchdog led_init(); // So we can debug spi_init(); eeprom_init(); USB_Init(); fht_init(); tx_init(); ethernet_init(); #ifdef HAS_FS df_init(&df); fs_init(&fs, df, 0); // needs df_init log_init(); // needs fs_init & rtc_init log_enabled = erb(EE_LOGENABLED); #endif input_handle_func = analyze_ttydata; display_channel = DISPLAY_USB; LED_OFF(); for(;;) { USB_USBTask(); CDC_Task(); RfAnalyze_Task(); Minute_Task(); FastRF_Task(); rf_router_task(); #ifdef HAS_ASKSIN rf_asksin_task(); #endif #ifdef HAS_ETHERNET Ethernet_Task(); #endif } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *input, *bm, *env, *filter; double lowerERB, upperERB; double dt, twoPiT, gain, z; double f1Down, f2Down, f1Up, f2Up, data; double x[4], y[4]; int nSamples, nChannels, lowerFreq, upperFreq, nFilter; int ii, nn, chan, fs, bExit = false, bUseMidEar = false; int chanIdx, nFilter2Process, *processFilter, infoFlag; int bTimeAlign = false, tc; // Define field names for gammatone structure //const char *field_names[] = {"fs","nFilter","lowerFreq","upperFreq","cf","bw","gain","delay"}; // Check for proper number of arguments if ((nrhs < 2) || (nlhs > 2)){ usage(); // Set exit flag to true because of incorrect function call bExit = true; } // Check if input arguments are valid else{ // Get dimension of input signal nSamples = (int)mxGetM(INPUT); nChannels = (int)mxGetN(INPUT); // Sampling frequency fs = (int) mxGetScalar(FS); // Input signal must be mono if(nChannels != 1){ mexPrintf("\n--------------------------------------------------------------------------------" ); mexPrintf("\n ERROR: gammatone.dll is just supporting mono signals." ); mexPrintf("\n--------------------------------------------------------------------------------\n"); // Set exit flag to true bExit = true; } // Set defaults ... if (nrhs < 3) lowerFreq = 80; else lowerFreq = (int)mxGetScalar(LOWERFREQ); if (nrhs < 4) upperFreq = 5000; else upperFreq = (int)mxGetScalar(UPPERFREQ); if (nrhs < 5){ // Round the number of auditory filter to the next integer value nFilter = getRound(HzToERBRate(fs/2)); // Total number of filters to process within this function call nFilter2Process = nFilter; // Create index vector for auditory filter processing processFilter = (int *) mxCalloc(nFilter2Process, sizeof(int)); // Create vector which indicates the indicees of the processed auditory filters for (chan=0; chan<nFilter; chan++){ processFilter[chan] = chan; } } else{ // Figure out how may auditory filters should be processed ... filter = mxGetPr(NFILTER); // Assume the first value to be the total number of auditory filters nFilter = (int) filter[0]; // Determine number of auditory filters which should be processed nFilter2Process = max((int)mxGetM(NFILTER),(int)mxGetN(NFILTER))-1; // In case just the total number of auditory filters was specified, process all filters if (nFilter2Process == 0){ nFilter2Process = nFilter; // Create index vector for auditory filter processing processFilter = (int *) mxCalloc(nFilter2Process, sizeof(int)); // Create vector which indicates the indicees of the processed auditory filters for (chan=0; chan<nFilter2Process; chan++){ processFilter[chan] = chan; } } else{ // Create index vector for auditory filter processing processFilter = (int *) mxCalloc(nFilter2Process, sizeof(int)); // Create vector which indicates the indicees of the processed auditory filters for (chan=0; chan<nFilter2Process; chan++){ processFilter[chan] = (int) filter[chan + 1] - 1; } } } if (nrhs < 6) bUseMidEar = false; else{ bUseMidEar = (int)mxGetScalar(USEMIDDLEEAR); } if (nrhs < 7) bTimeAlign = false; else{ bTimeAlign = (int)mxGetScalar(TIMEALIGN); } // Check if lower and upper frequency limit fall within the valid range // of the outer/middle ear filter ... if (bUseMidEar && (lowerFreq <= 20 || upperFreq >= 12500 )){ // Display error message mexPrintf("\n--------------------------------------------------------------------------------" ); mexPrintf("\n ERROR using gammatone.dll: " ); mexPrintf("\n The lower and upper frequency limit must be within 20 and 12500 Hz if the " ); mexPrintf("\n outer/middle ear gain is used. " ); mexPrintf("\n--------------------------------------------------------------------------------\n"); // Set exit flag to true because of incorrect function call bExit = true; } else if(bUseMidEar){ /* parameters of equal-loudness functions from BS3383, "Normal equal-loudness level contours for pure tones under free-field listening conditions", table 1. f is the tone frequency af and bf are frequency-dependent coefficients tf is the threshold sound pressure level of the tone, in dBs */ f[0]=20.0; af[0]=2.347; bf[0]=0.00561; tf[0]=74.3; f[1]=25.0; af[1]=2.190; bf[1]=0.00527; tf[1]=65.0; f[2]=31.5; af[2]=2.050; bf[2]=0.00481; tf[2]=56.3; f[3]=40.0; af[3]=1.879; bf[3]=0.00404; tf[3]=48.4; f[4]=50.0; af[4]=1.724; bf[4]=0.00383; tf[4]=41.7; f[5]=63.0; af[5]=1.579; bf[5]=0.00286; tf[5]=35.5; f[6]=80.0; af[6]=1.512; bf[6]=0.00259; tf[6]=29.8; f[7]=100.0; af[7]=1.466; bf[7]=0.00257; tf[7]=25.1; f[8]=125.0; af[8]=1.426; bf[8]=0.00256; tf[8]=20.7; f[9]=160.0; af[9]=1.394; bf[9]=0.00255; tf[9]=16.8; f[10]=200.0; af[10]=1.372; bf[10]=0.00254; tf[10]=13.8; f[11]=250.0; af[11]=1.344; bf[11]=0.00248; tf[11]=11.2; f[12]=315.0; af[12]=1.304; bf[12]=0.00229; tf[12]=8.9; f[13]=400.0; af[13]=1.256; bf[13]=0.00201; tf[13]=7.2; f[14]=500.0; af[14]=1.203; bf[14]=0.00162; tf[14]=6.0; f[15]=630.0; af[15]=1.135; bf[15]=0.00111; tf[15]=5.0; f[16]=800.0; af[16]=1.062; bf[16]=0.00052; tf[16]=4.4; f[17]=1000.0; af[17]=1.000; bf[17]=0.00000; tf[17]=4.2; f[18]=1250.0; af[18]=0.967; bf[18]=-0.00039; tf[18]=3.7; f[19]=1600.0; af[19]=0.943; bf[19]=-0.00067; tf[19]=2.6; f[20]=2000.0; af[20]=0.932; bf[20]=-0.00092; tf[20]=1.0; f[21]=2500.0; af[21]=0.933; bf[21]=-0.00105; tf[21]=-1.2; f[22]=3150.0; af[22]=0.937; bf[22]=-0.00104; tf[22]=-3.6; f[23]=4000.0; af[23]=0.952; bf[23]=-0.00088; tf[23]=-3.9; f[24]=5000.0; af[24]=0.974; bf[24]=-0.00055; tf[24]=-1.1; f[25]=6300.0; af[25]=1.027; bf[25]=0.00000; tf[25]=6.6; f[26]=8000.0; af[26]=1.135; bf[26]=0.00089; tf[26]=15.3; f[27]=10000.0; af[27]=1.266; bf[27]=0.00211; tf[27]=16.4; f[28]=12500.0; af[28]=1.501; bf[28]=0.00488; tf[28]=11.6; } if (nrhs < 8) infoFlag = false; else infoFlag = (int)mxGetScalar(INFOFLAG); } if(!bExit){ // Asign pointers input = mxGetPr(INPUT); // Create a matrix for the return argument BM = mxCreateDoubleMatrix(nSamples, nFilter2Process, mxREAL); // Asign pointer bm = mxGetPr(BM); // Envelope output if (nlhs>1){ // Create a matrix for second return argument ENV = mxCreateDoubleMatrix(nSamples, nFilter2Process, mxREAL); // Asign pointer env = mxGetPr(ENV); } // Initialize gammatone filter structure gammaTone* fChan; // Da der Kompiler meckert wenn nFilter keine Konstante ist, muss die // Gammatone-Struktur zur Laufzeit mit new initialisiert werden ... fChan = new gammaTone[nFilter]; // Map frequency to erb domain lowerERB = HzToERBRate(lowerFreq); upperERB = HzToERBRate(upperFreq); // Calculate center frequencies fChan[0].cf = ERBRateToHz(lowerERB); for (chan = 1; chan<nFilter-1; chan++) { // Linear space the gammatone center frequency in the ERB domain fChan[chan].cf = ERBRateToHz(lowerERB + chan * (upperERB-lowerERB)/((double)nFilter-1.0)); } fChan[nFilter-1].cf = ERBRateToHz(upperERB); // Report parameter if (infoFlag){ mexPrintf("\n \t |-------------------------------------| "); mexPrintf("\n \t | GAMMATONE PARAMETER | "); mexPrintf("\n \t |-------------------------------------| "); mexPrintf("\n \t | filter | cf [Hz] | bw | delay | "); mexPrintf("\n \t |-------------------------------------| "); } // Loop over number of auditory filters for (chan=0; chan<nFilter; chan++) { // Bandwidth fChan[chan].bw = erb(fChan[chan].cf) * bandwidthCorrection; // Compute gammatone envelope delay in samples (for 4th order) fChan[chan].delay = (3.0 * fs) / (fChan[chan].bw * 2.0 * PI); // Compute phase correction to align peak in temporal fine structure fChan[chan].phaseCorrection = -fChan[chan].cf * 3.0/fChan[chan].bw; // Report parameters ... if (infoFlag){ mexPrintf("\n \t |%5.0f |%9.2f |%7.2f |%7.2f |",(double)chan+1.0,fChan[chan].cf,fChan[chan].bw,fChan[chan].delay); } } if (infoFlag){ mexPrintf("\n \t |-------------------------------------|\n"); } // Time resolution dt = 1/double(fs); twoPiT = 2 * PI * dt; // Loop over number of auditory filters for (chan = 0; chan < nFilter2Process; chan++) { // Get index of current filter chanIdx = processFilter[chan]; // Calculate gain depending on middle ear filter if (bUseMidEar){ // Calculate middle ear coefficient fChan[chanIdx].midEarCoeff = DBtoAmplitude(loudnessLevelInPhons(DB,fChan[chanIdx].cf)-DB); // Calculate overall channel gain gain = fChan[chanIdx].midEarCoeff * pow(twoPiT * fChan[chanIdx].bw, 4) / 3.0; } else{ gain = pow(twoPiT * fChan[chanIdx].bw, 4) / 3.0; } z = exp(-twoPiT * fChan[chanIdx].bw); if (bTimeAlign){ // Integrate phase correction f1Down = cos(fChan[chanIdx].cf * twoPiT + fChan[chanIdx].phaseCorrection) * z; f2Down = sin(fChan[chanIdx].cf * twoPiT + fChan[chanIdx].phaseCorrection) * z; // Delay tc = getRound(fChan[chan].delay); } else{ f1Down = cos(fChan[chanIdx].cf * twoPiT) * z; f2Down = sin(fChan[chanIdx].cf * twoPiT) * z; // Delay tc = 0; } // Without phase correction f1Up = cos(fChan[chanIdx].cf * twoPiT) * z; f2Up = sin(fChan[chanIdx].cf * twoPiT) * z; // Initialize gammatone filter states for (ii = 0; ii < 4; ii++) { fChan[chanIdx].p[ii] = 0; fChan[chanIdx].q[ii] = 0; } // Loop over length of input signal for (nn = 0; nn < (nSamples + tc); nn++) { // *========================================== // * Basilar membrane displacement // *========================================== if (nn >= tc){ // % Basilar membrane displacement bm[(nn-tc)+chan*nSamples] = fChan[chanIdx].p[3] * gain; } // *========================================== // * Envelope // *========================================== if (nlhs>1){ if (nn >= tc){ // % Basilar membrane displacement env[(nn-tc)+chan*nSamples] = sqrt(fChan[chanIdx].p[3] * fChan[chanIdx].p[3] + fChan[chanIdx].q[3] * fChan[chanIdx].q[3]) * gain; } } // Loop over the order of the gammatone filterbank for (ii = 0; ii < 4; ii++) { x[ii] = f1Up * fChan[chanIdx].p[ii] - f2Up * fChan[chanIdx].q[ii]; y[ii] = f2Up * fChan[chanIdx].p[ii] + f1Up * fChan[chanIdx].q[ii]; } // Zero-padding data = (nn < nSamples) ? input[nn] : 0.0; fChan[chanIdx].p[0] = data * f1Down + x[0]; fChan[chanIdx].q[0] = data * f2Down + y[0]; fChan[chanIdx].p[1] = fChan[chanIdx].p[0] + x[1]; fChan[chanIdx].q[1] = fChan[chanIdx].q[0] + y[1]; fChan[chanIdx].p[2] = fChan[chanIdx].p[1] + x[1] + x[2]; fChan[chanIdx].q[2] = fChan[chanIdx].q[1] + y[1] + y[2]; fChan[chanIdx].p[3] = fChan[chanIdx].p[2] + x[1] + 2*x[2] + x[3]; fChan[chanIdx].q[3] = fChan[chanIdx].q[2] + y[1] + 2*y[2] + y[3]; } } // Free the memory used for the gammatone structure delete fChan; } // end of if(!bExit) } /* end mexFunction() */
// [bm, env, instp, instf] = gammatone_c(x, P_in, fs, cf, align, hrect) void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { double *x=0, *cf, *bm, *env = 0, *instp = 0, *instf = 0 ,*P_in=0, *P_out=0; int i, j, t, fs, nsamples, hrect, ch, Channels, align=0, intshift=0; double xx=0,a, tpt, tptbw, gain, envelopecomptime=0, phasealign=0; double p0r, p1r, p2r, p3r, p4r, p0i, p1i, p2i, p3i, p4i; double a1, a2, a3, a4, a5, u0r, u0i; /*, u1r, u1i;*/ double qcos, qsin, oldcs, coscf, sincf, oldphase, dp, dps; /*========================================= * Check argument numbers *========================================= */ if (nrhs < 4) { mexPrintf("??? Not enough input arguments.\n"); return; } if (nrhs > 6) { mexPrintf("??? Too many input arguments.\n"); return; } /*========================================= * input arguments *========================================= */ if (nrhs < 6) { hrect = 0; } else { hrect = (int)mxGetScalar(IN_hrect); } if (nrhs < 5) { align = 0; //default is align=off or zero } else { align = (int)mxGetScalar(IN_align); } Channels = mxGetN(IN_cf);//number of channels x = mxGetPr(IN_x); /* waveform */ i = mxGetN(IN_x); j = mxGetM(IN_x); if (i > 1 && j > 1) { mexPrintf("??? Input x must be a vector.\n"); return; } nsamples = myMax(i, j); fs = (int)mxGetScalar(IN_fs); /* sampling rate */ cf = mxGetPr(IN_cf); /* centre frequency */ P_in= mxGetPr ( IN_P ); /*========================================= * output arguments *========================================= */ OUT_bm = mxCreateDoubleMatrix( nsamples,Channels ,mxREAL); bm = mxGetPr(OUT_bm); if (nlhs > 1) { OUT_env = mxCreateDoubleMatrix(nsamples,Channels, mxREAL); env = mxGetPr(OUT_env); } if ( nlhs > 2 ) { OUT_P = mxCreateDoubleMatrix ( 8, Channels, mxREAL ); P_out = mxGetPr ( OUT_P ); } if (nlhs > 3) { OUT_instp = mxCreateDoubleMatrix(nsamples,Channels, mxREAL); instp = mxGetPr(OUT_instp); } if (nlhs > 4) { OUT_instf = mxCreateDoubleMatrix(nsamples,Channels, mxREAL); instf = mxGetPr(OUT_instf); } for (ch = 0; ch < Channels; ch++) { /*========================================= * Initialising variables *========================================= */ oldphase = 0.0; tpt = (M_PI + M_PI) / fs; tptbw = tpt * erb(cf[ch]) * BW_CORRECTION; a = exp(-tptbw); if (align) { //B=1.019*2*M_PI*erb(cf); envelopecomptime = 3/(BW_CORRECTION*2*M_PI*erb(cf[ch])); } else { envelopecomptime = 0; } intshift=(int)(floor(envelopecomptime*fs)); // // phasealign=-2*M_PI*cf[ch]*envelopecomptime; // //phasealign=mod(phasealign,2*M_PI); // phasealign=fmod(phasealign,2*M_PI); // //phasealign=myMod(phasealign,2*M_PI); // phasealign=phasealign/(2*M_PI*cf[ch]); /* based on integral of impulse response */ gain = (tptbw*tptbw*tptbw*tptbw) / 3; /* Update filter coefficients */ a1 = 4.0*a; a2 = -6.0*a*a; a3 = 4.0*a*a*a; a4 = -a*a*a*a; a5 = a*a; p0r = 0.0; p1r = P_in[0+ch*8]; p2r =P_in[1+ch*8]; p3r = P_in[2+ch*8]; p4r = P_in[3+ch*8]; //P[0]=p1r;P[1]=p2r;P[2]=p3r;P[3]=p4r;P[4]=p1i;P[5]=p2i;P[6]=p3i;P[7]=p4i; p0i = 0.0; p1i = P_in[4+ch*8]; p2i = P_in[5+ch*8]; p3i = P_in[6+ch*8]; p4i = P_in[7+ch*8]; /*=========================================================== * exp(a+i*b) = exp(a)*(cos(b)+i*sin(b)) * q = exp(-i*tpt*cf*t) = cos(tpt*cf*t) + i*(-sin(tpt*cf*t)) * qcos = cos(tpt*cf*t) * qsin = -sin(tpt*cf*t) *=========================================================== */ coscf = cos(tpt * cf[ch]); sincf = sin(tpt * cf[ch]); qcos = 1; qsin = 0; /* t=0 & q = exp(-i*tpt*t*cf)*/ for (t = 0; t < (nsamples); t++) { if (t>(nsamples-1)) { xx=0; } else { xx=x[t]; } /* x = [x zeros(1,intshift)]; kT=(0:length(x)-1)/fs; q=exp(1i.*(-wcf.*kT)).*x; % shift down to d.c. p=filter([1 0],[1 -4*a 6*a^2 -4*a^3 a^4],q); % filter: part 1 u=filter([1 4*a 4*a^2 0],[1 0],p); % filter: part 2 bm=gain*real(exp(1i*wcf*(kT(intshift+1:end)+phasealign)).*u(intshift+1:end)); % shift up in frequency env = gain*abs(u(intshift+1:end)); instf=real(cf+[diff(unwrap(angle(u(intshift+1:end)))) 0]./tpt); */ /* Filter part 1 & shift down to d.c. */ p0r = qcos*xx + a1*p1r + a2*p2r + a3*p3r + a4*p4r; p0i = qsin*xx + a1*p1i + a2*p2i + a3*p3i + a4*p4i; /* Clip coefficients to stop them from becoming too close to zero */ if (fabs(p0r) < VERY_SMALL_NUMBER) p0r = 0.0F; if (fabs(p0i) < VERY_SMALL_NUMBER) p0i = 0.0F; /* Filter part 2 */ u0r = p0r + a1*p1r + a5*p2r; u0i = p0i + a1*p1i + a5*p2i; /* Update filter results */ p4r = p3r; p3r = p2r; p2r = p1r; p1r = p0r; p4i = p3i; p3i = p2i; p2i = p1i; p1i = p0i; /*========================================== * Basilar membrane response * 1/ shift up in frequency first: (u0r+i*u0i) * exp(i*tpt*cf*t) = (u0r+i*u0i) * (qcos + i*(-qsin)) * 2/ take the real part only: bm = real(exp(j*wcf*kT).*u) * gain; bm = real(exp(j*wcf*kT+j*wcf*phasealign).*u) * gain; =(u0r+i*u0i) * (qcos + i*(-qsin))*(cos(phasealign)+i*sin(phasealign)) =(u0r+i*u0i) *(qcos*C+qsin*S +i(qcos*S-qsin*C))-->Real()=u0r * (qcos * C + qsin* S)+ u0i*(qsin*C-qcos*S) *========================================== */ if (t>(intshift-1)) { //bm[t + ch*(nsamples)-ch*(intshift)] = (u0r * qcos + u0i * qsin) * gain bm[t + ch*(nsamples)-(intshift)] =(u0r * (qcos * cos(2*M_PI*cf[ch]*phasealign) + qsin* sin(2*M_PI*cf[ch]*phasealign))+ u0i*(qsin*cos(2*M_PI*cf[ch]*phasealign)-qcos*sin(2*M_PI*cf[ch]*phasealign)) )* gain; if (1 == hrect && bm[t + ch*(nsamples)-(intshift)] < 0) { bm[t + ch*(nsamples)-(intshift)] = 0; /* half-wave rectifying */ } if ( nlhs > 1 ) { P_out[0+ch*8]=p1r;P_out[1+ch*8]=p2r;P_out[2+ch*8]=p3r;P_out[3+ch*8]=p4r;P_out[4+ch*8]=p1i;P_out[5+ch*8]=p2i;P_out[6+ch*8]=p3i;P_out[7+ch*8]=p4i; } /*========================================== * Instantaneous Hilbert envelope * env = abs(u) * gain; *========================================== */ if (nlhs > 2) { env[t + ch*(nsamples)-(intshift)] = sqrt(u0r * u0r + u0i * u0i) * gain; } /*========================================== * Instantaneous phase * instp = unwrap(angle(u)); *========================================== */ if (nlhs > 3) { instp[t + ch*(nsamples)-(intshift)] = atan2(u0i, u0r); /* unwrap it */ dp = instp[t + ch*(nsamples)-(intshift)] - oldphase; if (abs(dp) > M_PI) { dps = myMod(dp + M_PI, 2 * M_PI) - M_PI; if (dps == -M_PI && dp > 0) { dps = M_PI; } instp[t + ch*(nsamples)-(intshift)] = instp[t + ch*(nsamples)-(intshift)] + dps - dp; } oldphase = instp[t + ch*(nsamples)-(intshift)]; } /*========================================== * Instantaneous frequency * instf = cf + [diff(instp) 0]./tpt; *========================================== */ if (nlhs > 4 && t > (intshift)) { instf[t - 1 + ch*(nsamples)-(intshift)] = cf[ch] + (instp[t + ch*(nsamples)-(intshift)] - instp[t - 1 + ch*(nsamples)-(intshift)]) / tpt; } // // /*==================================================== // * The basic idea of saving computational load: // * cos(a+b) = cos(a)*cos(b) - sin(a)*sin(b) // * sin(a+b) = sin(a)*cos(b) + cos(a)*sin(b) // * qcos = cos(tpt*cf*t) = cos(tpt*cf + tpt*cf*(t-1)) // * qsin = -sin(tpt*cf*t) = -sin(tpt*cf + tpt*cf*(t-1)) // *==================================================== // */ } //t>(intshift-1) qcos = coscf * (oldcs = qcos) + sincf * qsin; qsin = coscf * qsin - sincf * oldcs; }//samples for loop if (nlhs > 4) { //instf[(ch+1)*nsamples - 1] = cf[ch]; instf[nsamples - 1] = cf[ch]; } }//Channels for loop return; } //mexFunction
int main(void) { wdt_enable(WDTO_2S); clock_prescale_set(clock_div_1); // Disable Clock Division // if we had been restarted by watchdog check the REQ BootLoader byte in the // EEPROM ... if (bit_is_set(MCUSR,WDRF) && erb(EE_REQBL)) { ewb( EE_REQBL, 0 ); // clear flag start_bootloader(); } // Setup the timers. Are needed for watchdog-reset OCR0A = 249; // Timer0: 0.008s = 8MHz/256/250 TCCR0B = _BV(CS02); TCCR0A = _BV(WGM01); TIMSK0 = _BV(OCIE0A); TCCR1A = 0; TCCR1B = _BV(CS11) | _BV(WGM12); // Timer1: 1us = 8MHz/8 #ifdef CURV3 // Timer3 is used by the LCD backlight (PWM) TCCR3A = _BV(COM3A1)| _BV(WGM30); // Fast PWM, 8-bit, clear on match TCCR3B = _BV(WGM32) | _BV(CS31); // Prescaler 8MHz/8: 3.9KHz #endif MCUSR &= ~(1 << WDRF); // Enable the watchdog led_init(); spi_init(); eeprom_init(); USB_Init(); fht_init(); tx_init(); joy_init(); // lcd init is done manually from menu_init bat_init(); df_init(&df); fs_init(&fs, df, 0); // needs df_init rtc_init(); // does i2c_init too log_init(); // needs fs_init & rtc_init menu_init(); // needs fs_init input_handle_func = analyze_ttydata; log_enabled = erb(EE_LOGENABLED); display_channel = DISPLAY_USB|DISPLAY_LCD|DISPLAY_RFROUTER; rf_router_init(); checkFrequency(); LED_OFF(); for(;;) { USB_USBTask(); CDC_Task(); RfAnalyze_Task(); Minute_Task(); FastRF_Task(); rf_router_task(); JOY_Task(); } }
int main(void) { wdt_enable(WDTO_2S); #if defined(CUL_ARDUINO) clock_prescale_set(clock_div_1); // for 8MHz clock div schould be 1 #endif MARK433_PORT |= _BV( MARK433_BIT ); // Pull 433MHz marker MARK915_PORT |= _BV( MARK915_BIT ); // Pull 915MHz marker // if we had been restarted by watchdog check the REQ BootLoader byte in the // EEPROM ... if(bit_is_set(MCUSR,WDRF) && erb(EE_REQBL)) { ewb( EE_REQBL, 0 ); // clear flag start_bootloader(); } // Setup the timers. Are needed for watchdog-reset OCR0A = 249; // Timer0: 0.008s = 8MHz/256/250 TCCR0B = _BV(CS02); TCCR0A = _BV(WGM01); TIMSK0 = _BV(OCIE0A); TCCR1A = 0; TCCR1B = _BV(CS11) | _BV(WGM12); // Timer1: 1us = 8MHz/8 MCUSR &= ~(1 << WDRF); // Enable the watchdog led_init(); spi_init(); eeprom_init(); USB_Init(); fht_init(); tx_init(); input_handle_func = analyze_ttydata; #ifdef HAS_RF_ROUTER rf_router_init(); display_channel = (DISPLAY_USB|DISPLAY_RFROUTER); #else display_channel = DISPLAY_USB; #endif checkFrequency(); LED_OFF(); for(;;) { USB_USBTask(); CDC_Task(); RfAnalyze_Task(); Minute_Task(); #ifdef HAS_FASTRF FastRF_Task(); #endif #ifdef HAS_RF_ROUTER rf_router_task(); #endif #ifdef HAS_ASKSIN rf_asksin_task(); #endif #ifdef HAS_MORITZ rf_moritz_task(); #endif #ifdef HAS_RWE rf_rwe_task(); #endif #ifdef HAS_RFNATIVE native_task(); #endif #ifdef HAS_KOPP_FC kopp_fc_task(); #endif #ifdef HAS_MBUS rf_mbus_task(); #endif #ifdef HAS_ZWAVE rf_zwave_task(); #endif } }
/*======================= * Main Function *======================= */ void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { double *x, *cf, *bm, *env = 0, *instp = 0, *instf = 0 ,*P_in=0, *P_out=0; int i, j, t, fs, nsamples, hrect, ch, Channels; double a, tpt, tptbw, gain; double p0r, p1r, p2r, p3r, p4r, p0i, p1i, p2i, p3i, p4i; double a1, a2, a3, a4, a5, u0r, u0i; /*, u1r, u1i;*/ double qcos, qsin, oldcs, coscf, sincf, oldphase, dp, dps; /*========================================= * Check argument numbers *========================================= */ if (nrhs < 4) { mexPrintf("??? Not enough input arguments.\n"); return; } if (nrhs > 5) { mexPrintf("??? Too many input arguments.\n"); return; } if (nlhs > 5) { mexPrintf("??? Too many output arguments.\n"); return; } /*========================================= * input arguments *========================================= */ if (nrhs < 5) { hrect = 0; } else { hrect = (int)mxGetScalar(IN_hrect); } Channels = mxGetN(IN_cf);//number of channles x = mxGetPr(IN_x); /* waveform */ i = mxGetN(IN_x); j = mxGetM(IN_x); if (i > 1 && j > 1) { mexPrintf("??? Input x must be a vector.\n"); return; } nsamples = myMax(i, j); fs = (int)mxGetScalar(IN_fs); /* sampling rate */ cf = mxGetPr(IN_cf); /* centre frequency */ P_in= mxGetPr ( IN_P ); /*========================================= * output arguments *========================================= */ OUT_bm = mxCreateDoubleMatrix( nsamples,Channels, mxREAL); bm = mxGetPr(OUT_bm); if (nlhs > 1) { OUT_env = mxCreateDoubleMatrix(nsamples,Channels, mxREAL); env = mxGetPr(OUT_env); } if ( nlhs > 2 ) { OUT_P = mxCreateDoubleMatrix ( 8, Channels, mxREAL ); P_out = mxGetPr ( OUT_P ); } if (nlhs > 3) { OUT_instp = mxCreateDoubleMatrix(nsamples,Channels, mxREAL); instp = mxGetPr(OUT_instp); } if (nlhs > 4) { OUT_instf = mxCreateDoubleMatrix(nsamples,Channels, mxREAL); instf = mxGetPr(OUT_instf); } for (ch = 0; ch < Channels; ch++) { /*========================================= * Initialising variables *========================================= */ oldphase = 0.0; tpt = (M_PI + M_PI) / fs; tptbw = tpt * erb(cf[ch]) * BW_CORRECTION; a = exp(-tptbw); /* based on integral of impulse response */ gain = (tptbw*tptbw*tptbw*tptbw) / 3; /* Update filter coefficients */ a1 = 4.0*a; a2 = -6.0*a*a; a3 = 4.0*a*a*a; a4 = -a*a*a*a; a5 = a*a; p0r = 0.0; p1r = P_in[0+ch*8]; p2r =P_in[1+ch*8]; p3r = P_in[2+ch*8]; p4r = P_in[3+ch*8]; //P[0]=p1r;P[1]=p2r;P[2]=p3r;P[3]=p4r;P[4]=p1i;P[5]=p2i;P[6]=p3i;P[7]=p4i; p0i = 0.0; p1i = P_in[4+ch*8]; p2i = P_in[5+ch*8]; p3i = P_in[6+ch*8]; p4i = P_in[7+ch*8]; /*=========================================================== * exp(a+i*b) = exp(a)*(cos(b)+i*sin(b)) * q = exp(-i*tpt*cf*t) = cos(tpt*cf*t) + i*(-sin(tpt*cf*t)) * qcos = cos(tpt*cf*t) * qsin = -sin(tpt*cf*t) *=========================================================== */ coscf = cos(tpt * cf[ch]); sincf = sin(tpt * cf[ch]); qcos = 1; qsin = 0; /* t=0 & q = exp(-i*tpt*t*cf)*/ for (t = 0; t < nsamples; t++) { /* Filter part 1 & shift down to d.c. */ p0r = qcos*x[t] + a1*p1r + a2*p2r + a3*p3r + a4*p4r; p0i = qsin*x[t] + a1*p1i + a2*p2i + a3*p3i + a4*p4i; /* Clip coefficients to stop them from becoming too close to zero */ if (fabs(p0r) < VERY_SMALL_NUMBER) p0r = 0.0F; if (fabs(p0i) < VERY_SMALL_NUMBER) p0i = 0.0F; /* Filter part 2 */ u0r = p0r + a1*p1r + a5*p2r; u0i = p0i + a1*p1i + a5*p2i; /* Update filter results */ p4r = p3r; p3r = p2r; p2r = p1r; p1r = p0r; p4i = p3i; p3i = p2i; p2i = p1i; p1i = p0i; /*========================================== * Basilar membrane response * 1/ shift up in frequency first: (u0r+i*u0i) * exp(i*tpt*cf*t) = (u0r+i*u0i) * (qcos + i*(-qsin)) * 2/ take the real part only: bm = real(exp(j*wcf*kT).*u) * gain; *========================================== */ bm[t + ch*(nsamples)] = (u0r * qcos + u0i * qsin) * gain; if (1 == hrect && bm[t + ch*(nsamples)] < 0) { bm[t + ch*(nsamples)] = 0; /* half-wave rectifying */ } if ( nlhs > 1 ) { P_out[0+ch*8]=p1r;P_out[1+ch*8]=p2r;P_out[2+ch*8]=p3r;P_out[3+ch*8]=p4r;P_out[4+ch*8]=p1i;P_out[5+ch*8]=p2i;P_out[6+ch*8]=p3i;P_out[7+ch*8]=p4i; } /*========================================== * Instantaneous Hilbert envelope * env = abs(u) * gain; *========================================== */ if (nlhs > 2) { env[t + ch*(nsamples)] = sqrt(u0r * u0r + u0i * u0i) * gain; } /*========================================== * Instantaneous phase * instp = unwrap(angle(u)); *========================================== */ if (nlhs > 3) { instp[t + ch*(nsamples)] = atan2(u0i, u0r); /* unwrap it */ dp = instp[t + ch*(nsamples)] - oldphase; if (abs(dp) > M_PI) { dps = myMod(dp + M_PI, 2 * M_PI) - M_PI; if (dps == -M_PI && dp > 0) { dps = M_PI; } instp[t + ch*(nsamples)] = instp[t + ch*(nsamples)] + dps - dp; } oldphase = instp[t + ch*(nsamples)]; } /*========================================== * Instantaneous frequency * instf = cf + [diff(instp) 0]./tpt; *========================================== */ if (nlhs > 4 && t > 0) { instf[t - 1 + ch*(nsamples)] = cf[ch] + (instp[t + ch*(nsamples)] - instp[t - 1 + ch*(nsamples)]) / tpt; } /*==================================================== * The basic idea of saving computational load: * cos(a+b) = cos(a)*cos(b) - sin(a)*sin(b) * sin(a+b) = sin(a)*cos(b) + cos(a)*sin(b) * qcos = cos(tpt*cf*t) = cos(tpt*cf + tpt*cf*(t-1)) * qsin = -sin(tpt*cf*t) = -sin(tpt*cf + tpt*cf*(t-1)) *==================================================== */ qcos = coscf * (oldcs = qcos) + sincf * qsin; qsin = coscf * qsin - sincf * oldcs; }//samples for loop if (nlhs > 4) { instf[nsamples - 1] = cf[ch]; } }//Channels for loop return; } //mexFunction
void rf_moritz_init(void) { #ifdef ARM #ifndef CC_ID AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_PIOA; // disable INT - we'll poll... #endif CC1100_CS_BASE->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup CC1100_CS_BASE->PIO_OER = _BV(CC1100_CS_PIN); //Enable output CC1100_CS_BASE->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); // disable INT - we'll poll... SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif CC1100_DEASSERT; // Toggle chip select signal my_delay_us(30); CC1100_ASSERT; my_delay_us(30); CC1100_DEASSERT; my_delay_us(45); CCSTROBE( CC1100_SRES ); // Send SRES command my_delay_us(100); #ifdef CC_ID CC1100_ASSERT; uint8_t *cfg = EE_CC1100_CFG; for(uint8_t i = 0; i < EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(erb(cfg++)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; #endif // load configuration for (uint8_t i = 0; i<60; i += 2) { if (pgm_read_byte( &MORITZ_CFG[i] )>0x40) break; CC1100_WRITEREG( pgm_read_byte(&MORITZ_CFG[i]), pgm_read_byte(&MORITZ_CFG[i+1]) ); } CCSTROBE( CC1100_SCAL ); my_delay_ms(4); // 4ms: Found by trial and error //This is ccRx() but without enabling the interrupt uint8_t cnt = 0xff; //Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1. //Why do it multiple times? while(cnt-- && (CCSTROBE( CC1100_SRX ) & 0x70) != 1) my_delay_us(10); moritz_on = 1; //todo check multiCC checkFrequency(); }
void // EEPROM Read IP erip(void *ip, uint8_t *addr) { uip_ipaddr(ip, erb(addr), erb(addr+1), erb(addr+2), erb(addr+3)); }