void USART1_IRQHandler(void) { if (USART_GetITStatus(CEREAL_USARTx, USART_IT_RXNE) != RESET) { uint8_t c = cereal_rx_raw(); if (!ringbuffer_isfull(&cereal_incoming)) { ringbuffer_push(&cereal_incoming, c); if (c == 0 || c == '\r' || c == '\n') { cereal_incoming.flag = 1; } } else { cereal_incoming.flag = 1; } } if (USART_GetITStatus(CEREAL_USARTx, USART_IT_TXE) != RESET ) { #ifdef ENABLE_CEREAL_BUFFERED_TX if (!ringbuffer_isempty(&cereal_outgoing)) { cereal_tx_raw(ringbuffer_pop(&cereal_outgoing)); } else { cereal_outgoing.flag = 0; USART_ITConfig(CEREAL_USARTx, USART_IT_TXE, DISABLE); } #endif } }
void cereal_wait() { #ifdef ENABLE_CEREAL_BUFFERED_TX while (ringbuffer_isfull(&cereal_outgoing)) ; #else while (USART_GetFlagStatus(CEREAL_USARTx, USART_FLAG_TXE) == RESET) ; #endif }
void cereal_tx(uint8_t x) { #ifdef ENABLE_CEREAL_BUFFERED_TX if (!ringbuffer_isfull(&cereal_outgoing)) { ringbuffer_push(&cereal_outgoing, x); if (cereal_outgoing.flag == 0) { cereal_tx_raw(ringbuffer_pop(&cereal_outgoing)); cereal_outgoing.flag = 1; USART_ITConfig(CEREAL_USARTx, USART_IT_TXE, ENABLE); } } #else cereal_tx_raw(x); while (USART_GetFlagStatus(CEREAL_USARTx, USART_FLAG_TXE) == RESET) ; #endif }
static void soundcard_tick(int cyclesexecuted, bool behind) { static int carry = 0; //if (!active) { // return; //} int total = cyclesexecuted + carry; carry = total % TICKSPERSAMPLE; int ticks = total - carry; int samples = ticks / TICKSPERSAMPLE; //log_println(LEVEL_INFO, TAG, "executed %d carry %d ticks %d samples %d", cyclesexecuted, carry, ticks, samples); if (samples == 0) return; SDL_LockAudio(); for (int i = 0; i < samples; i++) { masterchannel* master = &(channels[0].master); if (master->config && SOUND_CHANNEL_ENABLED) { // sound is enabled int16_t leftSample = 0; int16_t rightSample = 0; for (int i = 1; i < TOTALCHANNELS; i++) { if (channels[i].audio.config & SOUND_CHANNEL_ENABLED) { // channel ran out of samples.. so latch it again audiochannel* chan = &(channelslatched[i].audio); if (chan->samplepos == chan->samplelength) { channelslatched[i] = channels[i]; chan = &(channelslatched[i].audio); } int page = (chan->config & SOUND_CHANNEL_PAGE) >> SOUND_CHANNEL_PAGE_SHIFT; uint32_t pageoffset = SAMPLEPAGESIZE * page; uint32_t sampleoffset = pageoffset + chan->samplepointer + (chan->samplepos * 2); // LEFT if (chan->config & SOUND_CHANNEL_LEFT) { //audiobuffer[bufferindex] = soundcard_mixsamples(audiobuffer[bufferindex], // READ_WORD(sampleram, sampleoffset), VOLLEFT(chan->volume)); leftSample = READ_WORD(sampleram, sampleoffset); } // RIGHT if (chan->config & SOUND_CHANNEL_RIGHT) { //rightSample = soundcard_mixsamples(rightSample, READ_WORD(sampleram, sampleoffset), // VOLRIGHT(chan->volume)); rightSample = READ_WORD(sampleram, sampleoffset); } // chan is all out of samples.. chan->samplepos++; if (chan->samplepos == chan->samplelength) { if (chan->config & SOUND_CHANNEL_INTERRUPT) { chan->config |= SOUND_CHANNEL_RELOAD; board_raise_interrupt(&soundcard); } } } } // Adjust the output to the master volume. //audiobuffer[bufferindex] *= VOLLEFT(master->volume) / UINT8_MAX; //audiobuffer[bufferindex + 1] *= VOLLEFT(master->volume) / UINT8_MAX; ringbuffer_put(audiobuffer, leftSample); ringbuffer_put(audiobuffer, rightSample); // we have caught up with the output if (ringbuffer_isfull(audiobuffer)) { log_println(LEVEL_INFO, TAG, "audio buffer has overflown"); break; } }