Example #1
0
/////////////////////////////////////////////////////////////////////////////
//! Starts a new transfer. If this function is called during an ongoing
//! transfer, we wait until it has been finished and setup the new transfer
//! \param[in] transfer type:<BR>
//! <UL>
//!   <LI>IIC_Read: a common Read transfer
//!   <LI>IIC_Write: a common Write transfer
//!   <LI>IIC_Read_AbortIfFirstByteIs0: used to poll MBHP_IIC_MIDI: aborts transfer
//!         if the first received byte is 0
//!   <LI>IIC_Write_WithoutStop: don't send stop condition after transfer to allow
//!         a restart condition (e.g. used to access EEPROMs)
//! \param[in] iic_port the IIC port (0..MIOS32_IIC_NUM-1)
//! \param[in] address of IIC device (bit 0 always cleared)
//! \param[in] *buffer pointer to transmit/receive buffer
//! \param[in] len number of bytes which should be transmitted/received
//! \return 0 no error
//! \return < 0 on errors, if MIOS32_IIC_ERROR_PREV_OFFSET is added, the previous
//!      transfer got an error (the previous task didn't use \ref MIOS32_IIC_TransferWait
//!      to poll the transfer state)
//! \note Note that the semaphore will be released automatically after an error
//! (MIOS32_IIC_TransferBegin() has to be called again)
/////////////////////////////////////////////////////////////////////////////
s32 MIOS32_IIC_Transfer(u8 iic_port, mios32_iic_transfer_t transfer, u8 address, u8 *buffer, u16 len)
{
  iic_rec_t *iicx = &iic_rec[iic_port];// simplify addressing of record
  s32 error;

  if( iic_port >= MIOS32_IIC_NUM )
    return MIOS32_IIC_ERROR_INVALID_PORT;

  // wait until previous transfer finished
  if( (error = MIOS32_IIC_TransferWait(iic_port)) ) { // transmission error during previous transfer
    iicx->iic_semaphore = 0; // release semaphore for easier programming at user level
    return error + MIOS32_IIC_ERROR_PREV_OFFSET;
  }

  // disable interrupts
  MIOS32_IRQ_Disable(); // TODO: disable peripheral

  // clear transfer state and error value
  iicx->transfer_state.ALL = 0;
  iicx->transfer_error = 0;

  // set buffer length and start index
  iicx->buffer_len = len;
  iicx->buffer_ix = 0;

  // branch depending on read/write
  if( transfer == IIC_Read || transfer == IIC_Read_AbortIfFirstByteIs0 ) {
    // take new address/buffer/len
    iicx->iic_address = address | 1; // set bit 0 for read operation
    iicx->tx_buffer_ptr = NULL; // ensure that previous TX buffer won't be accessed
    iicx->rx_buffer_ptr = buffer;
    // special option for optimized MBHP_IIC_MIDI
    iicx->transfer_state.ABORT_IF_FIRST_BYTE_0 = transfer == IIC_Read_AbortIfFirstByteIs0 ? 1 : 0;
  } else if( transfer == IIC_Write || transfer == IIC_Write_WithoutStop ) {
    // take new address/buffer/len
    iicx->iic_address = address & 0xfe; // clear bit 0 for write operation
    iicx->tx_buffer_ptr = buffer;
    iicx->rx_buffer_ptr = NULL; // ensure that nothing will be received
    // option to skip stop-condition generation after successful write
    iicx->transfer_state.WRITE_WITHOUT_STOP = transfer == IIC_Write_WithoutStop ? 1 : 0;
  } else {
    iicx->iic_semaphore = 0; // release semaphore for easier programming at user level
    MIOS32_IRQ_Enable(); // TODO: enable peripheral??
    return (iicx->last_transfer_error=MIOS32_IIC_ERROR_UNSUPPORTED_TRANSFER_TYPE);
  }

  // clear last error status
  iicx->last_transfer_error = 0;

  // notify that transfer has started
  iicx->transfer_state.BUSY = 1;

  MIOS32_IRQ_Enable(); // TODO: enable peripheral

  // send start condition
  iicx->base->I2CONCLR = 0x04; // clear AA (assert acknowledge) bit
  iicx->base->I2CONSET = 0x20; // set STA (start) bit

  return 0; // no error
}
/////////////////////////////////////////////////////////////////////////////
// Read a patch
/////////////////////////////////////////////////////////////////////////////
s32 MbCvEnvironment::bankLoad(u8 bank, u8 patch, bool forceImmediateChange)
{
    if( bank >= CV_BANK_NUM )
        return -2; // invalid bank

    if( patch >= 128 )
        return -3; // invalid patch

#if 1
    DEBUG_MSG("[CV_BANK_PatchRead] read patch %c%03d\n", 'A'+bank, patch+1);
#endif

    if( mbCvPatch.synchedChange && !forceImmediateChange ) {
        // request change
        MIOS32_IRQ_Disable();
        mbCvPatch.reqChange = true;
        mbCvPatch.nextBankNum = bank;
        mbCvPatch.nextPatchNum = patch;
        MIOS32_IRQ_Enable();
    } else {
        // do immediate change
        mbCvPatch.bankNum = bank;
        mbCvPatch.patchNum = patch;

        // file operation
        MBCV_PATCH_Load(bank, patch);

#if 0
        // update patch structures
        MbCv *s = mbCv.first();
        for(int cv=0; cv < mbCv.size; ++cv, ++s) {
            s->updatePatch(false);
        }
#endif

        // send confirmation (e.g. to Lemur)
        if( lastNrpnMidiPort ) {
            midiSendNRPNDump(lastNrpnMidiPort, lastNrpnCvChannels, 0);
            midiSendGlobalNRPNDump(lastNrpnMidiPort);
        }

        // change done
        MIOS32_IRQ_Disable();
        mbCvPatch.reqChange = false;
        mbCvPatch.reqChangeAck = false;
        MIOS32_IRQ_Enable();
    }

    return 0; // no error
}
/////////////////////////////////////////////////////////////////////////////
// This function should be called from Tick() in main.c
// it updates the meters patterns for which an update has been requested
/////////////////////////////////////////////////////////////////////////////
s32 LC_METERS_CheckUpdates(void)
{
  u8 meter;
  u8 meter_select;
  u8 center_led;
  u8 level;

  for(meter=0, meter_select=0x01; meter<8; ++meter) {

    // check if update has been requested
    if( meter_update_req & meter_select ) {
      MIOS32_IRQ_Disable();
      meter_update_req &= ~meter_select; // clear request flag
      MIOS32_IRQ_Enable();

      // set LED pattern
      level = meter_level[meter];
      center_led = (level & (1 << 7)) ? 1 : 0;
      meter_pattern[meter] = meter_patterns[level & 0x0f] | (center_led ? (1 << (12-1)) : 0);
    }

    meter_select <<= 1; // shift left the select bit
  }

  return 0; // no error
}
/////////////////////////////////////////////////////////////////////////////
// This function should be called from Timer() in main.c every 20 ms (see Init())
//
// handles the meter counters. For the best show effect we don't decrement
// all meter levels at once every 300 ms, but seperately
// 	
// every single counter will be reloaded by lc_mproc.inc::LC_MPROC_Received_D0
// to 15 (== 300 ms / 20 ms), the levels will be decremented when this
// value reaches zero
/////////////////////////////////////////////////////////////////////////////
s32 LC_METERS_Timer(void)
{
  u8 meter;
  u8 level;

  for(meter=0; meter<8; ++meter) {
    
    // decrement counter, continue once counter is zero
    if( !--meter_counter[meter] ) {
      meter_counter[meter] = 15; // preload counter again

      // decrement meter level if != 0
      level = meter_level[meter];
      if( level & 0x7f ) {
	meter_level[meter] = (level & 0x80) | ((level & 0x7f) - 1);
	MIOS32_IRQ_Disable();
	meter_update_req |= (1 << meter); // request update
	MIOS32_IRQ_Enable();
	LC_LCD_Update_Meter(meter); // request update on LCD
      }
    }
  }

  return 0; // no error
}
Example #5
0
/////////////////////////////////////////////////////////////////////////////
//! puts more than one byte onto the transmit buffer (used for atomic sends)
//! \param[in] *buffer pointer to buffer to be sent
//! \param[in] len number of bytes to be sent
//! \return 0 if no error
//! \return -1 if buffer full or cannot get all requested bytes (retry)
//! \note Applications shouldn't call these functions directly, instead please use \ref FBV
/////////////////////////////////////////////////////////////////////////////
s32 FBV_UART_TxBufferPutMore_NonBlocking( u8 *buffer, u16 len)
{

  if( (tx_buffer_size+len) >= FBV_UART_TX_BUFFER_SIZE )
    return -1; // buffer full or cannot get all requested bytes (retry)

  // copy bytes to be transmitted into transmit buffer
  // this operation should be atomic!
  MIOS32_IRQ_Disable();

  u16 i;
  for(i=0; i<len; ++i) {
    tx_buffer[tx_buffer_head] = *buffer++;

    if( ++tx_buffer_head >= FBV_UART_TX_BUFFER_SIZE )
      tx_buffer_head = 0;

    // enable Tx interrupt if buffer was empty
    if( ++tx_buffer_size == 1 ) {
        FBV_UART->CR1 |= (1 << 7); // enable TXE interrupt (TXEIE=1)
    }
  }

  MIOS32_IRQ_Enable();

  return 0; // no error
}
/////////////////////////////////////////////////////////////////////////////
// This function sets the meter level
/////////////////////////////////////////////////////////////////////////////
s32 LC_METERS_LevelSet(u8 meter, u8 level)
{
  // coding:
  // meter: channel to be address (0 thru 7)
  // level: lever meter:
  //       0 thru C: level meter 0%..100% (overload not cleared!)
  //       E       : set overload
  //       F       : clear overload

  // our own coding in METER_LEVEL[meter_number] array:
  // O000llll
  // O: overload flag
  // llll: 1 thru D - lever meter 0%..100% (+1)

  MIOS32_IRQ_Disable();

  if( level == 0x0e ) {         // set overload flag
    // meter_level[meter] |= 0x80;
    meter_level[meter] = 0x8d;  // set overload flag and set level to highest value (seems to be better with Logic Audio)
  } else if (level == 0x0f ) {  // clear overload flag
    meter_level[meter] &= 0x7f;
  } else {                      // set value, dont touch overload flag
    meter_level[meter] = (meter_level[meter] & 0x80) | ((level & 0x0f) + 1);
  }

  meter_update_req |= (1 << meter); // request update of meter

  LC_LCD_Update_Meter(meter); // request update on LCD

  MIOS32_IRQ_Enable();

  return 0; // no error
}
Example #7
0
/////////////////////////////////////////////////////////////////////////////
// resets note stacks used for patch changer
/////////////////////////////////////////////////////////////////////////////
s32 SEQ_MIDI_IN_ResetChangerStacks(void)
{
  int i;

  for(i=0; i<SECTION_CHANGER_NOTESTACK_NUM; ++i)
    NOTESTACK_Init(&section_changer_notestack[i],
		   NOTESTACK_MODE_PUSH_TOP,
		   &section_changer_notestack_items[i][0],
		   SEQ_MIDI_IN_SECTION_CHANGER_NOTESTACK_SIZE);

  for(i=0; i<PATCH_CHANGER_NOTESTACK_NUM; ++i)
    NOTESTACK_Init(&patch_changer_notestack[i],
		   NOTESTACK_MODE_PUSH_TOP,
		   &patch_changer_notestack_items[i][0],
		   SEQ_MIDI_IN_PATCH_CHANGER_NOTESTACK_SIZE);

  // following operation should be atomic!
  u8 track;
  seq_core_trk_t *t = &seq_core_trk[0];
  MIOS32_IRQ_Disable();
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t)
    t->play_section = 0; // don't select section
  MIOS32_IRQ_Enable();

  return 0; // no error
}
Example #8
0
/////////////////////////////////////////////////////////////////////////////
// Access to "SID Available" flags
// Each of up to 8 SIDs has a flag - if set to 0, it won't be updated
/////////////////////////////////////////////////////////////////////////////
s32 SID_AvailableSet(u8 available)
{
  sid_available = available;

#if SID_USE_MBNET
  MIOS32_IRQ_Disable();
  if( sid_available && mbnet_tx_state == MBNET_TX_STATE_NOP ) {
    // start MBNet transfers once SIDs have been found
    mbnet_tx_state = MBNET_TX_STATE_SID1;
    mbnet_tx_reg_ctr = 0;
    mbnet_tx_msg_ctr = 0;
    mbnet_tx_msg_ctr_min = 0;
    mbnet_tx_msg_ctr_max = 0;
    mbnet_my_node_id = MBNET_NodeIDGet();
    MBNET_InstallTxHandler(SID_MBNET_TxHandler);
  } else if( !sid_available && mbnet_tx_state != MBNET_TX_STATE_NOP ) {
    // stop MBNet transfers
    mbnet_tx_state = MBNET_TX_STATE_NOP;
    MBNET_InstallTxHandler(NULL);
  }
  MIOS32_IRQ_Enable();
#endif

  return 0; // no error
}
Example #9
0
/////////////////////////////////////////////////////////////////////////////
// silence one voice
/////////////////////////////////////////////////////////////////////////////
void stopv(struct voicedata*v) {
  MIOS32_IRQ_Disable();

  v->egv[0].state=0; // stop aeg processing for voice
  v->egv[0].logout=0;
  v->egv[0].out=0;   // silence voice
  v->egv[1].state=0; // stop feg processing for voice
  v->egv[1].logout=0;
  v->egv[1].out=0;
  v->eg0trip=0;
  v->o1egstate=1;
  v->o1eglogout=0;
  v->o1egout=0;
  v->o1vol=0;
  v->o1o=0;
  v->o1fb=0;
  v->fk=0;
  v->chan=NCHAN-1;
  v->vol=0;
  v->out=0;
  v->o0ph=0x00000000;
  v->o0dph=0x00000000;
  v->o1dph=0x00000000;
  v->lo=v->ba=0;

  MIOS32_IRQ_Enable();
}
Example #10
0
/////////////////////////////////////////////////////////////////////////////
// Updates all CV channels and gates
/////////////////////////////////////////////////////////////////////////////
extern "C" s32 MBCV_MAP_Update(void)
{
  // retrieve the AOUT values of all channels
  MbCvEnvironment* env = APP_GetEnv();

  u16 *out = env->cvOut.first();
  for(int cv=0; cv<CV_SE_NUM; ++cv, ++out)
    AOUT_PinSet(cv, *out);

  // update AOUTs
  AOUT_Update();

  AOUT_DigitalPinsSet(env->cvGates);

  // gates and DIN sync signals are available at shift registers
  u8 gates = AOUT_DigitalPinsGet();
  u8 din_sync_value = 0;
  {
    if( env->mbCvClock.isRunning )
      din_sync_value |= (1 << 0); // START/STOP

    din_sync_value |= env->mbCvClock.externalClocks << 1;
  }

  // following DOUT transfers should be atomic to ensure, that all pins are updated at the same scan cycle
  MIOS32_IRQ_Disable();
  if( mbcv_hwcfg_dout.gate_sr )
    MIOS32_DOUT_SRSet(mbcv_hwcfg_dout.gate_sr-1, gates);
  if( mbcv_hwcfg_dout.clk_sr )
    MIOS32_DOUT_SRSet(mbcv_hwcfg_dout.clk_sr-1, din_sync_value);
  MIOS32_IRQ_Enable();

  return 0; // no error
}
Example #11
0
/////////////////////////////////////////////////////////////////////////////
// This task is running endless in background
/////////////////////////////////////////////////////////////////////////////
void APP_Background(void)
{
  // clear LCD screen
  MIOS32_LCD_Clear();

  MIOS32_LCD_CursorSet(0, 0);
  MIOS32_LCD_PrintString("see README.txt   ");
  MIOS32_LCD_CursorSet(0, 1);
  MIOS32_LCD_PrintString("for details     ");

  // send delay min/max changes to MIOS terminal
  while( 1 ) {
    if( print_message ) {
      MIOS32_IRQ_Disable();
      u32 c_total_delay = total_delay;
      u32 c_midi_clock_ctr = midi_clock_ctr;
      delay_t c_d_tick = d_tick;
      delay_t c_d_beat = d_beat;
      print_message = 0;
      MIOS32_IRQ_Enable();

      u32 bpm = 60000000 / c_d_beat.delay_last;
      u32 avg = c_midi_clock_ctr ? (c_total_delay / c_midi_clock_ctr) : 0;

      MIOS32_MIDI_SendDebugMessage("BPM %d.%d  -  tick min/avg/max = %d.%03d/%d.%03d/%d.%03d\n",
				   bpm / 1000, bpm % 1000,
				   c_d_tick.delay_min / 1000, c_d_tick.delay_min % 1000,
				   avg / 1000, avg % 1000,
				   c_d_tick.delay_max / 1000, c_d_tick.delay_max % 1000);
    }
  }
}
Example #12
0
/////////////////////////////////////////////////////////////////////////////
// This function requests a LEDring update for the given VPots
/////////////////////////////////////////////////////////////////////////////
s32 LC_VPOT_LEDRingUpdateSet(u8 rings)
{
  MIOS32_IRQ_Disable();
  ledring_update_req |= rings;
  MIOS32_IRQ_Enable();

  return 0; // no error
}
Example #13
0
/////////////////////////////////////////////////////////////////////////////
// This function sets the meter mode
/////////////////////////////////////////////////////////////////////////////
s32 LC_METERS_ModeSet(u8 meter, u8 mode)
{
  meter_mode[meter] = mode;
  MIOS32_IRQ_Disable();
  meter_update_req |= (1 << meter); // request update of meter
  MIOS32_IRQ_Enable();

  return 0; // no error
}
Example #14
0
/////////////////////////////////////////////////////////////////////////////
//! MSD access functions
/////////////////////////////////////////////////////////////////////////////
s32 TASK_MSD_EnableSet(u8 enable)
{
  MIOS32_IRQ_Disable();
  if( msd_state == MSD_DISABLED && enable ) {
    msd_state = MSD_INIT;
  } else if( msd_state == MSD_READY && !enable )
    msd_state = MSD_SHUTDOWN;
  MIOS32_IRQ_Enable();

  return 0; // no error
}
Example #15
0
s32 SID_Update(u32 mode)
{
  int sid, reg;
  // if register update should be forced, just inverse all shadow register values
  if( mode >= 1 ) { // (also for reset mode)
    MIOS32_IRQ_Disable();
    for(sid=0; sid<SID_NUM; ++sid)
      sid_regs_shadow_updated[sid] = 0xffffffff;
    MIOS32_IRQ_Enable();
  }

  // transfer SID registers to shadow registers and check for updates
  MIOS32_IRQ_Disable();
  for(sid=0; sid<SID_NUM; ++sid) {
    u8 *regs = (u8 *)&sid_regs[sid];
    u8 *regs_shadow = (u8 *)&sid_regs_shadow[sid];

    for(reg=0; reg<SID_REGS_NUM; ++reg) {
      if( *regs_shadow != *regs )
	sid_regs_shadow_updated[sid] |= (1 << reg);
      *regs_shadow++ = *regs++;
    }
  }
  MIOS32_IRQ_Enable();

  // trigger next update
  if( mbnet_tx_state == MBNET_TX_STATE_DONE && sid_available ) {
    if( mbnet_tx_msg_ctr && (!mbnet_tx_msg_ctr_min || mbnet_tx_msg_ctr < mbnet_tx_msg_ctr_min) )
      mbnet_tx_msg_ctr_min = mbnet_tx_msg_ctr;
    if( mbnet_tx_msg_ctr > mbnet_tx_msg_ctr_max )
      mbnet_tx_msg_ctr_max = mbnet_tx_msg_ctr;

    mbnet_tx_msg_ctr = 0;
    mbnet_tx_reg_ctr = 0;

    mbnet_tx_state = MBNET_TX_STATE_SID1;
    MBNET_TriggerTxHandler();
  }

  return 0; // no error
}
Example #16
0
/////////////////////////////////////////////////////////////////////////////
// This function sets the absolute vpot value
/////////////////////////////////////////////////////////////////////////////
s32 LC_VPOT_ValueSet(u8 vpot, u8 value)
{
  vpot_abs_value[vpot] = value;

  MIOS32_IRQ_Disable();
  ledring_update_req |= (1 << vpot); // request update of ledring
  MIOS32_IRQ_Enable();

  LC_LCD_Update_Knob(vpot); // request update on LCD

  return 0; // no error
}
Example #17
0
/////////////////////////////////////////////////////////////////////////////
//! returns the next byte of the receive buffer without taking it
//! \return -1 if no new byte available
//! \return >= 0: number of received bytes
//! \note Applications shouldn't call these functions directly, instead please use \ref FBV
/////////////////////////////////////////////////////////////////////////////
s32 FBV_UART_RxBufferPeek(void)
{
  if( !rx_buffer_size )
    return -1; // nothing new in buffer

  // get byte - this operation should be atomic!
  MIOS32_IRQ_Disable();
  u8 b = rx_buffer[rx_buffer_tail];
  MIOS32_IRQ_Enable();

  return b; // return received byte
}
Example #18
0
/////////////////////////////////////////////////////////////////////////////
//! puts more than one byte onto the transmit buffer (used for atomic sends)
//! \param[in] uart UART number (0..2)
//! \param[in] *buffer pointer to buffer to be sent
//! \param[in] len number of bytes to be sent
//! \return 0 if no error
//! \return -1 if UART not available
//! \return -2 if buffer full or cannot get all requested bytes (retry)
//! \return -3 if UART not supported by MIOS32_UART_TxBufferPut Routine
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
/////////////////////////////////////////////////////////////////////////////
s32 MIOS32_UART_TxBufferPutMore_NonBlocking(u8 uart, u8 *buffer, u16 len)
{
#if NUM_SUPPORTED_UARTS == 0
  return -1; // no UART available
#else
  if( uart >= NUM_SUPPORTED_UARTS )
    return -1; // UART not available

  if( (tx_buffer_size[uart]+len) >= MIOS32_UART_TX_BUFFER_SIZE )
    return -2; // buffer full or cannot get all requested bytes (retry)

  // copy bytes to be transmitted into transmit buffer
  // this operation should be atomic!
  MIOS32_IRQ_Disable();

  u16 i;
  for(i=0; i<len; ++i) {
    tx_buffer[uart][tx_buffer_head[uart]] = *buffer++;

    if( ++tx_buffer_head[uart] >= MIOS32_UART_TX_BUFFER_SIZE )
      tx_buffer_head[uart] = 0;

    // enable Tx interrupt if buffer was empty
    if( ++tx_buffer_size[uart] == 1 ) {
      switch( uart ) {
        case 0: MIOS32_UART0->CR1 |= (1 << 7); break; // enable TXE interrupt (TXEIE=1)
        case 1: MIOS32_UART1->CR1 |= (1 << 7); break; // enable TXE interrupt (TXEIE=1)
        case 2: MIOS32_UART2_TX->CR1 |= (1 << 7); break; // enable TXE interrupt (TXEIE=1)
        case 3: MIOS32_UART3->CR1 |= (1 << 7); break; // enable TXE interrupt (TXEIE=1)
        default: MIOS32_IRQ_Enable(); return -3; // uart not supported by routine (yet)
      }
    }
  }

  MIOS32_IRQ_Enable();

  return 0; // no error
#endif
}
Example #19
0
/////////////////////////////////////////////////////////////////////////////
//! gets a byte from the receive buffer
//! \return -1 if no new byte available
//! \return >= 0: number of received bytes
//! \note Applications shouldn't call these functions directly, instead please use \ref FBV
/////////////////////////////////////////////////////////////////////////////
s32 FBV_UART_RxBufferGet(void)
{
   if( !rx_buffer_size )
    return -1; // nothing new in buffer

  // get byte - this operation should be atomic!
  MIOS32_IRQ_Disable();
  u8 b = rx_buffer[rx_buffer_tail];
  if( ++rx_buffer_tail >= FBV_UART_RX_BUFFER_SIZE )
    rx_buffer_tail = 0;
  --rx_buffer_size;
  MIOS32_IRQ_Enable();

  return b; // return received byte
}
/////////////////////////////////////////////////////////////////////////////
// This function will be called each second to handle the screen saver
/////////////////////////////////////////////////////////////////////////////
s32 SEQ_LCD_LOGO_ScreenSaver_Period1S(void)
{
  // operation should be atomic
  MIOS32_IRQ_Disable();

  if( screen_saver_ctr < (60*(u16)seq_lcd_logo_screensaver_delay) ) {
    if( ++screen_saver_ctr >= (60*(u16)seq_lcd_logo_screensaver_delay) ) {
      SEQ_LCD_LOGO_ScreenSaver_Enable();
    }
  }

  MIOS32_IRQ_Enable();

  return 0; // no error
}
Example #21
0
/////////////////////////////////////////////////////////////////////////////
// Parser
/////////////////////////////////////////////////////////////////////////////
s32 CONSOLE_Parse(mios32_midi_port_t port, u8 byte)
{
  // temporary change debug port (will be restored at the end of this function)
  mios32_midi_port_t prev_debug_port = MIOS32_MIDI_DebugPortGet();
  MIOS32_MIDI_DebugPortSet(port);

  if( byte == '\r' ) {
    // ignore
  } else if( byte == '\n' ) {
    // example for parsing the command:
    char *separators = " \t";
    char *brkt;
    char *parameter;

    if( (parameter = strtok_r(line_buffer, separators, &brkt)) ) {
      if( strcmp(parameter, "help") == 0 ) {
	MIOS32_MIDI_SendDebugMessage("Welcome to " MIOS32_LCD_BOOT_MSG_LINE1 "!");
	MIOS32_MIDI_SendDebugMessage("Following commands are available:");
	MIOS32_MIDI_SendDebugMessage("  reset:          clears the current measurements\n");
	MIOS32_MIDI_SendDebugMessage("  help:           this page\n");
      } else if( strcmp(parameter, "reset") == 0 ) {
	MIOS32_IRQ_Disable();
	u8 including_min_max = 1;
	DelayInit(&d_tick, including_min_max);
	DelayInit(&d_measure, including_min_max);
	DelayInit(&d_beat, including_min_max);
	midi_clock_ctr = 0;
	total_delay = 0;
	MIOS32_IRQ_Enable();

	MIOS32_MIDI_SendDebugMessage("Measurements have been cleared!\n");
      } else {
	MIOS32_MIDI_SendDebugMessage("Unknown command - type 'help' to list available commands!\n");
      }
    }

    line_ix = 0;

  } else if( line_ix < (STRING_MAX-1) ) {
    line_buffer[line_ix++] = byte;
    line_buffer[line_ix] = 0;
  }

  // restore debug port
  MIOS32_MIDI_DebugPortSet(prev_debug_port);

  return 0; // no error
}
Example #22
0
/////////////////////////////////////////////////////////////////////////////
//! gets a byte from the transmit buffer
//! \return -1 if no new byte available
//! \return >= 0: transmitted byte
//! \note Applications shouldn't call these functions directly, instead please use \ref FBV
/////////////////////////////////////////////////////////////////////////////
s32 FBV_UART_TxBufferGet(void)
{

  if( !tx_buffer_size )
    return -1; // nothing new in buffer

  // get byte - this operation should be atomic!
  MIOS32_IRQ_Disable();
  u8 b = tx_buffer[tx_buffer_tail];
  if( ++tx_buffer_tail >= FBV_UART_TX_BUFFER_SIZE )
    tx_buffer_tail = 0;
  --tx_buffer_size;
  MIOS32_IRQ_Enable();

  return b; // return transmitted byte
}
Example #23
0
/////////////////////////////////////////////////////////////////////////////
//! puts a byte onto the receive buffer
//! \param[in] b byte which should be put into Rx buffer
//! \return 0 if no error
//! \return -1 if buffer full (retry)
//! \note Applications shouldn't call these functions directly, instead please use \ref FBV
/////////////////////////////////////////////////////////////////////////////
s32 FBV_UART_RxBufferPut( u8 b)
{

  if( rx_buffer_size >= FBV_UART_RX_BUFFER_SIZE )
    return -1; // buffer full (retry)

  // copy received byte into receive buffer
  // this operation should be atomic!
  MIOS32_IRQ_Disable();
  rx_buffer[rx_buffer_head] = b;
  if( ++rx_buffer_head >= FBV_UART_RX_BUFFER_SIZE )
    rx_buffer_head = 0;
  ++rx_buffer_size;
  MIOS32_IRQ_Enable();

  return 0; // no error
}
Example #24
0
/////////////////////////////////////////////////////////////////////////////
// called whenever record variables should be reseted (e.g. on track restart)
/////////////////////////////////////////////////////////////////////////////
s32 SEQ_RECORD_Reset(u8 track)
{
  // exit if track number too high
  if( track >= SEQ_CORE_NUM_TRACKS )
    return -1; // unsupported track

  seq_core_trk_t *t = &seq_core_trk[track];

  // init track specific variables
  MIOS32_IRQ_Disable();
  t->state.REC_DONT_OVERWRITE_NEXT_STEP = 0;
  t->rec_timestamp = 0;
  t->rec_poly_ctr = 0;
  MIOS32_IRQ_Enable();

  return 0; // no error
}
/////////////////////////////////////////////////////////////////////////////
//! Returns the DIN pin toggle notifications after a SRIO scan. Should be used 
//! to check and clear these flags when processed by a DIN handler for exclusive
//! access (avoid propagation of already handled DIN pin changes)
//!
//! Examples:<BR>
//! 1) if a scan matrix handler processes the DIN pins of the first SR,
//! it should call
//! \code
//!   changed = MIOS32_DIN_SRChangedGetAndClear(0, 0xff)
//! \endcode
//! to get a notification, if (and which) pins have toggled during the last scan.
//! The flags will be cleared, so that the remaining handlers won't process
//! the pins of the first DIN register anymore.
//!
//! 2) it's also possible, to check and clear only dedicated pins of the DIN
//!    register by applying a different pin mask. E.g.
//! \code
//!   changed = MIOS32_DIN_SRChangedGetAndClear(0, 0xc0)
//! \endcode
//!    will only check/clear D6 and D7 of the DIN register, the remaining
//!    toggle notifications won't be touched and will be forwarded to remaining 
//!    handlers
//! \param[in] sr shift register number (0..15)
//! \param[in] mask pin mask (8bit value)
//! \return 8bit value which contains the selected (masked) change flags
//! \return no error status (-1)! - if unavailable SR selected, 0x00 will be returned
/////////////////////////////////////////////////////////////////////////////
u8 MIOS32_DIN_SRChangedGetAndClear(u32 sr, u8 mask)
{
  u8 num_sr = MIOS32_SRIO_ScanNumGet();
  u8 changed;

  // check if SR available
  if( sr >= num_sr )
    return 0x00;

  // get and clear changed flags - must be atomic!
  MIOS32_IRQ_Disable();
  changed = mios32_srio_din_changed[sr] & mask;
  mios32_srio_din_changed[sr] &= ~mask;
  MIOS32_IRQ_Enable();

  return changed;
}
Example #26
0
/////////////////////////////////////////////////////////////////////////////
// For Section Changes
// If velocity == 0, Note Off event has been received, otherwise Note On event
/////////////////////////////////////////////////////////////////////////////
static s32 SEQ_MIDI_IN_Receive_NoteSC(u8 note, u8 velocity)
{
  int octave = note / 12;
  int octave_taken = 0;

  int group;
  for(group=0; group<4; ++group) {
    if( octave == (seq_midi_in_sect_note[group] / 12) ) {
      octave_taken = 1;
      notestack_t *n = &section_changer_notestack[group];

      int section = -1;
      if( velocity ) { // Note On
	NOTESTACK_Push(n, note, velocity);
	section = n->note_items[0].note % 12;
      } else { // Note Off
	if( NOTESTACK_Pop(n, note) > 0 && n->len ) {
	  section = n->note_items[0].note % 12;
	}
      }

      // switch to new section if required
      if( section >= 0 && section < 12 ) {
#if DEBUG_VERBOSE_LEVEL >= 1
	DEBUG_MSG("Group %d Section %d\n", group, section);
#endif

	// following operation should be atomic!
	u8 track;
	seq_core_trk_t *t = &seq_core_trk[group*SEQ_CORE_NUM_TRACKS_PER_GROUP];
	MIOS32_IRQ_Disable();
	for(track=0; track<SEQ_CORE_NUM_TRACKS_PER_GROUP; ++track, ++t)
	  t->play_section = section;
	MIOS32_IRQ_Enable();
      }

#if DEBUG_VERBOSE_LEVEL >= 1
      DEBUG_MSG("NOTESTACK_SECTION_CHANGER_G%d:\n", group+1);
      NOTESTACK_SendDebugMessage(n);
#endif
    }
  }

  return octave_taken; // return 1 if octave has been taken, otherwise 0
}
/////////////////////////////////////////////////////////////////////////////
//! This function should be called from a task to check for button changes
//! periodically. Events (change from 0->1 or from 1->0) will be notified 
//! via the given callback function <notify_hook> with following parameters:
//!   <notifcation-hook>(s32 pin, s32 value)
//! \return < 0 on errors
/////////////////////////////////////////////////////////////////////////////
s32 BLM_CHEAPO_ButtonHandler(void *_notify_hook)
{
  void (*notify_hook)(u32 pin, u32 value) = _notify_hook;

  // no hook?
  if( _notify_hook == NULL )
    return -2;

  int row;
  for(row=0; row<NUM_ROWS; ++row) {
    
    // check if there are pin changes - must be atomic!
    MIOS32_IRQ_Disable();
    u8 changed = button_row_changed[row];
    button_row_changed[row] = 0;
    MIOS32_IRQ_Enable();

    // any pin change at this SR?
    if( !changed )
      continue;

    // check all 8 pins of the SR
    int pin;
    u8 mask = (1 << 0);
    for(pin=0; pin<8; ++pin, mask <<= 1)
      if( changed & mask ) {
	u8 pin_value = (button_row[row] & (1 << pin)) ? 1 : 0;
#if BLM_CHEAPO_RIGHT_HALF_REVERSED
	// reverse pins for right half (layout measure)
	u8 blm_pin = pin;
	if( row >= 4 ) {
	  blm_pin = 7 - pin;
	}
#endif

#if 0
	MIOS32_MIDI_SendDebugMessage("[BLM_CHEAPO] Row:%d  Pin:%d  Value:%d\n", row, blm_pin, pin_value);
#endif
	notify_hook(8*row + blm_pin, pin_value);
      }
  }

  return 0; // no error
}
Example #28
0
/////////////////////////////////////////////////////////////////////////////
//! Updates the output channels of all DPOT channels
//! Should be called, whenever changes have been requested via 
//! DPOT_Set_Value()
//! \return < 0 on errors
/////////////////////////////////////////////////////////////////////////////
s32 DPOT_Update(void)
{
    s32 status = 0;
    u32 req = 0;
  
    // check for DPOT channel update requests
    MIOS32_IRQ_Disable();
    req = dpot_update_req;
    dpot_update_req = 0;
    MIOS32_IRQ_Enable();

    // update hardware
    if (req)
    {
        status = DPOT_Device_Update(req);
    }

    return status;
}
/////////////////////////////////////////////////////////////////////////////
//! returns the next byte of the receive buffer without taking it
//! \param[in] uart UART number (0..2)
//! \return -1 if UART not available
//! \return -2 if no new byte available
//! \return >= 0: number of received bytes
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
/////////////////////////////////////////////////////////////////////////////
s32 MIOS32_UART_RxBufferPeek(u8 uart)
{
#if MIOS32_UART_NUM == 0
  return -1; // no UART available
#else
  if( uart >= MIOS32_UART_NUM )
    return -1; // UART not available

  if( !rx_buffer_size[uart] )
    return -2; // nothing new in buffer

  // get byte - this operation should be atomic!
  MIOS32_IRQ_Disable();
  u8 b = rx_buffer[uart][rx_buffer_tail[uart]];
  MIOS32_IRQ_Enable();

  return b; // return received byte
#endif
}
Example #30
0
/////////////////////////////////////////////////////////////////////////////
// This function should be called from Tick() in main.c
// it updates the LEDring patterns for which an update has been requested
/////////////////////////////////////////////////////////////////////////////
s32 LC_VPOT_LEDRing_CheckUpdates(void)
{
  u8 ledring;
  u8 ledring_select;
  u8 value;
  u8 center_led;

  for(ledring=0, ledring_select=0x01; ledring<8; ++ledring) {

    // check if update has been requested
    if( ledring_update_req & ledring_select ) {
      MIOS32_IRQ_Disable();
      ledring_update_req &= ~ledring_select; // clear request flag
      MIOS32_IRQ_Enable();
      
      // branch depending on mode
      if( lc_flags.GPC_SEL ) {
	value = LC_GPC_VPotValueGet(ledring);
	ledring_pattern[ledring] = preset_patterns_gpc[value >> 2];
      } else {