M bitsy/devuda1341.c => bitsy/devuda1341.c +38 -19
@@ 642,24 642,6 @@ indisable(void) {
}
}
-void
-audiopower(int flag) {
- if (debug) {
- iprint("audiopower %d\n", flag);
- }
- if (flag) {
- egpiobits(EGPIO_audio_power, 1);
- egpiobits(EGPIO_audio_ic_power | EGPIO_codec_reset, 1);
- } else {
- /* power off */
- if (audio.omode & Aread)
- indisable();
- if (audio.omode & Awrite)
- outdisable();
- egpiobits(EGPIO_audio_ic_power | EGPIO_codec_reset | EGPIO_audio_power, 0);
- }
-}
-
static void
sendaudio(IOstate *s) {
/* interrupt routine calls this too */
@@ 731,6 713,42 @@ recvaudio(IOstate *s) {
iunlock(&s->ilock);
}
+void
+audiopower(int flag) {
+ IOstate *s;
+
+ if (debug) {
+ iprint("audiopower %d\n", flag);
+ }
+ if (flag) {
+ /* power on only when necessary */
+ if (audio.amode) {
+ egpiobits(EGPIO_audio_power | EGPIO_audio_ic_power | EGPIO_codec_reset, 1);
+ enable();
+ if (audio.amode & Aread) {
+ inenable();
+ s = &audio.i;
+ dmareset(s->dma, 1, 0, 4, 2, SSPRecvDMA, Port4SSP);
+ recvaudio(s);
+ }
+ if (audio.amode & Awrite) {
+ outenable();
+ s = &audio.o;
+ dmareset(s->dma, 0, 0, 4, 2, SSPXmitDMA, Port4SSP);
+ sendaudio(s);
+ }
+ mxvolume();
+ }
+ } else {
+ /* power off */
+ if (audio.amode & Aread)
+ indisable();
+ if (audio.amode & Awrite)
+ outdisable();
+ egpiobits(EGPIO_audio_ic_power | EGPIO_codec_reset | EGPIO_audio_power, 0);
+ }
+}
+
static void
audiointr(void *x, ulong ndma) {
IOstate *s = x;
@@ 804,13 822,13 @@ audioopen(Chan *c, int mode)
if (omode & Aread) {
inenable();
s = &audio.i;
- audio.amode |= Aread;
if(s->bufinit == 0)
bufinit(s);
setempty(s);
s->emptying = &s->buf[Nbuf-1];
s->chan = c;
s->dma = dmaalloc(1, 0, 4, 2, SSPRecvDMA, Port4SSP, audiointr, (void*)s);
+ audio.amode |= Aread;
}
if (omode & Awrite) {
outenable();
@@ 821,6 839,7 @@ audioopen(Chan *c, int mode)
setempty(s);
s->chan = c;
s->dma = dmaalloc(0, 0, 4, 2, SSPXmitDMA, Port4SSP, audiointr, (void*)s);
+ audio.amode |= Awrite;
}
resetlevel();
mxvolume();
M bitsy/fns.h => bitsy/fns.h +1 -1
@@ 23,7 23,7 @@ char* getconf(char*);
ulong getfar(void);
ulong getfsr(void);
#define getpgcolor(a) 0
-void gpiointrenable(ulong, int, void (*)(Ureg*, void*), void*, char*)
+void gpiointrenable(ulong, int, void (*)(Ureg*, void*), void*, char*);
void h3650uartsetup(void);
void icacheinvalidate(void);
void idle(void);
M bitsy/power.c => bitsy/power.c +24 -21
@@ 10,8 10,6 @@
/* Power management for the bitsy */
-int powerup;
-
enum {
pmcr_sf = 0,
@@ 21,32 19,35 @@ enum {
pcfr_fo = 3,
};
+jmp_buf power_resume;
+
static void
onoffintr(Ureg*, void *x)
{
/* On/off button interrupt */
int i;
- if (powerup) {
- /* Power back up */
- powerup = 0;
- exit(0);
- } else {
- /* Power down */
-
- /* debounce, 50 ms*/
- for (i = 0; i < 50; i++) {
- delay(1);
- if ((gpioregs->level & GPIO_PWR_ON_i) == 0)
- return; /* bounced */
- }
- powerup = 1;
- irpower(0);
- audiopower(0);
- lcdpower(0);
- rs232power(0);
- sa1100_power_off();
+ /* debounce, 50 ms*/
+ for (i = 0; i < 50; i++) {
+ delay(1);
+ if ((gpioregs->level & GPIO_PWR_ON_i) == 0)
+ return; /* bounced */
+ }
+ if (i = setjmp(power_resume)) {
+ /* power back up */
+ rs232power(1);
+ lcdpower(1);
+ audiopower(1);
+ irpower(1);
+ return;
}
+ /* Power down */
+ irpower(0);
+ audiopower(0);
+ lcdpower(0);
+ rs232power(0);
+ sa1100_power_off();
+ /* no return */
}
static void
@@ 54,6 55,8 @@ sa1100_power_off(void)
{
delay(100);
splhi();
+ /* enable wakeup by µcontroller, on/off switch or real-time clock alarm */
+ powerregs->pwer = 0x80000003;
/* disable internal oscillator, float CS lines */
powerregs->pcfr = 1<<pcfr_opde | 1<<pcfr_fp | 1<<pcfr_fs;
/* set lowest clock */
M bitsy/sa1110dma.c => bitsy/sa1110dma.c +17 -11
@@ 78,10 78,25 @@ dmainit(void) {
}
}
+void
+dmareset(int i, int rd, int bigendian, int burstsize, int datumsize, int device, ulong port) {
+ ulong ddar;
+
+ ddar =
+ (rd?1:0)<<RW |
+ (bigendian?1:0)<<E |
+ ((burstsize==8)?1:0)<<BS |
+ ((datumsize==2)?1:0)<<DW |
+ device<<DS |
+ 0x80000000 | ((ulong)port << 6);
+ dmaregs[i].ddar = ddar;
+ dmaregs[i].dcsr_clr = 0xff;
+ if (debug) print("dma: dmareset: 0x%lux\n", ddar);
+}
+
int
dmaalloc(int rd, int bigendian, int burstsize, int datumsize, int device, ulong port, void (*intr)(void*, ulong), void *param) {
int i;
- ulong ddar;
lock(&dma);
for (i = 0; i < NDMA; i++) {
@@ 89,18 104,9 @@ dmaalloc(int rd, int bigendian, int burstsize, int datumsize, int device, ulong
continue;
dma.chan[i].allocated++;
unlock(&dma);
- ddar =
- (rd?1:0)<<RW |
- (bigendian?1:0)<<E |
- ((burstsize==8)?1:0)<<BS |
- ((datumsize==2)?1:0)<<DW |
- device<<DS |
- 0x80000000 | ((ulong)port << 6);
- dmaregs[i].ddar = ddar;
- if (debug) print("dma: dmaalloc: 0x%lux\n", ddar);
+ dmareset(i, rd, bigendian, burstsize, datumsize, device, port);
dma.chan[i].intr = intr;
dma.chan[i].param = param;
- dmaregs[i].dcsr_clr = 0xff;
return i;
}
unlock(&dma);
M bitsy/sa1110dma.h => bitsy/sa1110dma.h +1 -0
@@ 9,6 9,7 @@ enum {
void dmainit(void);
int dmaalloc(int, int, int, int, int, ulong, void (*)(void*, ulong), void*);
+void dmareset(int, int, int, int, int, int, ulong);
void dmafree(int);
ulong dmastart(int, ulong, int);
M bitsy/trap.c => bitsy/trap.c +1 -1
@@ 146,7 146,7 @@ gpiointrenable(ulong bit, int edge, void (*f)(Ureg*, void*), void* a, char *name
/* it had better be input */
if(bit & gpioregs->direction)
- panic(""gpiointrenable %lux of output pin", bit);
+ panic("gpiointrenable %lux of output pin", bit);
/* set edge register */
switch(edge){