Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added PWM functionality as an output target #430

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib_xua/api/xua_audiohub.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ void XUA_AudioHub(chanend ?c_aud,
#if (XUA_NUM_PDM_MICS > 0 || defined(__DOXYGEN__))
, chanend c_pdm_in
#endif
#if (XUA_PWM_CHANNELS > 0) || defined(__DOXYGEN__)
, chanend c_pwm_channels
#endif
);

void SpdifTxWrapper(chanend c_spdif_tx);
Expand Down
30 changes: 30 additions & 0 deletions lib_xua/api/xua_conf_default.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
#define SPDIF_TX_TILE AUDIO_IO_TILE
#endif

/**
* @brief Location (tile) of SPDIF Tx. Default: XUD_TILE
*/
#ifndef PWM_CHANNELS_TILE
#define PWM_CHANNELS_TILE XUD_TILE
#endif

/**
* @brief Location (tile) of PDM Rx. Default: AUDIO_IO_TILE
*/
Expand Down Expand Up @@ -86,6 +93,27 @@
#define XUA_NUM_PDM_MICS (0)
#endif

/**
* @brief Number of PWM output channels in the design. Must be 2 or 0.
*
* Default: 0
*/
#ifndef XUA_NUM_PWM_CHANNELS
#define XUA_NUM_PWM_CHANNELS (0)
#endif
#if (XUA_NUM_PWM_CHANNELS != 0 && XUA_NUM_PWM_CHANNELS != 2)
#error "Only none or two PWM channels supported at present"
#endif

/**
* @brief Defines which output channels (stereo) should be output on PWM. Note, Output channels indexed from 0.
*
* Default: 0 (i.e. channels 0 & 1)
* */
#ifndef PWM_CHANNELS_INDEX
#define PWM_CHANNELS_INDEX (0)
#endif

/**
* @brief Number of DSD output channels.
*
Expand Down Expand Up @@ -125,6 +153,8 @@
#define I2S_WIRES_ADC (I2S_CHANS_ADC / I2S_CHANS_PER_FRAME)
#endif

#define XUA_I2S_EN ((I2S_WIRES_ADC) > 0 || (I2S_WIRES_DAC) > 0)

/*
* Defines relating to the interface to external audio hardware i.e. DAC/ADC
*/
Expand Down
24 changes: 22 additions & 2 deletions lib_xua/src/core/audiohub/xua_audiohub.xc
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3

#pragma unsafe arrays
unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
#if (XUA_PWM_CHANNELS > 0)
, chanend c_pwm_channels
#endif
#if (XUA_ADAT_TX_EN)
, chanend c_adat_out
, unsigned adatSmuxMode
Expand Down Expand Up @@ -411,6 +414,10 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward samples to S/PDIF Tx thread */
outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX + 1]);
#endif
#if (XUA_PWM_CHANNELS > 0) && (NUM_USB_CHAN_OUT > 0)
outuint(c_pwm_channels, samplesOut[PWM_CHANNELS_INDEX]); /* Forward samples to PWM generator threads */
outuint(c_pwm_channels, samplesOut[PWM_CHANNELS_INDEX + 1]);
#endif

#if (XUA_NUM_PDM_MICS > 0)
if ((AUD_TO_MICS_RATIO - 1) == audioToMicsRatioCounter)
Expand Down Expand Up @@ -651,6 +658,9 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
#if (XUA_NUM_PDM_MICS > 0)
, chanend c_pdm_in
#endif
#if (XUA_PWM_CHANNELS > 0) || defined(__DOXYGEN__)
, chanend c_pwm_channels
#endif
)
{
#if (XUA_ADAT_TX_EN)
Expand All @@ -670,7 +680,6 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
/* Note, marked unsafe since other cores may be using this mclk port */
configure_clock_src(clk_audio_mclk, p_mclk_in);


#if (DSD_CHANS_DAC > 0)
/* Make sure the DSD ports are on and buffered - just in case they are not shared with I2S */
EnableBufferedPort(p_dsd_clk, 32);
Expand Down Expand Up @@ -782,7 +791,8 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
p_bclk,
#endif
#endif
p_mclk_in, clk_audio_bclk, divide, curSamFreq);
p_mclk_in,
clk_audio_bclk, divide, curSamFreq);
}

{
Expand Down Expand Up @@ -859,6 +869,13 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
outuint(c_spdif_out, mClk);
#endif

#if (XUA_PWM_CHANNELS > 0)
/* Communicate master clock and sample freq to PWM thread */
// TODO outct(c_pwm_channels, XS1_CT_END);
// TODO outuint(c_pwm_channels, curSamFreq);
// TODO outuint(c_pwm_channels, mClk);
#endif

#if (XUA_NUM_PDM_MICS > 0)
/* Send decimation factor to PDM task(s) */
c_pdm_in <: curSamFreq / AUD_TO_MICS_RATIO;
Expand All @@ -884,6 +901,9 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
#else
, null
#endif
#if (XUA_PWM_CHANNELS > 0)
, c_pwm_channels
#endif
#if (XUA_ADAT_TX_EN)
, c_adat_out
, adatSmuxMode
Expand Down
51 changes: 50 additions & 1 deletion lib_xua/src/core/main.xc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <platform.h>
#include <xs1.h>
#include <xclib.h>
#include <stdio.h>
#include <print.h>
#ifdef XSCOPE
#include <xscope.h>
Expand All @@ -34,6 +35,10 @@
#include "spdif.h" /* From lib_spdif */
#endif

#if (XUA_PWM_CHANNELS > 0)
#include "pwm_thread.h"
#endif

#if (XUA_ADAT_RX_EN)
#include "adat_rx.h"
#endif
Expand Down Expand Up @@ -110,6 +115,7 @@ on tile[AUDIO_IO_TILE] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] =
#define p_i2s_adc null
#endif

#if XUA_I2S_EN

#if CODEC_MASTER
on tile[AUDIO_IO_TILE] : buffered in port:32 p_lrclk = PORT_I2S_LRCLK;
Expand All @@ -118,7 +124,10 @@ on tile[AUDIO_IO_TILE] : buffered in port:32 p_bclk = PORT_I2S_BCLK;
on tile[AUDIO_IO_TILE] : buffered out port:32 p_lrclk = PORT_I2S_LRCLK;
on tile[AUDIO_IO_TILE] : buffered out port:32 p_bclk = PORT_I2S_BCLK;
#endif

#else
#define p_lrclk null
#define p_bclk null
#endif
on tile[AUDIO_IO_TILE] : in port p_mclk_in = PORT_MCLK_IN;

#if XUA_USB_EN
Expand Down Expand Up @@ -166,6 +175,10 @@ on tile[MIDI_TILE] : buffered in port:1 p_midi_rx = PORT_MIDI_IN;
clock clk_pdm = on tile[PDM_TILE]: XS1_CLKBLK_1;
#endif

#if (XUA_PWM_CHANNELS > 0)
clock clk_pwm_channels = on tile[PWM_CHANNELS_TILE]: CLKBLK_PWM;
#endif

#ifdef MIDI
on tile[MIDI_TILE] : clock clk_midi = CLKBLK_MIDI;
#endif
Expand Down Expand Up @@ -296,6 +309,9 @@ void usb_audio_io(chanend ?c_aud_in,
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
chanend c_spdif_tx,
#endif
#if (XUA_PWM_CHANNELS > 0)
chanend c_pwm_channels,
#endif
#if (MIXER)
chanend c_mix_ctl,
#endif
Expand Down Expand Up @@ -344,6 +360,10 @@ void usb_audio_io(chanend ?c_aud_in,
xua_pdm_mic_config(p_mclk_in, p_pdm_clk, p_pdm_mics, clk_pdm);
#endif

#if (XUA_PWM_CHANNELS > 0) && (PWM_CHANNELS_TILE == AUDIO_IO_TILE)
pwm_init(p_mclk_in);
#endif

#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE == AUDIO_IO_TILE)
chan c_spdif_tx;

Expand Down Expand Up @@ -391,6 +411,9 @@ void usb_audio_io(chanend ?c_aud_in,
#endif
#if (XUA_NUM_PDM_MICS > 0)
, c_pdm_pcm
#endif
#if (XUA_PWM_CHANNELS > 0)
, c_pwm_channels
#endif
);
}
Expand Down Expand Up @@ -471,6 +494,10 @@ int main()
chan c_spdif_tx;
#endif

#if (XUA_PWM_CHANNELS > 0)
chan c_pwm_channels;
#endif

#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
chan c_clk_ctl;
chan c_clk_int;
Expand Down Expand Up @@ -560,6 +587,10 @@ int main()

/* Attach mclk count port to mclk clock-block (for feedback) */
//set_port_clock(p_for_mclk_count, clk_audio_mclk);
#if (XUA_PWM_CHANNELS > 0) && (PWM_CHANNELS_TILE != AUDIO_IO_TILE)
pwm_init(p_mclk_in);
#endif

#if(AUDIO_IO_TILE != XUD_TILE)
set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb);
set_port_clock(p_for_mclk_count, clk_audio_mclk_usb);
Expand Down Expand Up @@ -627,6 +658,9 @@ int main()
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
, c_spdif_tx
#endif
#if (XUA_PWM_CHANNELS > 0)
, c_pwm_channels
#endif
#if (MIXER)
, c_mix_ctl
#endif
Expand Down Expand Up @@ -658,6 +692,21 @@ int main()
}
#endif

#if (XUA_PWM_CHANNELS > 0)
on tile[PWM_CHANNELS_TILE]:
{
thread_speed();
timer tmr;
int tt;
tmr :> tt;
// Nasty - wait for clock block to be inited
// Ideally, this happens before the PAR.
// But it is inside the IO thread
tmr when timerafter(tt + 1000000) :> void;
pwm_thread(c_pwm_channels);
}
#endif

#if defined(MIDI) && defined(IAP) && (IAP_TILE == MIDI_TILE)
/* MIDI and IAP share a core */
on tile[IAP_TILE]:
Expand Down
41 changes: 41 additions & 0 deletions lib_xua/src/core/pwm_thread.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @file pwm_thread.c
* @brief Fork the threads to run a PWM engine
* @author Henk Muller, XMOS Semiconductor Ltd
*/
#include "xua_conf_default.h" // Settings
#if (XUA_PWM_CHANNELS > 0)
#include <platform.h>
#include <xcore/port.h>
#include <xcore/chanend.h>
#include <xcore/clock.h>
#include "software_dac_hp.h"
#include "uac_hwresources.h"

void setup_master_clock(port_t clk_in) __attribute__ ((weak));
void setup_master_clock(port_t clk_in) {
}

void pwm_init(port_t clk_in) {
xclock_t clk = CLKBLK_PWM;
setup_master_clock(clk_in);
port_set_invert(clk_in);
clock_enable(clk);
clock_set_source_port(clk, clk_in);
}

void pwm_thread(chanend_t c_data)
{
software_dac_hp_t sd;
xclock_t clk = CLKBLK_PWM;
port_t ports[2] = {PORT_PWM_OUT_LEFT, PORT_PWM_OUT_RIGHT};
port_t clk_out = PORT_PWM_CLK_OUT;

software_dac_hp_init(&sd, ports, clk, clk_out, 8);

software_dac_hp(&sd, c_data);
}
#endif



20 changes: 20 additions & 0 deletions lib_xua/src/core/pwm_thread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __pwm_thread__h_
#define __pwm_thread__h_

#include "xua_conf_default.h" // Settings

#if (XUA_PWM_CHANNELS > 0)
#ifdef __XC__
void pwm_init(in port clk_in);
void pwm_thread(chanend c_data);
#else
#include <xcore/chanend.h>
void pwm_init(port_t clk_in);
void pwm_thread(chanend_t c_data);
#endif
#endif

#endif



1 change: 1 addition & 0 deletions lib_xua/src/core/uac_hwresources.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
#define CLKBLK_FLASHLIB XS1_CLKBLK_3 /* Clock block for use by flash lib */
#define CLKBLK_ADAT_RX XS1_CLKBLK_REF /* Use REF for ADAT_RX on x200/AI series */
#define CLKBLK_I2S_BIT XS1_CLKBLK_3
#define CLKBLK_PWM XS1_CLKBLK_1

#endif /* _UAC_HWRESOURCES_H_ */