Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 16:54 19 May 2024 Privacy Policy
Jump to

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 Kingdom
Posts: 8606
Posted: 10:57pm 18 Feb 2016
Copy link to clipboard 
Print this post

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);
}
}
Edited by matherp 2016-02-20
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 12:59am 19 Feb 2016
Copy link to clipboard 
Print this post

  matherp said   This was some code that I did for WhiteWizzard ages ago

And as all your code, it worked brilliantly well!

  matherp said   Channel_number can be zero or 1. Channel 0 will not interfere with IR commands, channel 1 will.


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 Kingdom
Posts: 8606
Posted: 01:15am 19 Feb 2016
Copy link to clipboard 
Print this post

  Quote  Is there a 'technical requirement' that causes it to interfere with IR?


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

  Quote  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.


No idea - they are completely incompatible so not worth trying
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024