Browse Source

fix i2s channels

Signed-off-by: surenyi <surenyi82@qq.com>
bfsk
surenyi 3 years ago
parent
commit
b77eda163c
  1. 3
      include/edma.h
  2. 3
      include/spi.h
  3. 3
      platforms/dsk/platform_dsk.c
  4. 4
      platforms/dsk/tlv320aic23.c
  5. 2
      src/bfsk/tone.c
  6. 2
      src/console.c
  7. 163
      src/edma.c
  8. 12
      src/platform.c
  9. 4
      src/platform_internal.h
  10. 318
      src/spi.c

3
include/edma.h

@ -5,8 +5,9 @@ extern "C" {
#endif
int edma_set_irq(int vect_id);
int edma_attach_tcc_irq(int tccNum, void (*func)(int tccNum));
int edma_attach_tcc_irq(int tccNum, void (*func)(int tccNum, void *arg), void *arg);
int edma_dettach_tcc_irq(int tccNum);
int edma_copy(void *to, const void *from, int len);
#ifdef __cplusplus
}

3
include/spi.h

@ -16,7 +16,8 @@ int spi_open(int dev_id, int mode, int freq, int bits);
int spi_write(int dev_id, const void *buf, int len);
int spi_read(int dev_id, void *buf, int len);
int spi_edma_write(int dev_id, const void *buf, int len, void (*notify)(void *args), void *args);
int spi_edma_write(int dev_id, const void *buf, int len, void (*on_complete)(void *args), void *args);
int spi_edma_read(int dev_id, void *buf, int len, void (*on_complete)(void *args), void *args);
void spi_close(int dev_id);

3
platforms/dsk/platform_dsk.c

@ -73,6 +73,9 @@ void platform_pre_init()
void platform_post_init()
{
CACHE_setL2Mode(CACHE_32KCACHE);
edma_set_irq(8);
led_off(0);
led_off(1);
led_off(2);

4
platforms/dsk/tlv320aic23.c

@ -26,8 +26,8 @@ void aic23_init()
Uint16 aic23[] = {
0x0, 0x17,
0x1, 0x17,
0x2, 0xff,
0x3, 0xf9,
0x2, 0xfb,
0x3, 0xfb,
0x4, 0x133,
0x5, 0x06,
0x6, 0x0,

2
src/bfsk/tone.c

@ -160,7 +160,7 @@ void tone_generate(simpleaudio *sa_out, float tone_freq, size_t nsamples_dur)
}
assert ( simpleaudio_write(sa_out, buf, nsamples_dur * sa_out->channels) > 0 );
assert (simpleaudio_write(sa_out, buf, nsamples_dur) > 0 );
free(buf);
}

2
src/console.c

@ -8,7 +8,7 @@ simpleaudio *sa = NULL;
int console_init()
{
tone_init(4096, 1.0);
tone_init(4096, 0.4);
sa = simpleaudio_open_stream(SA_BACKEND_SYSDEFAULT, "mcbsp:2",
SA_STREAM_PLAYBACK,

163
src/edma.c

@ -1,15 +1,81 @@
#include <string.h>
#include <stdlib.h>
#include "platform_internal.h"
struct edma_descr {
int in_use;
void (*handler)(int tcc, void *arg);
void *data;
};
#define EDMA_CHANNEL_MAX (_EDMA_CHA_CNT)
static struct edma_descr *__edma_descr[EDMA_CHANNEL_MAX];
void edma_lowlevel_init()
{
memset(__edma_descr, 0, sizeof __edma_descr);
}
void edma_lowlevel_close()
{
int i;
struct edma_descr *edptr;
irq_dettach(IRQ_EVT_EDMAINT, EDMA_intDispatcher, NULL);
for (i = 0; i < EDMA_CHANNEL_MAX; ++i) {
edptr = __edma_descr[i];
if (edptr) {
if (edptr->in_use)
EDMA_intDisable(i);
free(edptr);
__edma_descr[i] = NULL;
}
}
}
int edma_set_irq(int vect_id)
{
return irq_attach(vect_id, IRQ_EVT_EDMAINT, EDMA_intDispatcher, NULL);
}
int edma_attach_tcc_irq(int tccNum, void (*func)(int tccNum))
static void __edma_int_handler(int tccNum)
{
EDMA_reset(IRQ_EVT_EDMAINT);
struct edma_descr *edptr = __edma_descr[tccNum];
EDMA_intClear(tccNum);
if (edptr && edptr->in_use && edptr->handler) {
edptr->handler(tccNum, edptr->data);
}
}
int edma_attach_tcc_irq(int tccNum, void (*func)(int tccNum, void *arg), void *arg)
{
struct edma_descr *edptr;
if (tccNum < 0 || tccNum >= EDMA_CHANNEL_MAX) {
return -1;
}
edptr = __edma_descr[tccNum];
if (!edptr) {
edptr = calloc(1, sizeof *edptr);
if (edptr == NULL) {
return -2;
}
__edma_descr[tccNum] = edptr;
}
if (edptr->in_use) {
return -2;
}
edptr->handler = func;
edptr->data = arg;
edptr->in_use = 1;
EDMA_intDisable(tccNum);
EDMA_intHook(tccNum, func);
EDMA_intAlloc(tccNum);
EDMA_intHook(tccNum, __edma_int_handler);
EDMA_intClear(tccNum);
EDMA_intEnable(tccNum);
return 0;
@ -17,8 +83,99 @@ int edma_attach_tcc_irq(int tccNum, void (*func)(int tccNum))
int edma_dettach_tcc_irq(int tccNum)
{
struct edma_descr *edptr;
if (tccNum < 0 || tccNum >= EDMA_CHANNEL_MAX) {
return -1;
}
edptr = __edma_descr[tccNum];
if (edptr)
edptr->in_use = 0;
EDMA_intDisable(tccNum);
EDMA_intFree(tccNum);
EDMA_intHook(tccNum, EDMA_intDefaultHandler);
return 0;
}
static void __copy_done(int tccNum, void *arg)
{
int *done = arg;
*done = 1;
}
int edma_copy(void *to, const void *from, int len)
{
Uint32 esize;
EDMA_Config edma_conf;
int slen = len;
int tcc;
EDMA_Handle handle;
volatile int done = 0;
if ((len & 0x3) == 0) {
esize = EDMA_OPT_ESIZE_32BIT;
len /= 4;
} else {
if ((len & 0x1) == 0) {
esize = EDMA_OPT_ESIZE_16BIT;
len /= 2;
} else {
esize = EDMA_OPT_ESIZE_8BIT;
}
}
handle = EDMA_open(EDMA_CHA_ANY, EDMA_OPEN_RESET);
if (handle == EDMA_HINV) {
return -1;
}
tcc = EDMA_intAlloc(-1);
if (tcc < 0) {
EDMA_close(handle);
return -2;
}
edma_conf.opt = EDMA_OPT_RMK(
EDMA_OPT_PRI_MEDIUM,
esize,
EDMA_OPT_2DS_NO,
EDMA_OPT_SUM_INC,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_INC,
EDMA_OPT_TCINT_YES,
EDMA_OPT_TCC_OF(tcc),
EDMA_OPT_TCCM_OF(tcc >> 4),
EDMA_OPT_ATCINT_NO,
EDMA_OPT_ATCC_OF(0),
EDMA_OPT_PDTS_DEFAULT,
EDMA_OPT_PDTS_DEFAULT,
EDMA_OPT_LINK_NO,
EDMA_OPT_FS_NO);
edma_conf.src = EDMA_SRC_RMK((Uint32)from);
edma_conf.cnt = EDMA_CNT_RMK(0, len);
edma_conf.dst = EDMA_DST_RMK((Uint32)(to));
edma_conf.idx = EDMA_IDX_RMK(0, 0);
edma_conf.rld = EDMA_RLD_RMK(0, 0);
edma_attach_tcc_irq(tcc, __copy_done, (void *)&done);
EDMA_config(handle, &edma_conf);
// EDMA_enableChannel(handle);
EDMA_setChannel(handle);
while (done == 0)
;
EDMA_disableChannel(handle);
edma_dettach_tcc_irq(tcc);
EDMA_close(handle);
return (slen);
}

12
src/platform.c

@ -8,8 +8,10 @@ int platform_init()
spi_lowlevel_init();
timer_lowlevel_init();
/* clear edma PaRam */
EDMA_clearPram(0x00000000);
edma_lowlevel_init();
/* clear edma PaRam */
platform_pre_init();
IRQ_setVecs(vectors);
@ -18,12 +20,20 @@ int platform_init()
IRQ_nmiEnable();
IRQ_globalEnable();
EDMA_reset(IRQ_EVT_EDMAINT);
platform_post_init();
return 0;
}
void platform_close()
{
IRQ_globalDisable();
edma_lowlevel_close();
}
Uint8 read_reg8(Uint32 addr)
{
return *(volatile Uint8 *)(addr);

4
src/platform_internal.h

@ -10,8 +10,12 @@ void tick_close();
void irq_lowlevel_init();
void spi_lowlevel_init();
void spi_lowlevel_init();
void edma_lowlevel_init();
void timer_lowlevel_init();
int timer_event_id(int dev_id);
void edma_lowlevel_close();
#endif

318
src/spi.c

@ -1,63 +1,70 @@
/* vim: set fdm=marker sw=4 ts=4 nu: */
#include <string.h>
#include <stdlib.h>
#include "platform_internal.h"
#include "spi.h"
#define TXBUF_SIZE (1024)
#define RXBUF_SIZE (1024)
typedef struct __spi_handle *spi_t;
/* {{{: struct __spi_handle {...} */
struct __spi_handle {
MCBSP_Handle spi;
int bits;
int is_i2s;
/* tx */
EDMA_Handle xh;
void (*xnotify)(void *args);
void *xargs;
char xbuf[TXBUF_SIZE];
/* rx */
EDMA_Handle rh;
void (*rnotify)(void *args);
void *rargs;
char rbuf[RXBUF_SIZE];
};
static struct __spi_handle __spi_devs[_MCBSP_PORT_CNT];
/* }}} */
void spi_lowlevel_init()
{
memset(__spi_devs, 0, sizeof __spi_devs);
}
static spi_t __find_spi_with_xtcc(int tccNum)
/* {{{: interrupt handler */
static void __tx_notify(int tccNum, void *arg)
{
int i;
spi_t spi;
for (i = 0; i < _MCBSP_PORT_CNT; ++i) {
spi = &__spi_devs[i];
if (MCBSP_getXmtEventId(spi->spi) == tccNum) {
return spi;
spi_t spi = arg;
void (*handler)(void *);
if (spi) {
EDMA_disableChannel(spi->xh);
handler = spi->xnotify;
if (handler) {
spi->xnotify = NULL;
handler(spi->xargs);
edma_dettach_tcc_irq(tccNum);
}
}
return NULL;
}
static void __tx_notify(int tccNum)
static void __rx_notify(int tccNum, void *arg)
{
spi_t spi;
spi_t spi = arg;
void (*handler)(void *);
EDMA_intClear(tccNum);
spi = __find_spi_with_xtcc(tccNum);
if (spi) {
EDMA_disableChannel(spi->xh);
if (spi->xnotify)
spi->xnotify(spi->xargs);
EDMA_disableChannel(spi->rh);
handler = spi->rnotify;
if (handler) {
spi->rnotify = NULL;
handler(spi->rargs);
edma_dettach_tcc_irq(tccNum);
}
}
}
/* }}} */
/* {{{: i2s_slave_open(...) */
static Uint32 __parse_to_dlen1(int bits)
{
Uint32 dlen1;
@ -104,6 +111,8 @@ int i2s_slave_open(int dev_id, int bits)
return -1; /* busy ? */
}
spi->is_i2s = 1;
if ((int)(dlen1 = __parse_to_dlen1(bits)) < 0) {
return -3;
}
@ -146,7 +155,7 @@ int i2s_slave_open(int dev_id, int bits)
MCBSP_RCR_RCOMPAND_MSB, // Transmit companding mode(XCOMPAND)
MCBSP_RCR_RFIG_YES, // Transmit frame ignore(XFIG)
MCBSP_RCR_RDATDLY_1BIT, // Transmit data delay(XDATDLY)
MCBSP_RCR_RFRLEN1_OF(0), // Transmit frame length
MCBSP_RCR_RFRLEN1_OF(1), // Transmit frame length
// in phase 1(XFRLEN1)
dlen1, // Transmit element length
// in phase 1(XWDLEN1)
@ -163,7 +172,7 @@ int i2s_slave_open(int dev_id, int bits)
MCBSP_XCR_XCOMPAND_MSB, // Transmit companding mode(XCOMPAND)
MCBSP_XCR_XFIG_NO, // Transmit frame ignore(XFIG)
MCBSP_XCR_XDATDLY_1BIT, // Transmit data delay(XDATDLY)
MCBSP_XCR_XFRLEN1_OF(0), // Transmit frame length
MCBSP_XCR_XFRLEN1_OF(1), // Transmit frame length
// in phase 1(XFRLEN1)
dlen1, // Transmit element length
// in phase 1(XWDLEN1)
@ -206,7 +215,9 @@ int i2s_slave_open(int dev_id, int bits)
MCBSP_SRGR_DEFAULT_DELAY);
return 0;
}
/* }}} */
/* {{{: spi_open(int dev_id, int mode, int freq, int bits) */
int spi_open(int dev_id, int mode, int freq, int bits)
{
MCBSP_Config mbconf;
@ -224,6 +235,9 @@ int spi_open(int dev_id, int mode, int freq, int bits)
if (spi->spi) {
return -1; /* busy ? */
}
spi->is_i2s = 0;
if ((int)(dlen1 = __parse_to_dlen1(bits)) < 0) {
return -3;
}
@ -355,45 +369,9 @@ int spi_open(int dev_id, int mode, int freq, int bits)
spi->spi = handle;
return 0;
}
/* }}} */
static int __write_u8(spi_t spi, const Uint8 *buf, int len)
{
int i;
for (i = 0; i < len; ++i) {
while (!MCBSP_xrdy(spi->spi))
;
MCBSP_write(spi->spi, buf[i]);
}
return (len);
}
static int __write_u16(spi_t spi, const Uint16 *buf, int len)
{
int i;
len >>= 1;
for (i = 0; i < len; ++i) {
while (!MCBSP_xrdy(spi->spi))
;
MCBSP_write(spi->spi, buf[i]);
}
return (len);
}
static int __write_u32(spi_t spi, const Uint32 *buf, int len)
{
int i;
len >>= 2;
for (i = 0; i < len; ++i) {
while (!MCBSP_xrdy(spi->spi))
;
MCBSP_write(spi->spi, buf[i]);
}
return (len);
}
/* {{{: int spi_write(int dev_id, const void *buf, int len) */
static spi_t __get_active_device(int dev_id)
{
spi_t spi;
@ -406,11 +384,12 @@ static spi_t __get_active_device(int dev_id)
return spi->spi ? spi : NULL;
}
int spi_write(int dev_id, const void *buf, int len)
int spi_write(int dev_id, const void *buf, int _len)
{
const Uint8 *u8;
const Uint16 *u16;
const Uint32 *u32;
int i, len = _len;
spi_t spi;
if ((spi = __get_active_device(dev_id)) == NULL) {
@ -422,65 +401,62 @@ int spi_write(int dev_id, const void *buf, int len)
switch (spi->bits) {
case 8:
u8 = buf;
__write_u8(spi, u8, len);
for (i = 0; i < len; ++i) {
while (!MCBSP_xrdy(spi->spi))
;
MCBSP_write(spi->spi, u8[i]);
}
break;
case 12:
case 16:
len >>= 1;
u16 = buf;
__write_u16(spi, u16, len);
for (i = 0; i < len; ++i) {
while (!MCBSP_xrdy(spi->spi))
;
MCBSP_write(spi->spi, u16[i]);
}
break;
case 20:
case 24:
case 32:
len >>= 2;
u32 = buf;
__write_u32(spi, u32, len);
for (i = 0; i < len; ++i) {
while (!MCBSP_xrdy(spi->spi))
;
MCBSP_write(spi->spi, u32[i]);
}
break;
default:
return (-1);
}
return (len);
return (_len);
}
/* }}} */
int spi_edma_write(int dev_id, const void *buf, int len, void (*notify)(void *args), void *args)
static int __do_spi_edma_write(spi_t spi, int bits, const void *buf, int len, void (*notify)(void *args), void *args)
{
spi_t spi;
Uint32 esize;
EDMA_Config edma_conf;
int slen, xevent;
static EDMA_Config edma_conf;
int frmlen = 0, xevent, slen = len;
if ((spi = __get_active_device(dev_id)) == NULL) {
return -2;
}
spi = &__spi_devs[dev_id];
if (len > TXBUF_SIZE) {
len = TXBUF_SIZE;
}
slen = len;
memcpy(spi->xbuf, buf, len);
switch (spi->bits) {
switch (bits) {
case 8:
esize = EDMA_OPT_ESIZE_8BIT;
break;
case 12:
case 16:
esize = EDMA_OPT_ESIZE_16BIT;
len /= 2;
len >>= 1;
break;
case 20:
case 24:
case 32:
esize = EDMA_OPT_ESIZE_32BIT;
len /= 4;
len >>= 2;
break;
default:
return (-2);
}
CACHE_wbL2(spi->xbuf, len, CACHE_WAIT);
xevent = MCBSP_getXmtEventId(spi->spi);
edma_conf.opt = EDMA_OPT_RMK(
@ -492,7 +468,7 @@ int spi_edma_write(int dev_id, const void *buf, int len, void (*notify)(void *ar
EDMA_OPT_DUM_NONE,
EDMA_OPT_TCINT_YES,
EDMA_OPT_TCC_OF(xevent),
EDMA_OPT_TCCM_OF(xevent >> 4),
EDMA_OPT_TCCM_OF((xevent >> 4)),
EDMA_OPT_ATCINT_NO,
EDMA_OPT_ATCC_OF(0),
EDMA_OPT_PDTS_DEFAULT,
@ -500,11 +476,22 @@ int spi_edma_write(int dev_id, const void *buf, int len, void (*notify)(void *ar
EDMA_OPT_LINK_NO,
EDMA_OPT_FS_NO
);
edma_conf.src = EDMA_SRC_RMK((Uint32)(spi->xbuf));
edma_conf.cnt = EDMA_CNT_RMK(0, len);
if (len > 65535) {
frmlen = len / 65535 - 1;
if (frmlen > 65535)
frmlen = 65535;
len = 65535;
slen = (frmlen + 1) * 65535 * (bits / 8);
}
edma_conf.src = EDMA_SRC_RMK((Uint32)(buf));
edma_conf.cnt = EDMA_CNT_RMK(frmlen, len);
edma_conf.dst = EDMA_DST_OF(MCBSP_getXmtAddr(spi->spi));
edma_conf.idx = EDMA_IDX_RMK(0, 0);
edma_conf.rld = EDMA_RLD_RMK(0, 0);
edma_conf.rld = EDMA_RLD_RMK(len, 0);
spi->xnotify = notify;
spi->xargs = args;
@ -512,58 +499,38 @@ int spi_edma_write(int dev_id, const void *buf, int len, void (*notify)(void *ar
if (spi->xh == NULL)
spi->xh = EDMA_open(xevent, 0);
edma_attach_tcc_irq(xevent, __tx_notify);
EDMA_config(spi->xh, &edma_conf);
edma_attach_tcc_irq(xevent, __tx_notify, spi);
EDMA_enableChannel(spi->xh);
return (slen);
}
static int __read_u8(spi_t spi, Uint8 *buf, int len)
{
int i;
for (i = 0; i < len; ++i) {
while (!MCBSP_rrdy(spi->spi))
;
buf[i] = MCBSP_read(spi->spi);
}
return (len);
}
static int __read_u16(spi_t spi, Uint16 *buf, int len)
int spi_edma_write(int dev_id, const void *buf, int len, void (*notify)(void *args), void *args)
{
int i;
spi_t spi;
int bits;
len >>= 1;
for (i = 0; i < len; ++i) {
while (!MCBSP_rrdy(spi->spi))
;
buf[i] = MCBSP_read(spi->spi);
if ((spi = __get_active_device(dev_id)) == NULL) {
return -2;
}
return (len);
}
static int __read_u32(spi_t spi, Uint32 *buf, int len)
{
int i;
spi = &__spi_devs[dev_id];
len >>= 2;
for (i = 0; i < len; ++i) {
while (!MCBSP_rrdy(spi->spi))
;
buf[i] = MCBSP_read(spi->spi);
}
return (len);
bits = spi->bits; /* i2s: 2 channels ? */
return __do_spi_edma_write(spi, bits, buf, len, notify, args);
}
int spi_read(int dev_id, void *buf, int len)
/* {{{: int spi_read(int dev_id, void *buf, int _len) */
int spi_read(int dev_id, void *buf, int _len)
{
Uint8 *u8;
Uint16 *u16;
Uint32 *u32;
spi_t spi;
int i, len = _len;
if ((spi = __get_active_device(dev_id)) == NULL) {
return -1;
@ -572,25 +539,113 @@ int spi_read(int dev_id, void *buf, int len)
switch (spi->bits) {
case 8:
u8 = buf;
__read_u8(spi, u8, len);
for (i = 0; i < len; ++i) {
while (!MCBSP_rrdy(spi->spi))
;
u8[i] = MCBSP_read(spi->spi);
}
break;
case 12:
case 16:
len >>= 1;
u16 = buf;
__read_u16(spi, u16, len);
for (i = 0; i < len; ++i) {
while (!MCBSP_rrdy(spi->spi))
;
u16[i] = MCBSP_read(spi->spi);
}
break;
case 20:
case 24:
case 32:
len >>= 2;
u32 = buf;
__read_u32(spi, u32, len);
for (i = 0; i < len; ++i) {
while (!MCBSP_rrdy(spi->spi))
;
u32[i] = MCBSP_read(spi->spi);
}
break;
default:
return (-1);
}
return (len);
return (_len);
}
/* }}} */
int spi_edma_read(int dev_id, void *buf, int len, void (*on_complete)(void *args), void *args)
{
spi_t spi;
Uint32 esize;
EDMA_Config edma_conf;
int xevent, slen = len;
if ((spi = __get_active_device(dev_id)) == NULL) {
return -2;
}
spi = &__spi_devs[dev_id];
switch (spi->bits) {
case 8:
esize = EDMA_OPT_ESIZE_8BIT;
break;
case 12:
case 16:
esize = EDMA_OPT_ESIZE_16BIT;
len /= 2;
break;
case 20:
case 24:
case 32:
esize = EDMA_OPT_ESIZE_32BIT;
len /= 4;
break;
default:
return (-2);
}
xevent = MCBSP_getRcvEventId(spi->spi);
edma_conf.opt = EDMA_OPT_RMK(
EDMA_OPT_PRI_MEDIUM,
esize,
EDMA_OPT_2DS_NO,
EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_INC,
EDMA_OPT_TCINT_YES,
EDMA_OPT_TCC_OF(xevent),
EDMA_OPT_TCCM_OF(xevent >> 4),
EDMA_OPT_ATCINT_NO,
EDMA_OPT_ATCC_OF(0),
EDMA_OPT_PDTS_DEFAULT,
EDMA_OPT_PDTS_DEFAULT,
EDMA_OPT_LINK_NO,
EDMA_OPT_FS_NO);
edma_conf.src = EDMA_SRC_OF(MCBSP_getRcvAddr(spi->spi));
edma_conf.cnt = EDMA_CNT_RMK(0, len);
edma_conf.dst = EDMA_DST_RMK((Uint32)(buf));
edma_conf.idx = EDMA_IDX_RMK(0, 0);
edma_conf.rld = EDMA_RLD_RMK(0, 0);
spi->rnotify = on_complete;
spi->rargs = args;
if (spi->rh == NULL)
spi->rh = EDMA_open(xevent, 0);
edma_attach_tcc_irq(xevent, __rx_notify, spi);
EDMA_config(spi->rh, &edma_conf);
EDMA_enableChannel(spi->rh);
return (slen);
}
/* {{{ void spi_close(int dev_id) */
void spi_close(int dev_id)
{
spi_t spi;
@ -603,4 +658,5 @@ void spi_close(int dev_id)
spi->spi = NULL;
spi->bits = 0;
}
/* }}} */

Loading…
Cancel
Save