int sound_add_sample(U8 *data, U32 length, U32 freq, int vol) { // Add a set of samples into the playback queue, if not currently // playing start the playback process. // If this is the first sample simply start to play it if (sound_mode != SOUND_MODE_PCM || sample.ptr != sample.sample_buf) { if (sample.sample_buf == NULL) { sample.sample_buf = system_allocate(SAMPLEBUFSZ); if (sample.sample_buf == NULL) return -1; } if (length > SAMPLEBUFSZ - 1) length = SAMPLEBUFSZ - 1; memcpy(sample.sample_buf, data, length); sound_play_sample(sample.sample_buf, length, freq, vol); return length; } // Otherwise add the data to the buffer // Turn off ints while we update shared values sound_interrupt_disable(); // add the data U8 *sbuf = sample.ptr; U32 in = sample.in_index; U32 out = sample.out_index; int cnt = (int) ((out - in - 1) & (SAMPLEBUFSZ - 1)); if (cnt > length) cnt = length; length = cnt; while (cnt-- > 0) { sbuf[in] = *data++; in = (in + 1) & (SAMPLEBUFSZ - 1); } sample.in_index = in; sample.count = (((in - out) & (SAMPLEBUFSZ - 1)) + SAMPPERBUF - 1)/SAMPPERBUF; // re-enable and wait for the current sample to complete sound_interrupt_enable(AT91C_SSC_ENDTX); *AT91C_SSC_PTCR = AT91C_PDC_TXTEN; return length; }
// Enable an I2C port // returns > 0 OK, == 0 no memory < 0 error int i2c_enable(int port, int mode) { if (port >= 0 && port < I2C_N_PORTS) { U32 pinmask; i2c_port *p = i2c_ports[port]; // Allocate memory if required if (!p) { p = (i2c_port *) system_allocate(sizeof(i2c_port)); if (!p) return 0; i2c_ports[port] = p; } p->scl_pin = sensor_pins[port].pins[SP_DIGI0]; p->sda_pin = sensor_pins[port].pins[SP_DIGI1]; pinmask = p->scl_pin | p->sda_pin; p->state = I2C_IDLE; /* Set clock pin for output, open collector driver, with * pullups enabled. Set data to be enabled for output with * pullups disabled. */ *AT91C_PIOA_SODR = pinmask; *AT91C_PIOA_OER = pinmask; *AT91C_PIOA_MDER = p->scl_pin; *AT91C_PIOA_PPUDR = p->sda_pin; *AT91C_PIOA_PPUER = p->scl_pin; /* If we are always active, we never drop below the ACTIVEIDLE state */ p->lego_mode = ((mode & I2C_LEGO_MODE) ? 1 : 0); p->no_release = ((mode & I2C_NO_RELEASE) ? 1 : 0); p->always_active = ((mode & I2C_ALWAYS_ACTIVE) ? 1 : 0); if (p->always_active) { p->state = I2C_ACTIVEIDLE; build_active_list(); } return 1; } return -1; }
/** * Allocate the required buffers and structures from system memory to allow * use of the specified usart and associated dma channel. */ usart * usart_allocate(AT91S_USART *dev, AT91S_PDC *dma, int inSz, int outSz) { usart *us; // do memory allocation for buffer space U8 *mem = system_allocate(sizeof(usart) + inSz*BUF_CNT + outSz*BUF_CNT); if (mem == NULL) return NULL; us = (usart *) mem; us->dma = dma; us->dev = dev; mem += sizeof(usart); us->in_buf[0] = mem; mem += inSz; us->in_buf[1] = mem; mem += inSz; us->out_buf[0] = mem; mem += outSz; us->out_buf[1] = mem; us->in_offset = 0; us->in_base = us->out_base = 0; us->in_size = inSz; us->out_size = outSz; return us; }