forked from tenbaht/sduino
-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
1,048 additions
and
0 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
ch55xduino/ch55x/libraries/Generic_Examples/examples/05.USB/SoundCard/SoundCard.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
USB sound card example | ||
created 2024 | ||
by Deqing Sun for use with CH55xduino | ||
CH552 act as mono 24000K sound card | ||
playback high 8bit on P3.4 | ||
Improved from ziv2013's work | ||
This example code is in the public domain. | ||
cli board options: usb_settings=user148 | ||
*/ | ||
|
||
#ifndef USER_USB_RAM | ||
#error "This example needs to be compiled with a USER USB setting" | ||
#endif | ||
|
||
#include "src/USBAudioSpeaker/USBAudioSpeaker.h" | ||
|
||
void setup() { | ||
|
||
USBInit(); | ||
|
||
// PWM2 is on P3.4 | ||
pinMode(34, OUTPUT); | ||
// turn on PWM2 | ||
PIN_FUNC &= ~(bPWM2_PIN_X); | ||
// Set PWM to Fsys/256 with 1 divider | ||
PWM_CK_SE = 1; | ||
PWM_CTRL |= bPWM2_OUT_EN; | ||
PWM_DATA2 = 128; | ||
} | ||
|
||
|
||
void loop() { | ||
|
||
} |
155 changes: 155 additions & 0 deletions
155
...ibraries/Generic_Examples/examples/05.USB/SoundCard/src/USBAudioSpeaker/USBAudioSpeaker.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
// clang-format off | ||
#include <Arduino.h> | ||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include "include/ch5xx.h" | ||
#include "include/ch5xx_usb.h" | ||
#include "USBconstant.h" | ||
#include "USBhandler.h" | ||
#include "USBAudioSpeaker.h" | ||
// clang-format on | ||
|
||
__xdata volatile uint8_t soundBufferPlayBackIndex = 0; | ||
|
||
#define T2_RELOAD_VALUE (65536 - F_CPU / 24000) | ||
#define T2_RELOAD_VALUE_LOW (T2_RELOAD_VALUE & 0xFF) | ||
#define T2_RELOAD_VALUE_HIGH ((T2_RELOAD_VALUE >> 8) & 0xFF) | ||
#define T2_RELOAD_VALUE_NEAR_FINISH (65536 - F_CPU / 24000 / 4) | ||
#define T2_RELOAD_VALUE_NEAR_FINISH_LOW (T2_RELOAD_VALUE_NEAR_FINISH & 0xFF) | ||
#define T2_RELOAD_VALUE_NEAR_FINISH_HIGH \ | ||
((T2_RELOAD_VALUE_NEAR_FINISH >> 8) & 0xFF) | ||
|
||
void Timer2Interrupt(void) __interrupt { | ||
// if (TF2) { | ||
// TF2 = 0; | ||
// __data signed char highByteOfPCM = | ||
// Ep1Buffer[(soundBufferPlayBackIndex<<1)+1]; | ||
// __data unsigned char highByteOfPCMUnsigned = highByteOfPCM+128; | ||
|
||
// PWM_CTRL |= bPWM_IF_END; | ||
// while (!(PWM_CTRL & bPWM_IF_END)); | ||
// PWM_DATA2 = highByteOfPCMUnsigned; | ||
// soundBufferPlayBackIndex++; | ||
// } | ||
|
||
// due to PWM bug, https://github.com/DeqingSun/ch55xduino/issues/135 | ||
// we need to carefully handle the PWM data | ||
// and SDCC is not good at handling partial inline assembly. | ||
// we just do everything in inline assembly. | ||
__asm__(";check if TF2 is set \n" | ||
" jb _TF2,notSkipTimer2INTR$ \n" | ||
" sjmp skipTimer2INTR$ \n" | ||
"notSkipTimer2INTR$: \n" | ||
" clr _TF2 \n" | ||
|
||
";get (soundBufferPlayBackIndex<<1)+1 \n" | ||
";also inc soundBufferPlayBackIndex \n" | ||
" mov dptr,#_soundBufferPlayBackIndex \n" | ||
" movx a,@dptr \n" | ||
" mov r7,a \n" | ||
";check if soundBufferPlayBackIndex is too big \n" | ||
" add a,#232 \n" | ||
" jnc soundBufferPlayBackIndexNotBig$ \n" | ||
" sjmp skipTimer2INTR$ \n" | ||
"soundBufferPlayBackIndexNotBig$: \n" | ||
" mov a,r7 \n" | ||
" inc a \n" | ||
" movx @dptr,a \n" | ||
" mov a,r7 \n" | ||
" rl a \n" | ||
" inc a \n" | ||
|
||
";get Ep1Buffer[(soundBufferPlayBackIndex<<1)+1] \n" | ||
" add a,#_Ep1Buffer \n" | ||
" mov dpl,a \n" | ||
" clr a \n" | ||
" addc a,#(_Ep1Buffer >> 8) \n" | ||
" mov dph,a \n" | ||
" movx a,@dptr \n" | ||
|
||
";add 128 for PWM \n" | ||
" mov r7,a \n" | ||
" mov a,#0x80 \n" | ||
" add a,r7 \n" | ||
" mov r7,a \n" | ||
|
||
";load previous PWM \n" | ||
" mov a,_PWM_DATA2 \n" | ||
" add a,#232 \n" | ||
" jnc previousPWMSmall$ \n" | ||
";if previous PWM was 20~25 \n" | ||
";we have chance to update PWM on the falling edge \n" | ||
";and that triggers bug of PWM \n" | ||
";so we just wait after falling in that case \n" | ||
|
||
";previousPWM not Small, just set at beginning \n" | ||
";clear bPWM_IF_END \n" | ||
" orl _PWM_CTRL,#0x10 \n" | ||
";wait for bPWM_IF_END \n" | ||
"waitPWM_IF_END$: \n" | ||
" mov a,_PWM_CTRL \n" | ||
" jnb acc.4,waitPWM_IF_END$ \n" | ||
" mov a,r7 \n" | ||
" mov _PWM_DATA2,a \n" | ||
" sjmp pwmSetFinish$ \n" | ||
|
||
"previousPWMSmall$: \n" | ||
";clear bPWM_IF_END \n" | ||
" orl _PWM_CTRL,#0x10 \n" | ||
";wait for bPWM_IF_END \n" | ||
"waitPWM_IF_END_small$: \n" | ||
" mov a,_PWM_CTRL \n" | ||
" jnb acc.4,waitPWM_IF_END_small$ \n" | ||
" mov a,r7 \n" | ||
" nop\n nop\n nop\n nop\n nop\n " | ||
" nop\n nop\n nop\n nop\n nop\n " | ||
" nop\n nop\n nop\n nop\n nop\n " | ||
" nop\n nop\n nop\n nop\n nop\n " | ||
" nop\n nop\n nop\n nop\n nop\n " | ||
|
||
" mov _PWM_DATA2,a \n" | ||
|
||
"pwmSetFinish$: \n" | ||
|
||
"skipTimer2INTR$: \n"); | ||
} | ||
|
||
void USBInit() { | ||
USBDeviceCfg(); // Device mode configuration | ||
USBDeviceEndPointCfg(); // Endpoint configuration | ||
USBDeviceIntCfg(); // Interrupt configuration | ||
UEP0_T_LEN = 0; | ||
UEP1_T_LEN = 0; // Pre-use send length must be cleared | ||
|
||
for (uint8_t i = 0; i < 48; i++) { | ||
Ep1Buffer[i] = 0; | ||
} | ||
|
||
T2CON = 0x00; | ||
// bTMR_CLK may be set by uart0, we keep it as is. | ||
T2MOD |= bTMR_CLK | bT2_CLK; // use Fsys for T2 | ||
|
||
TL2 = 0; | ||
TH2 = 0; | ||
RCAP2L = T2_RELOAD_VALUE_LOW; | ||
RCAP2H = T2_RELOAD_VALUE_HIGH; | ||
|
||
ET2 = 1; | ||
TR2 = 1; | ||
} | ||
|
||
void AUDIO_EP1_Out(void) { | ||
|
||
// Force T2 interrupt to sync with the data received | ||
TR2 = 0; | ||
TF2 = 0; | ||
// the last data will be played back during the new data is being received | ||
// just make sure the last data is played back before the new last data is | ||
// received | ||
TL2 = T2_RELOAD_VALUE_NEAR_FINISH_LOW; | ||
TH2 = T2_RELOAD_VALUE_NEAR_FINISH_HIGH; | ||
soundBufferPlayBackIndex = 0; | ||
TR2 = 1; | ||
|
||
UEP1_CTRL = UEP1_CTRL & ~MASK_UEP_T_RES | UEP_T_RES_TOUT; | ||
} |
23 changes: 23 additions & 0 deletions
23
...ibraries/Generic_Examples/examples/05.USB/SoundCard/src/USBAudioSpeaker/USBAudioSpeaker.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#ifndef __USB_AUDIO_SPEAKER_H__ | ||
#define __USB_AUDIO_SPEAKER_H__ | ||
|
||
// clang-format off | ||
#include <stdint.h> | ||
#include "include/ch5xx.h" | ||
#include "include/ch5xx_usb.h" | ||
#include "USBhandler.h" | ||
// clang-format on | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
void USBInit(void); | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
#endif | ||
|
||
void AUDIO_EP1_Out(void); | ||
|
||
#endif |
Oops, something went wrong.