Sound4Calc/src/sound4calc.c

222 lines
5.2 KiB
C
Raw Normal View History

2017-02-25 11:29:24 +01:00
#include "sound4calc.h"
2017-01-12 22:41:56 +01:00
2017-02-25 22:23:56 +01:00
static struct {
int freq;
int length_ms;
} seq[] = {
2017-02-27 21:55:02 +01:00
{ 440, 500 },
{ 392, 500 },
2017-03-04 15:11:14 +01:00
{ 349, 1000 },
{ 262, 500 },
{ 294, 500 },
{ 262, 1000 },
2017-02-27 21:55:02 +01:00
{ -1, -1 },
2017-02-25 22:23:56 +01:00
};
2017-02-25 21:30:59 +01:00
2017-02-26 21:41:26 +01:00
struct Note note;
2017-02-26 14:16:21 +01:00
2017-05-16 11:26:25 +02:00
int frequency;
timer_t *timer = NULL;
2017-04-08 08:48:22 +02:00
2017-02-26 21:41:26 +01:00
/*
CallSequence()
make a little sound sequence
*/
2017-05-16 11:26:25 +02:00
/*void CallSequence(timer_t **timer)
2017-01-11 16:25:08 +01:00
{
2017-02-27 21:47:09 +01:00
static int seq_length = 0;
static int seq_note = -1;
2017-04-08 08:48:22 +02:00
2017-02-27 21:47:09 +01:00
if(seq_length<=0)
2017-02-25 21:30:59 +01:00
{
2017-02-27 21:47:09 +01:00
seq_note++;
2017-02-25 21:30:59 +01:00
2017-02-26 13:55:45 +01:00
//Stop the timer
2017-02-27 21:47:09 +01:00
if(seq[seq_note].freq < 0)
2017-02-26 13:55:45 +01:00
{
2017-02-27 21:47:09 +01:00
seq_length = 0;
seq_note = -1;
2017-04-08 08:48:22 +02:00
timer_stop(timer);
2017-02-26 13:55:45 +01:00
return;
}
2017-02-25 21:30:59 +01:00
2017-04-08 08:48:22 +02:00
uint32_t constant = clock_setting(note.wave.length * seq[seq_note].freq, clock_Hz);
*timer = htimer_setup(timer_user, constant, timer_Po_4, 0);
2017-05-16 11:26:25 +02:00
timer_attach(*timer, CallSequence, timer);
2017-04-08 08:48:22 +02:00
timer_start(*timer);
2017-02-26 13:55:45 +01:00
// update of the number of turn
2017-02-27 21:47:09 +01:00
seq_length = note.wave.length * seq[seq_note].freq * seq[seq_note].length_ms / 1000;
2017-02-26 13:55:45 +01:00
}
PlayNote();
2017-02-27 21:47:09 +01:00
seq_length--;
2017-05-16 11:26:25 +02:00
}*/
2016-05-14 22:19:51 +02:00
2017-04-08 08:48:22 +02:00
void Sequence()
{
2017-05-16 11:26:25 +02:00
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--;
2017-04-08 08:48:22 +02:00
}
2017-02-27 21:55:02 +01:00
/*
CallNote();
Create a single sound
*/
2017-05-16 11:26:25 +02:00
/*void CallNote()
2017-04-08 08:48:22 +02:00
{
2017-05-16 11:26:25 +02:00
//timer_t *timer = NULL;
uint32_t duration = note.freq * note.wave.length;
uint32_t constante = clock_setting(duration, clock_Hz);
2017-04-08 08:48:22 +02:00
2017-05-16 11:26:25 +02:00
timer = htimer_setup(timer_user, constante, timer_Po_4, 2 * duration);
timer_attach(timer, PlayNote, NULL);
}*/
2017-04-08 08:48:22 +02:00
void Note()
2017-02-26 13:55:45 +01:00
{
2017-05-16 11:26:25 +02:00
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);
2017-02-26 13:55:45 +01:00
}
2017-02-25 22:23:56 +01:00
2017-02-26 21:41:26 +01:00
/*
2017-02-27 21:47:09 +01:00
StopTimer()
Allow to stop the timer, it's to be independant with the main programm
2017-02-26 21:41:26 +01:00
*/
2017-02-26 15:07:48 +01:00
void StopTimer()
{
2017-05-16 11:26:25 +02:00
timer_stop(timer);
2017-02-26 15:07:48 +01:00
}
2017-02-27 21:47:09 +01:00
2017-02-25 17:22:24 +01:00
/*
2017-02-26 21:41:26 +01:00
PlayNote()
2017-04-08 08:48:22 +02:00
allow to make different waveforms with bits
2017-02-25 17:22:24 +01:00
*/
void PlayNote()
{
2017-02-26 13:55:45 +01:00
static int x = 0;
2017-02-25 22:23:56 +01:00
2017-03-04 15:11:14 +01:00
PutPinState((note.wave.signal >> x) & 0x01);
2017-02-26 13:55:45 +01:00
x = x + 1;
2017-04-08 08:48:22 +02:00
if(x >= note.wave.length)
2017-03-04 15:11:14 +01:00
{
x = 0;
}
2017-05-16 11:26:25 +02:00
2017-02-25 17:22:24 +01:00
}
2017-02-25 21:30:59 +01:00
/*
2017-02-26 21:41:26 +01:00
PutPinState()
put the pin at the level wanted
SH4 :
2017-03-04 15:11:14 +01:00
state 0 : xxxx.x0xx
state 1 : xxxx.x1xx
2017-05-16 11:26:25 +02:00
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
2017-04-08 08:48:22 +02:00
a lot of bits to the port in order to reduce the volume. (Poupe solution)
2017-03-04 15:11:14 +01:00
2017-02-26 21:41:26 +01:00
SH3 :
state 0 : xxxx.xxx0
state 1 : xxxx.xxx1
2017-02-25 21:30:59 +01:00
*/
void PutPinState(char level)
{
2017-02-26 13:55:45 +01:00
level = !!level;
if(isSH3())
{
*(volatile unsigned char*)SH7337_SCPDR = (*(volatile unsigned char*)SH7337_SCPDR & 0xFE) | level ;
}
else
{
2017-04-08 08:48:22 +02:00
*(volatile unsigned char*)SH7305_PJDR = (*(volatile unsigned char*)SH7305_PJDR & 0xFB) | (level << 0x2);
2017-02-26 13:55:45 +01:00
}
2017-02-25 21:30:59 +01:00
}
2017-02-25 17:22:24 +01:00
/*
2017-02-26 21:41:26 +01:00
InitPorts();
Ports initialisation
Open all need ports to use SwitchPinState()
2017-02-25 17:22:24 +01:00
*/
2017-02-25 11:29:24 +01:00
void InitPorts()
2016-05-14 22:19:51 +02:00
{
2017-02-26 13:55:45 +01:00
if(isSH3())
{
2017-02-24 21:57:01 +01:00
// SCIF2 clock on (STBCR3.MSTP31)
2017-02-26 13:55:45 +01:00
*(volatile unsigned char*)SH7337_STBCR3 &= ~0x02;
2017-02-24 21:57:01 +01:00
// switch off SCSMR_2.TE and SCSMR_2.RE
2017-02-26 13:55:45 +01:00
*(volatile unsigned short*)SH7337_SCSCR2 &= ~0x0030;
2017-02-24 21:57:01 +01:00
// SCIF2 clock off (STBCR3.MSTP31)
2017-02-26 13:55:45 +01:00
*(volatile unsigned char*)SH7337_STBCR3 |= 0x02;
2017-02-24 21:57:01 +01:00
// set bit 6 of port G to output mode
2017-02-26 13:55:45 +01:00
*(volatile unsigned short*)SH7337_PGCR = ( *(volatile unsigned short*)SH7337_PGCR & ~0x3000 ) | 0x1000;
2017-02-24 21:57:01 +01:00
// set bit 5 and 6 of port G
2017-02-26 13:55:45 +01:00
*(volatile unsigned char*)SH7337_PGDR |= 0x60;
2017-02-24 21:57:01 +01:00
// set port SC bit 0 to output
2017-02-26 13:55:45 +01:00
*(volatile unsigned short*)SH7337_SCPCR = ( *(volatile unsigned short*)SH7337_SCPCR & ~0x0003 ) | 0x0001;
}
else
{
2017-02-24 21:57:01 +01:00
// SCIF2 clock on (MSTPCR0.MSTP007)
2017-02-26 13:55:45 +01:00
*(volatile unsigned int*)SH7305_MSTPCR0 &= ~0x00000080;
2017-02-24 21:57:01 +01:00
// switch off SCSMR_2.TE and SCSMR_2.RE
2017-02-26 13:55:45 +01:00
*(volatile unsigned short*)SH7305_SCSCR &= ~0x0030;
2017-02-24 21:57:01 +01:00
// SCIF2 clock off (MSTPCR0.MSTP007)
2017-02-26 13:55:45 +01:00
*(volatile unsigned int*)SH7305_MSTPCR0 |= 0x00000080;
2017-02-24 21:57:01 +01:00
// set bit 3 of port U to output mode
2017-02-26 13:55:45 +01:00
*(volatile unsigned short*)SH7305_PUCR = ( *(volatile unsigned short*)SH7305_PUCR & ~0x00C0 ) | 0x0040;
2017-02-24 21:57:01 +01:00
// set bit 4 and 5 of port U
2017-02-26 13:55:45 +01:00
*(volatile unsigned char*)SH7305_PUDR |= 0x0C;
2017-02-25 21:30:59 +01:00
// set port J bit 2 to output
2017-05-16 11:26:25 +02:00
*(unsigned short*)SH7305_PJCR = ( *(unsigned short*)SH7305_PJCR & ~0x0030 ) | 0x0010;
2017-03-04 15:11:14 +01:00
2017-02-25 21:30:59 +01:00
// set port J bit 3 to input
2017-05-16 11:26:25 +02:00
*(unsigned short*)SH7305_PJCR= ( *(unsigned short*)SH7305_PJCR & ~0x00C0 ) | 0x0080;
2017-02-24 21:57:01 +01:00
// set port J bit 3 to output mode
2017-03-04 15:11:14 +01:00
//*(volatile unsigned short*)SH7305_PJCR = ( *(volatile unsigned short*)SH7305_PJCR & ~0x00C0 ) | 0x0040;
2017-02-26 13:55:45 +01:00
}
2017-01-12 22:41:56 +01:00
}