Sound4Calc/src/sound4calc.c

222 lines
5.2 KiB
C

#include "sound4calc.h"
static struct {
int freq;
int length_ms;
} seq[] = {
{ 440, 500 },
{ 392, 500 },
{ 349, 1000 },
{ 262, 500 },
{ 294, 500 },
{ 262, 1000 },
{ -1, -1 },
};
struct Note note;
int frequency;
timer_t *timer = NULL;
/*
CallSequence()
make a little sound sequence
*/
/*void CallSequence(timer_t **timer)
{
static int seq_length = 0;
static int seq_note = -1;
if(seq_length<=0)
{
seq_note++;
//Stop the timer
if(seq[seq_note].freq < 0)
{
seq_length = 0;
seq_note = -1;
timer_stop(timer);
return;
}
uint32_t constant = clock_setting(note.wave.length * seq[seq_note].freq, clock_Hz);
*timer = htimer_setup(timer_user, constant, timer_Po_4, 0);
timer_attach(*timer, CallSequence, timer);
timer_start(*timer);
// update of the number of turn
seq_length = note.wave.length * seq[seq_note].freq * seq[seq_note].length_ms / 1000;
}
PlayNote();
seq_length--;
}*/
void Sequence()
{
static int seq_length = 0;
static int seq_note = -1;
if(seq_length<=0)
{
seq_note++;
//Stop the timer
if(seq[seq_note].freq < 0)
{
seq_length = 0;
seq_note = -1;
timer_stop(timer);
return;
}
uint32_t constant = clock_setting(note.wave.length * seq[seq_note].freq, clock_Hz);
timer = htimer_setup(timer_user, constant, timer_Po_4, 0);
timer_attach(timer, Sequence, NULL);
timer_start(timer);
// update of the number of turn
seq_length = note.wave.length * seq[seq_note].freq * seq[seq_note].length_ms / 1000;
}
PlayNote();
seq_length--;
}
/*
CallNote();
Create a single sound
*/
/*void CallNote()
{
//timer_t *timer = NULL;
uint32_t duration = note.freq * note.wave.length;
uint32_t constante = clock_setting(duration, clock_Hz);
timer = htimer_setup(timer_user, constante, timer_Po_4, 2 * duration);
timer_attach(timer, PlayNote, NULL);
}*/
void Note()
{
uint32_t duration = note.freq * note.wave.length;
uint32_t constante = clock_setting(duration, clock_Hz);
timer = htimer_setup(timer_user, constante, timer_Po_4, 2 * duration);
timer_attach(timer, PlayNote, NULL);
timer_start(timer);
}
/*
StopTimer()
Allow to stop the timer, it's to be independant with the main programm
*/
void StopTimer()
{
timer_stop(timer);
}
/*
PlayNote()
allow to make different waveforms with bits
*/
void PlayNote()
{
static int x = 0;
PutPinState((note.wave.signal >> x) & 0x01);
x = x + 1;
if(x >= note.wave.length)
{
x = 0;
}
}
/*
PutPinState()
put the pin at the level wanted
SH4 :
state 0 : xxxx.x0xx
state 1 : xxxx.x1xx
We can put 2 other state (on bit 3) but the sound volume is too high
We could reduce the sound volume but we have to send
a lot of bits to the port in order to reduce the volume. (Poupe solution)
SH3 :
state 0 : xxxx.xxx0
state 1 : xxxx.xxx1
*/
void PutPinState(char level)
{
level = !!level;
if(isSH3())
{
*(volatile unsigned char*)SH7337_SCPDR = (*(volatile unsigned char*)SH7337_SCPDR & 0xFE) | level ;
}
else
{
*(volatile unsigned char*)SH7305_PJDR = (*(volatile unsigned char*)SH7305_PJDR & 0xFB) | (level << 0x2);
}
}
/*
InitPorts();
Ports initialisation
Open all need ports to use SwitchPinState()
*/
void InitPorts()
{
if(isSH3())
{
// SCIF2 clock on (STBCR3.MSTP31)
*(volatile unsigned char*)SH7337_STBCR3 &= ~0x02;
// switch off SCSMR_2.TE and SCSMR_2.RE
*(volatile unsigned short*)SH7337_SCSCR2 &= ~0x0030;
// SCIF2 clock off (STBCR3.MSTP31)
*(volatile unsigned char*)SH7337_STBCR3 |= 0x02;
// set bit 6 of port G to output mode
*(volatile unsigned short*)SH7337_PGCR = ( *(volatile unsigned short*)SH7337_PGCR & ~0x3000 ) | 0x1000;
// set bit 5 and 6 of port G
*(volatile unsigned char*)SH7337_PGDR |= 0x60;
// set port SC bit 0 to output
*(volatile unsigned short*)SH7337_SCPCR = ( *(volatile unsigned short*)SH7337_SCPCR & ~0x0003 ) | 0x0001;
}
else
{
// SCIF2 clock on (MSTPCR0.MSTP007)
*(volatile unsigned int*)SH7305_MSTPCR0 &= ~0x00000080;
// switch off SCSMR_2.TE and SCSMR_2.RE
*(volatile unsigned short*)SH7305_SCSCR &= ~0x0030;
// SCIF2 clock off (MSTPCR0.MSTP007)
*(volatile unsigned int*)SH7305_MSTPCR0 |= 0x00000080;
// set bit 3 of port U to output mode
*(volatile unsigned short*)SH7305_PUCR = ( *(volatile unsigned short*)SH7305_PUCR & ~0x00C0 ) | 0x0040;
// set bit 4 and 5 of port U
*(volatile unsigned char*)SH7305_PUDR |= 0x0C;
// set port J bit 2 to output
*(unsigned short*)SH7305_PJCR = ( *(unsigned short*)SH7305_PJCR & ~0x0030 ) | 0x0010;
// set port J bit 3 to input
*(unsigned short*)SH7305_PJCR= ( *(unsigned short*)SH7305_PJCR & ~0x00C0 ) | 0x0080;
// set port J bit 3 to output mode
//*(volatile unsigned short*)SH7305_PJCR = ( *(volatile unsigned short*)SH7305_PJCR & ~0x00C0 ) | 0x0040;
}
}