diff --git a/Main.c b/Main.c
index 508ac95..efebb3e 100644
--- a/Main.c
+++ b/Main.c
@@ -8,6 +8,8 @@
This file contains the main app function and init.
*/
+#include "audio.h"
+#include "Board_DAC.h"
#include "Welcome.h"
//25x25 Dot Qr Code, 25bits per line (x)
@@ -71,6 +73,9 @@ int main (void)
*/
static void vMainInitApp(void)
{
+ // Init audio pin
+ DAC_Initialize();
+
// Init GLCD
GLCD_Initialize ();
GLCD_SetForegroundColor (GLCD_COLOR_BLACK);
@@ -81,6 +86,13 @@ static void vMainInitApp(void)
// Init LED
LED_Initialize();
+
+ vStartAudio();
+ vPrintQr();
+
+ while (1)
+ {
+ }
}
/**
diff --git a/RTE/_MCB1760_mit_LPC1768/RTE_Components.h b/RTE/_MCB1760_mit_LPC1768/RTE_Components.h
index cc7f6a8..77d94e1 100644
--- a/RTE/_MCB1760_mit_LPC1768/RTE_Components.h
+++ b/RTE/_MCB1760_mit_LPC1768/RTE_Components.h
@@ -1,27 +1,32 @@
-
-/*
- * Auto generated Run-Time-Environment Component Configuration File
- * *** Do not modify ! ***
- *
- * Project: 'Welcome'
- * Target: 'MCB1760 mit LPC1768'
- */
-
-#ifndef RTE_COMPONENTS_H
-#define RTE_COMPONENTS_H
-
-
-/*
- * Define the Device Header File:
- */
-#define CMSIS_device_header "LPC17xx.h"
-
-#define RTE_DEVICE_STARTUP_LPC17XX /* Device Startup for NXP17XX */
-#define RTE_Drivers_I2C0 /* Driver I2C0 */
- #define RTE_Drivers_I2C1 /* Driver I2C1 */
- #define RTE_Drivers_I2C2 /* Driver I2C2 */
-#define RTE_Drivers_SPI0 /* Driver SPI0 */
- #define RTE_Drivers_SPI1 /* Driver SPI1 */
-#define RTE_Drivers_SPI2 /* Driver SPI2 */
-
-#endif /* RTE_COMPONENTS_H */
+
+/*
+ * Auto generated Run-Time-Environment Configuration File
+ * *** Do not modify ! ***
+ *
+ * Project: 'Welcome'
+ * Target: 'MCB1760 mit LPC1768'
+ */
+
+#ifndef RTE_COMPONENTS_H
+#define RTE_COMPONENTS_H
+
+
+/*
+ * Define the Device Header File:
+ */
+#define CMSIS_device_header "LPC17xx.h"
+
+/* Keil::CMSIS Driver:I2C:2.4.0 */
+#define RTE_Drivers_I2C0 /* Driver I2C0 */
+ #define RTE_Drivers_I2C1 /* Driver I2C1 */
+ #define RTE_Drivers_I2C2 /* Driver I2C2 */
+/* Keil::CMSIS Driver:SPI:SPI:2.1.0 */
+#define RTE_Drivers_SPI2 /* Driver SPI2 */
+/* Keil::CMSIS Driver:SPI:SSP:2.7.0 */
+#define RTE_Drivers_SPI0 /* Driver SPI0 */
+ #define RTE_Drivers_SPI1 /* Driver SPI1 */
+/* Keil::Device:Startup:1.0.0 */
+#define RTE_DEVICE_STARTUP_LPC17XX /* Device Startup for NXP17XX */
+
+
+#endif /* RTE_COMPONENTS_H */
diff --git a/Welcome.uvoptx b/Welcome.uvoptx
index 513fe7f..b8173f7 100644
--- a/Welcome.uvoptx
+++ b/Welcome.uvoptx
@@ -10,7 +10,7 @@
*.s*; *.src; *.a*
*.obj; *.o
*.lib
- *.txt; *.h; *.inc
+ *.txt; *.h; *.inc; *.md
*.plm
*.cpp
0
@@ -77,7 +77,7 @@
0
1
- 0
+ 8
0
1
@@ -140,10 +140,59 @@
0
UL2CM3
- -UAny -O206 -S8 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD10000000 -FCFE0 -FN1 -FF0LPC_IAP_512.FLM -FS00 -FL080000 -FP0($$Device:LPC1768$Flash\LPC_IAP_512.FLM)
+ -UAny -O206 -S8 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD10000000 -FCFE0 -FN1 -FF0LPC_IAP_512.FLM -FS00 -FL080000 -FP0($$Device:LPC1768$Flash\LPC_IAP_512.FLM)
-
+
+
+ 0
+ 0
+ 48
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ .\audio.c
+
+
+
+
+ 1
+ 0
+ 47
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ .\audio.c
+
+
+
+
+ 2
+ 0
+ 81
+ 1
+ 8200
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ .\audio.c
+
+ \\Welcome\audio.c\81
+
+
0
@@ -226,6 +275,54 @@
0
0
+
+ 1
+ 3
+ 1
+ 1
+ 0
+ 0
+ .\audio.c
+ audio.c
+ 0
+ 0
+
+
+ 1
+ 4
+ 5
+ 0
+ 0
+ 0
+ .\audio.h
+ audio.h
+ 0
+ 0
+
+
+ 1
+ 5
+ 1
+ 0
+ 0
+ 0
+ .\melody.c
+ melody.c
+ 0
+ 0
+
+
+ 1
+ 6
+ 5
+ 0
+ 0
+ 0
+ .\melody.h
+ melody.h
+ 0
+ 0
+
diff --git a/Welcome.uvprojx b/Welcome.uvprojx
index f351e56..e542e43 100644
--- a/Welcome.uvprojx
+++ b/Welcome.uvprojx
@@ -10,7 +10,7 @@
MCB1760 mit LPC1768
0x4
ARM-ADS
- 5060750::V5.06 update 6 (build 750)::ARMCC
+ 5060960::V5.06 update 7 (build 960)::.\ARMCC
0
@@ -185,6 +185,7 @@
0
0
0
+ 0
1
0
8
@@ -351,7 +352,7 @@
0
0
0
- 0
+ 4
@@ -392,6 +393,26 @@
5
.\Welcome.h
+
+ audio.c
+ 1
+ .\audio.c
+
+
+ audio.h
+ 5
+ .\audio.h
+
+
+ melody.c
+ 1
+ .\melody.c
+
+
+ melody.h
+ 5
+ .\melody.h
+
diff --git a/audio.c b/audio.c
new file mode 100644
index 0000000..3af528d
--- /dev/null
+++ b/audio.c
@@ -0,0 +1,106 @@
+#include "audio.h"
+#include "Board_DAC.h"
+#include "LPC17xx.h"
+#include "melody.h"
+
+#define FREQ(x) ((x & 0xffff0000) >> 16)
+#define WAVES(x) (x & 0xffff)
+
+struct AudioState
+{
+ bool highState;
+ uint16_t u16RemainingWaves;
+ uint32_t u32EndBreak;
+ const uint32_t *cpu32NextAction;
+ uint32_t u32StackPointer;
+ const uint32_t *cpu32Stack[10];
+};
+
+static struct AudioState sAudioState;
+
+bool bPerformAudioStep()
+{
+ bool bSuccess = true;
+ struct AudioState *psState = &sAudioState;
+ psState = psState;
+
+ sAudioState.highState = !sAudioState.highState;
+ if (sAudioState.highState)
+ {
+ DAC_SetValue(512);
+ if (sAudioState.u16RemainingWaves == 0)
+ {
+ LPC_TIM0->MR0 = sAudioState.u32EndBreak;
+ }
+ }
+ else
+ {
+ DAC_SetValue(0);
+ if (sAudioState.u16RemainingWaves > 0)
+ {
+ sAudioState.u16RemainingWaves--;
+ }
+ else
+ {
+ if (FREQ(*sAudioState.cpu32NextAction) == 0)
+ {
+ sAudioState.highState = true;
+ sAudioState.cpu32NextAction = cppu32JumpLabels[*sAudioState.cpu32NextAction];
+ bSuccess = false;
+ }
+ else if (FREQ(*sAudioState.cpu32NextAction) == 1)
+ {
+ sAudioState.highState = true;
+ sAudioState.cpu32Stack[sAudioState.u32StackPointer] = sAudioState.cpu32NextAction + 1;
+ sAudioState.cpu32NextAction = cppu32JumpLabels[WAVES(*sAudioState.cpu32NextAction)];
+ sAudioState.u32StackPointer++;
+ bSuccess = false;
+ }
+ else if (FREQ(*sAudioState.cpu32NextAction) == 2)
+ {
+ sAudioState.highState = true;
+ sAudioState.u32StackPointer--;
+ sAudioState.cpu32NextAction = sAudioState.cpu32Stack[sAudioState.u32StackPointer];
+ bSuccess = false;
+ }
+ else
+ {
+ uint32_t u32Frequency = FREQ(*sAudioState.cpu32NextAction);
+ LPC_TIM0->MR0 = u32Frequency * 2;
+ uint32_t u32Waves = WAVES(*sAudioState.cpu32NextAction);
+ sAudioState.u16RemainingWaves = u32Waves * 9 / 10 - 1;
+ sAudioState.u32EndBreak = u32Waves * u32Frequency * 2 / 5;
+ sAudioState.cpu32NextAction++;
+ }
+ }
+ }
+
+ return bSuccess;
+}
+
+void TIMER0_IRQHandler()
+{
+ LPC_TIM0->IR = 0x1; // acknowledge interrupt
+
+ while (!bPerformAudioStep())
+ {
+ }
+}
+
+// Initializes the interrupt-driven audio output
+void vStartAudio()
+{
+ sAudioState.highState = true;
+ sAudioState.u16RemainingWaves = 0;
+ sAudioState.cpu32NextAction = cpu32EntryPoint;
+ sAudioState.u32StackPointer = 0;
+
+ // Init timerinterrupt 0 (20 ms)
+ LPC_SC->PCONP |= (1 << 2); // turn on
+ LPC_SC->PCLKSEL0 |= (1 << 2); // select clock
+ LPC_TIM0->MR0 = 100000 * 2 - 1;
+ LPC_TIM0->MCR = 0x3;
+ NVIC_SetPriority(TIMER0_IRQn, 1U); // priority
+ NVIC_EnableIRQ(TIMER0_IRQn);
+ LPC_TIM0->TCR = 1; // start
+}
diff --git a/audio.h b/audio.h
new file mode 100644
index 0000000..4d7694e
--- /dev/null
+++ b/audio.h
@@ -0,0 +1,8 @@
+#ifndef AUDIO_H
+#define AUDIO_H
+
+#include
+
+void vStartAudio(void);
+
+#endif
diff --git a/melody.c b/melody.c
new file mode 100644
index 0000000..c09dc68
--- /dev/null
+++ b/melody.c
@@ -0,0 +1,90 @@
+#include "melody.h"
+
+// freq: wave duration as multiple of 40ns
+// duration: total duration as multiple of 40ns
+#define TONE(freq, duration) ((((uint32_t)freq & 0xffff) << 16) | (((uint32_t)duration / (uint32_t)freq) & 0xffff))
+
+const uint32_t TACT = 2120 * 1000 * 25; // 2.12 seconds for one tact
+
+const uint32_t GIS2 = 30098;
+const uint32_t F = 35793;
+const uint32_t DIS = 40177;
+const uint32_t CIS = 45097;
+const uint32_t C = 47778;
+const uint32_t B = 53629;
+const uint32_t GIS = 60197;
+
+const uint32_t CALL = 0x10000;
+const uint32_t RETURN = 0x20000;
+
+const uint32_t refrain[];
+const uint32_t quadrupel[];
+const uint32_t *cpu32EntryPoint = refrain;
+
+const uint32_t GOTO_REFRAIN = 0;
+const uint32_t CALL_QUADRUPEL = CALL + 1;
+
+const uint32_t *jumplabels[] = {
+ refrain,
+ quadrupel,
+};
+const uint32_t **cppu32JumpLabels = jumplabels;
+
+const uint32_t quadrupel[] = {
+ TONE(GIS, TACT / 16),
+ TONE(B, TACT / 16),
+ TONE(CIS, TACT / 16),
+ TONE(B, TACT / 16),
+ RETURN,
+};
+
+const uint32_t refrain[] = {
+ CALL_QUADRUPEL,
+
+ TONE(F, TACT * 3 / 16),
+ TONE(F, TACT * 3 / 16),
+ TONE(DIS, TACT * 3 / 8),
+ CALL_QUADRUPEL,
+
+ TONE(DIS, TACT * 3 / 16),
+ TONE(DIS, TACT * 3 / 16),
+ TONE(CIS, TACT * 3 / 16),
+ TONE(C, TACT / 16),
+ TONE(B, TACT / 8),
+ CALL_QUADRUPEL,
+
+ TONE(CIS, TACT / 4),
+ TONE(DIS, TACT / 8),
+ TONE(C, TACT * 3 / 16),
+ TONE(B, TACT / 16),
+ TONE(GIS, TACT / 4),
+ TONE(GIS, TACT / 8),
+
+ TONE(DIS, TACT / 4),
+ TONE(CIS, TACT / 2),
+ CALL_QUADRUPEL,
+
+ TONE(F, TACT * 3 / 16),
+ TONE(F, TACT * 3 / 16),
+ TONE(DIS, TACT * 3 / 8),
+ CALL_QUADRUPEL,
+
+ TONE(GIS2,TACT / 4),
+ TONE(C, TACT / 8),
+ TONE(CIS, TACT * 3 / 16),
+ TONE(C, TACT / 16),
+ TONE(B, TACT / 8),
+ CALL_QUADRUPEL,
+
+ TONE(CIS, TACT / 4),
+ TONE(DIS, TACT / 8),
+ TONE(C, TACT * 3 / 16),
+ TONE(B, TACT / 16),
+ TONE(GIS, TACT / 4),
+ TONE(GIS, TACT / 8),
+
+ TONE(DIS, TACT / 4),
+ TONE(CIS, TACT / 2),
+
+ GOTO_REFRAIN,
+};
diff --git a/melody.h b/melody.h
new file mode 100644
index 0000000..c8bbdd3
--- /dev/null
+++ b/melody.h
@@ -0,0 +1,9 @@
+#ifndef MELODY_H
+#define MELODY_H
+
+#include "stdint.h"
+
+extern const uint32_t *cpu32EntryPoint;
+extern const uint32_t **cppu32JumpLabels;
+
+#endif