Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : MM+: Stereo Tone command
Author | Message | ||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8606 |
This was some code that I did for WhiteWizzard ages ago that required a modified version of the Micromite+ beta firmware but now works perfectly with V5.1 as standard. The format of the command is: TONE channel_number, pin_number, frequency in Hz, duration in seconds Channel_number can be zero or 1. Channel 0 will not interfere with IR commands, channel 1 will. The output in both cases is a square wave of the selected frequency. The command is non-blocking and returns to Basic immediately so to play "music" you need to pause after issuing the command before the next note. The frequency and duration are completely independent of the CPU speed. To play in "stereo" just issue the command twice in quick succession for one channel and then the other using (of course) different pin numbers If the command is issued while a note is playing on the same channel the new note will immediately replace the old one. There is only one restriction: calls to tone must be made with the frequency and duration defined by floating point variables and not literals so dim freq!= 400.0 dim dur! = 1.0 TONE 0, 12, freq!, dur! is valid TONE 0, 12, 400.0, 1.0 won't work and will lock up the Micromite CSUB tone 0000003C 'T1Int 3C029D00 8C43008C 8C640008 8C630004 AC830000 8C43008C 8C62000C 2444FFFF 1440000F AC64000C 24030010 3C02BF88 AC431064 3C02BF88 AC401068 3C02BF80 AC400600 3C029D00 8C4300AC AC600000 8C43008C AC600004 8C42008C AC400008 03E00008 00000000 'T5Int 3C029D00 8C43008C 8C640014 8C630010 AC830000 8C43008C 8C620018 2444FFFF 1440000F AC640018 3C030100 3C02BF88 AC431064 3C02BF88 AC401068 3C02BF80 AC400E00 3C029D00 8C4300B0 AC600000 8C43008C AC600010 8C42008C AC400014 03E00008 00000000 'getFPC 27BDFFF8 AFBF0004 00852023 03E42021 ACC40000 8FBF0004 03E00008 27BD0008 'main 27BDFFC0 AFBF003C AFB70038 AFB60034 AFB50030 AFB4002C AFB30028 AFB20024 AFB10020 AFB0001C 0080B021 00A0A821 00C09021 00E08821 00002021 3C059D00 24A50140 27A60010 0411FFE5 00000000 3C109D00 8E020058 8E440000 0040F809 8E250000 00408821 8E130058 8E02009C 0040F809 3C044000 02202021 0260F809 00402821 0040B821 8E020000 8C420000 8E03008C 3C04A5A5 3484A5A5 AC640000 3C0304C4 3463B401 0043182A 54600006 00022FC2 24430003 28450000 0065100B 10000003 00022883 00A22821 00052843 3C109D00 8E020080 00A02021 0040F809 00052FC3 8E030064 00402021 0060F809 8E450000 00408821 24120001 10000009 24140001 8E02009C 0040F809 3C044100 02202021 0260F809 00402821 00408821 001290C0 8E130068 8E020080 3404FFFF 0040F809 00002821 02202021 0260F809 00402821 5054FFEF 8E130064 8EC20000 8EC30004 00431025 14400047 24030010 3C030100 3C02BF88 AC431064 3C02BF88 AC401068 3C109D00 8E020010 8EA40000 24050008 0040F809 00003021 8E13008C 8E020024 8EA40000 0040F809 24050007 AE620014 8E13008C 8E020028 0040F809 8EA40000 24030001 00431004 AE620010 8E02001C 8EA40000 0040F809 24050005 8FA40010 8E0200B0 3C039D00 24630068 00641821 AC430000 8E13008C 8E02007C 0040F809 02E02021 AE620018 24020008 12420005 24100030 3A520040 24020060 00008021 0052800A 3C029D00 8C42007C 0040F809 02202021 3C03BF80 AC620E20 36108000 3C02BF80 AC500E00 2403001C 3C02BF88 AC4310E4 24030004 3C02BF88 AC4310E8 3C020100 3C03BF88 AC621034 3C03BF88 AC621064 3C03BF88 AC621068 10000045 8FBF003C 3C02BF88 AC431064 3C02BF88 AC401068 3C109D00 8E020010 8EA40000 24050008 0040F809 00003021 8E13008C 8E020024 8EA40000 0040F809 24050007 AE620008 8E13008C 8E020028 0040F809 8EA40000 24030001 00431004 AE620004 8E02001C 8EA40000 0040F809 24050005 8FA40010 8E0200AC 3C039D00 24630000 00641821 AC430000 8E13008C 8E02007C 0040F809 02E02021 AE62000C 24020008 12420005 24100010 3A520040 24020020 00008021 0052800A 3C029D00 8C42007C 0040F809 02202021 3C03BF80 AC620620 36108000 3C02BF80 AC500600 2403001C 3C02BF88 AC4310A4 24030004 3C02BF88 AC4310A8 24020010 3C03BF88 AC621034 3C03BF88 AC621064 3C03BF88 AC621068 8FBF003C 8FB70038 8FB60034 8FB50030 8FB4002C 8FB30028 8FB20024 8FB10020 8FB0001C 03E00008 27BD0040 End CSUB c-source: #define Version 100 //Version 1.00 #define _SUPPRESS_PLIB_WARNING // required for XC1.33 Later compiler versions will need PLIB to be installed #include <plib.h> // the pre Harmony peripheral libraries #include "../cfunctions.h" #define MX470 #define magic 0 #define t1pin 1 #define t1port 2 #define t1count 3 #ifdef MX470 #define t5pin 4 #define t5port 5 #define t5count 6 #endif // void T1Int(void){ *(volatile unsigned int *)CFuncRam[t1port]=CFuncRam[t1pin]; if(!(CFuncRam[t1count]--)){ mT1IntEnable(0); T1CON=0; CFuncT1=0; CFuncRam[t1pin]=0; CFuncRam[t1port]=0; } } #ifdef MX470 void T5Int(void){ *(volatile unsigned int *)CFuncRam[t5port]=CFuncRam[t5pin]; if(!(CFuncRam[t5count]--)){ mT5IntEnable(0); T5CON=0; CFuncT5=0; CFuncRam[t5pin]=0; CFuncRam[t5port]=0; } } #endif __attribute__((noinline)) void getFPC(void *a, void *b, volatile unsigned int *c) { *c = (unsigned int) (__builtin_return_address (0) - (b -a)) ; } #ifdef MX470 void main(long long *channel, long long *pin, float *frequency, float *duration){ #else void main(long long *pin, float *frequency, float *duration){ #endif volatile unsigned int libAddr ; getFPC(NULL,&&getFPCLab,&libAddr) ; // warning can be ignored, stupid editor getFPCLab: { } int ps,clockspeed,divide=1; float counts,tickspersecond,tickrate; counts=FMul(*frequency,*duration); counts=FMul(counts,LoadFloat(0x40000000)); //number of interrupts for the pulse train clockspeed=CurrentCpuSpeed; CFuncRam[magic]=0xA5A5A5A5; if(clockspeed>80000000){ //start by assuming divide by 1 clockspeed/=4; } else { clockspeed/=2; } tickspersecond=IntToFloat(clockspeed); tickrate=FDiv(tickspersecond,*frequency); while(FCmp(tickrate,IntToFloat(0xFFFF))==1){ tickrate=FDiv(tickrate,LoadFloat(0x41000000)); divide*=8; } #ifdef MX470 if(*channel==0){ mT5IntEnable(0); ExtCfg(*pin,EXT_DIG_OUT,0); CFuncRam[t5port]=(int)(volatile unsigned int *)GetPortAddr(*pin,LATINV); CFuncRam[t5pin]=1<<GetPinBit(*pin); PinSetBit(*pin, LATCLR); CFuncT5=(unsigned int)&T5Int + libAddr; CFuncRam[t5count]=FloatToInt(counts); //used to hold count of cycles ps=0; if(divide==8)ps=0x30; if(divide==64)ps=0x60; PR5 = FloatToInt(tickrate); T5CON = 0x8000 | ps; // T5 on, prescaler as input mT5SetIntPriority(1); // high priority mT5ClearIntFlag(); // clear interrupt flag mT5IntEnable(1); } else #endif { mT1IntEnable(0); ExtCfg(*pin,EXT_DIG_OUT,0); CFuncRam[t1port]=(int)(volatile unsigned int *)GetPortAddr(*pin,LATINV); CFuncRam[t1pin]=1<<GetPinBit(*pin); PinSetBit(*pin, LATCLR); CFuncT1=(unsigned int)&T1Int + libAddr; CFuncRam[t1count]=FloatToInt(counts); //used to hold count of cycles ps=0; if(divide==8)ps=0x10; if(divide==64)ps=0x20; PR1 = FloatToInt(tickrate); T1CON = 0x8000 | ps; // T1 on, prescaler as input mT1SetIntPriority(1); // high priority mT1ClearIntFlag(); // clear interrupt flag mT1IntEnable(1); } } |
||||
WhiteWizzard Guru Joined: 05/04/2013 Location: United KingdomPosts: 2794 |
And as all your code, it worked brilliantly well! Is there a 'technical requirement' that causes it to interfere with IR? Also, (without trying it), does the IR not respond correctly (but the music keep playing!!) OR does the IR cause the music to stop/pause/fail along with zero/corrupt/intermittent reception of IR. Thanks, WW For everything Micromite visit micromite.org Direct Email: whitewizzard@micromite.o |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8606 |
They use the same hardware timer. The PIC32s have a very small number of timers so it isn't possible to dedicate one for TONE except timer 5 on the MM+ Timer 5 on the MM2 is used for com2 so isn't available to CFunctions No idea - they are completely incompatible so not worth trying |
||||
Print this page |