Skip to content

Commit

Permalink
A bit more codec stuff.
Browse files Browse the repository at this point in the history
  • Loading branch information
profi200 committed Dec 28, 2019
1 parent 5ebabd0 commit c5884f7
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 15 deletions.
7 changes: 4 additions & 3 deletions include/arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@

#ifdef ARM11

#define __cpsid(flags) __asm__ volatile("cpsid " #flags : : : "memory");
#define __cpsie(flags) __asm__ volatile("cpsie " #flags : : : "memory");
#define __cpsid(flags) __asm__ volatile("cpsid " #flags : : : "memory")
#define __cpsie(flags) __asm__ volatile("cpsie " #flags : : : "memory")
#define __setend(end) __asm__ volatile("setend " #end : : : "memory")

static inline void __wfi(void)
{
Expand Down Expand Up @@ -191,7 +192,7 @@ static inline void __wfi(void)
__asm__ volatile("mcr p15, 0, %0, c7, c0, 4" : : "r" (0) : "memory");
}

#endif // ifdef ARM11, elif ARM9
#endif // ifdef ARM11

static inline u32 __getCpsr(void)
{
Expand Down
14 changes: 12 additions & 2 deletions include/arm11/hardware/codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,23 @@


/**
* @brief Initialize CODEC for Circle-Pad/Touchscreen.
* @brief Initialize CODEC for Circle-Pad/Touchscreen/Sound.
*/
void CODEC_init(void);

/**
* @brief Deinitializes the CODEC chip for sleep or poweroff.
*/
void CODEC_deinit(void);

/**
* @brief The opposite of CODEC_deinit(). Does a partial init.
*/
void CODEC_wakeup(void);

/**
* @brief Get raw ADC data for Circle-Pad/Touchscreen.
*
* @param[in] buf The buffer to write the data to.
*/
void CODEC_getRawData(u32 buf[13]);
void CODEC_getRawAdcData(u32 buf[13]);
145 changes: 136 additions & 9 deletions source/arm11/hardware/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,64 @@
#include "arm11/hardware/gpio.h"


typedef struct
{
u8 driverGainHP;
u8 driverGainSP;
u8 analogVolumeHP;
u8 analogVolumeSP;
s8 shutterVolume[2];
u8 microphoneBias;
u8 quickCharge;
u8 PGA_GAIN; // microphone gain
u8 reserved[3];
s16 filterHP32[15]; // 3 * 5
s16 filterHP47[15];
s16 filterSP32[15];
s16 filterSP47[15];
s16 filterMic32[28]; // (1+2)+((1+4)*5)
s16 filterMic47[28];
s16 filterFree[28];
u8 analogInterval;
u8 analogStabilize;
u8 analogPrecharge;
u8 analogSense;
u8 analogDebounce;
u8 analog_XP_Pullup;
u8 YM_Driver;
u8 reserved2;
} CodecCal;


alignas(4) static CodecCal fallbackCal =
{
0u,
1u,
0u,
7u,
{0xFD, 0xEC},
3u,
2u,
0u,
{0, 0, 0},
{32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 32736, 49168, 0, 16352, 0},
{32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 32745, 49164, 0, 16361, 0},
{32767, 38001, 22413, 30870, 36440, 51536, 30000, 51536, 0, 0, 32736, 49168, 0, 16352, 0},
{32767, 36541, 25277, 31456, 35336, 51134, 30000, 51134, 0, 0, 32745, 49164, 0, 16361, 0},
{32767, 0, 0, 32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0},
{32767, 0, 0, 32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0},
{32767, 0, 0, 52577, 56751, 32767, 8785, 12959, 52577, 56751, 32767, 8785, 12959, 52577, 56751, 32767, 8785, 12959, 32767, 0, 0, 0, 0, 32767, 0, 0, 0, 0},
1u,
9u,
4u,
3u,
0u,
6u,
1u,
0u
};



static void codecSwitchBank(u8 bank)
{
Expand Down Expand Up @@ -83,6 +141,74 @@ static void codecMaskReg(u8 bank, u8 reg, u8 val, u8 mask)
codecWriteReg(bank, reg, data);
}

// Helpers
static void codecSwapCalibrationData(CodecCal *cal)
{
u16 *tmp = (u16*)cal->filterHP32;
for(int i = 0; i < 15; i++)
{
tmp[i] = __builtin_bswap16(tmp[i]);
}

tmp = (u16*)cal->filterHP47;
for(int i = 0; i < 15; i++)
{
tmp[i] = __builtin_bswap16(tmp[i]);
}

tmp = (u16*)cal->filterSP32;
for(int i = 0; i < 15; i++)
{
tmp[i] = __builtin_bswap16(tmp[i]);
}

tmp = (u16*)cal->filterSP47;
for(int i = 0; i < 15; i++)
{
tmp[i] = __builtin_bswap16(tmp[i]);
}

tmp = (u16*)cal->filterMic32;
for(int i = 0; i < 28; i++)
{
tmp[i] = __builtin_bswap16(tmp[i]);
}

tmp = (u16*)cal->filterMic47;
for(int i = 0; i < 28; i++)
{
tmp[i] = __builtin_bswap16(tmp[i]);
}

tmp = (u16*)cal->filterFree;
for(int i = 0; i < 28; i++)
{
tmp[i] = __builtin_bswap16(tmp[i]);
}
}

static void codecMaskWaitReg(u8 bank, u8 reg, u8 val, u8 mask)
{
for(u32 i = 0; i < 64; i++) // Some kind of timeout? No error checking.
{
codecMaskReg(bank, reg, val, mask);
if((codecReadReg(bank, reg) & mask) == val) break;
}
}

static void codecEnableTouchscreen(void)
{
codecMaskReg(0x67, 0x26, 0x80, 0x80);
codecMaskReg(0x67, 0x24, 0, 0x80);
codecMaskReg(0x67, 0x25, 0x10, 0x3C);
}

static void codecDisableTouchscreen(void)
{
codecMaskReg(0x67, 0x26, 0, 0x80);
codecMaskReg(0x67, 0x24, 0x80, 0x80);
}


void CODEC_init(void)
{
Expand All @@ -93,26 +219,27 @@ void CODEC_init(void)

NSPI_init();

// TODO: Load calibration from HWCAL files on eMMC.
CodecCal *const cal = &fallbackCal;
codecSwapCalibrationData(cal); // Come the fuck on. Why is this not stored in the correct endianness?

// Circle pad
codecWriteReg(0x67, 0x24, 0x98);
codecWriteReg(0x67, 0x26, 0x00);
codecWriteReg(0x67, 0x25, 0x43);
codecWriteReg(0x67, 0x24, 0x18);
codecWriteReg(0x67, 0x17, 0x43);
codecWriteReg(0x67, 0x19, 0x69);
codecWriteReg(0x67, 0x1B, 0x80);
codecWriteReg(0x67, 0x27, 0x11);
codecWriteReg(0x67, 0x17, cal->analogPrecharge<<4 | cal->analogSense);
codecWriteReg(0x67, 0x19, cal->analog_XP_Pullup<<4 | cal->analogStabilize);
codecWriteReg(0x67, 0x1B, cal->YM_Driver<<7 | cal->analogDebounce);
codecWriteReg(0x67, 0x27, 0x10u | cal->analogInterval);
codecWriteReg(0x67, 0x26, 0xEC);
codecWriteReg(0x67, 0x24, 0x18);
codecWriteReg(0x67, 0x25, 0x53);

// Touchscreen
codecMaskReg(0x67, 0x26, 0x80, 0x80);
codecMaskReg(0x67, 0x24, 0, 0x80);
codecMaskReg(0x67, 0x25, 0x10, 0x3C);
codecEnableTouchscreen();
}

void CODEC_getRawData(u32 buf[13])
void CODEC_getRawAdcData(u32 buf[13])
{
//codecSwitchBank(0x67);
// This reg read seems useless and doesn't affect funtionality.
Expand Down
2 changes: 1 addition & 1 deletion source/arm11/hardware/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ static void updateMcuIrqState(void)
{
alignas(4) u8 buf[13 * 4];
CODEC_getRawData((u32*)buf);
CODEC_getRawAdcData((u32*)buf);
// Touchscreen
u32 emuButtons = !(buf[0] & 1u<<4)<<20; // KEY_TOUCH
Expand Down

0 comments on commit c5884f7

Please sign in to comment.