int8_t timer_realtime_start(uint16_t value, uint16_t interval, timer_callback_t f) { uint8_t i; HAS_CRITICAL_SECTION; ENTER_CRITICAL_SECTION(); if( num_realtime_clock == MAX_REALTIME_CLOCK ) { LEAVE_CRITICAL_SECTION(); return -ENOMEM; } for( i = 0; i < MAX_REALTIME_CLOCK; i++ ) { if( realtime[i].f == NULL ) { timer_realtime_set_hw_top(value); num_realtime_clock++; realtime[i].value = value; realtime[i].interval = interval; realtime[i].f = f; LEAVE_CRITICAL_SECTION(); return SOS_OK; } } LEAVE_CRITICAL_SECTION(); return -ENOMEM; }
LRESULT CMainFrame::OnListItemChanged(LPNMHDR lpNMHDR) { return 0; NMLISTVIEW *pNMLV = (NMLISTVIEW *)lpNMHDR; ENTER_CRITICAL_SECTION(&m_csThreadRefreshStatus); if(0 == (pNMLV->uChanged & LVIF_STATE)) { LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return 0; } if(pNMLV->uNewState & LVIS_SELECTED) { ATLTRACE(_T("OnListItemChanged %d, LV : %d, TV : %d\n"), pNMLV->lParam, m_viewList.GetSelectedItemData(), m_viewTree.GetSelectedItemData()); if(m_viewTree.GetSelectedItemData() != pNMLV->lParam) { m_viewTree.SelectItemWithData(pNMLV->lParam); RefreshAction(); } } LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return 0; }
LRESULT CMainFrame::OnTreeSelChanged(LPNMHDR lpNLHDR) { return 0; ENTER_CRITICAL_SECTION(&m_csThreadRefreshStatus); if(!lpNLHDR) { LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return 0; } NMTREEVIEW *pNMTV = (NMTREEVIEW *)lpNLHDR; ATLTRACE(_T("OnTreeSelChanged %d, LV : %d, TV : %d\n"), pNMTV->itemNew.lParam, m_viewList.GetSelectedItemData(), m_viewTree.GetSelectedItemData()); if(pNMTV->itemNew.lParam != m_viewList.GetSelectedItemData()) { m_viewList.SelectDiskObject(m_mapObject[pNMTV->itemNew.lParam]); RefreshAction(); } LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return 0; }
void CMainFrame::OnCommand(UINT /*wNotifyCode*/, int wID, HWND /*hwndCtl*/) { ENTER_CRITICAL_SECTION(&m_csThreadRefreshStatus); // Commands which do not change the tree are sent to the object directly. CTreeItem itemSelected = m_view.GetSelectedItem(); if ( itemSelected.IsNull() ) { LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return; } CDiskObjectPtr obj; const CObjectUIHandler *phandler; obj = m_mapObject[m_view.GetItemData(itemSelected)]; ATLASSERT( obj.get() != NULL ); phandler = CObjectUIHandler::GetUIHandler( obj ); phandler->OnCommand( obj, wID ); m_view.UpdateDiskObject( obj ); OnSelChanged(NULL); LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); }
/** * @brief get message that matches the header in the queue * * NOTE it matches only daddr, saddr, did, sid, type * NOTE it only gets the first that matches the description */ Message *mq_get(mq_t *q, Message *m) { HAS_CRITICAL_SECTION; Message *ret; #ifdef SOS_USE_PREEMPTION if(q->head == NULL) return NULL; ENTER_CRITICAL_SECTION(); // Search the queue ret = mq_real_get(&(q->head), m); #else if(q->msg_cnt == 0) return NULL; ENTER_CRITICAL_SECTION(); //! first search high priority queue ret = mq_real_get(&(q->hq_head), &(q->hq_tail), m); if(ret) { q->msg_cnt--; LEAVE_CRITICAL_SECTION(); return ret; } //! search low priority queue ret = mq_real_get(&(q->lq_head), &(q->lq_tail), m); if(ret) { q->msg_cnt--; } #endif LEAVE_CRITICAL_SECTION(); return ret; }
sp_pid_t sp_create( task_t task, uint8_t priority ) { sp_pid_t i; HAS_CRITICAL_SECTION; ENTER_CRITICAL_SECTION(); // Search for empty slot for( i = 0; i < SPK_MAX_TASKS; i++ ) { // Found an empty slot if( spk_tasks[i].task == NULL ) { spk_tasks[i].lc = 0; // The pid field is not being used spk_tasks[i].status = TASK_WAITING; spk_tasks[i].priority = priority; spk_tasks[i].errno = 0; spk_tasks[i].task = task; spk_tasks[i].wait_obj = NULL; spk_tasks[i].next = NULL; LEAVE_CRITICAL_SECTION(); sp_signal( i ); return i; } } // All slots taken LEAVE_CRITICAL_SECTION(); SP_EXCEPTION(); return 0; }
/////////////////////////////////////////////////////////////////////////////// // // Implementation of command handling methods // /////////////////////////////////////////////////////////////////////////////// void CMainFrame::OnBind(UINT /*wNotifyCode*/, int /*wID*/, HWND /*hwndCtl*/) { ENTER_CRITICAL_SECTION(&m_csThreadRefreshStatus); CDiskObjectList singleDisks; CFindIfVisitor<FALSE> singleDiskFinder; WTL::CString strMsg; singleDisks = singleDiskFinder.FindIf(m_pRoot, IsWritableUnitDisk); nbbwiz::CWizard dlgBindWizard; dlgBindWizard.SetSingleDisks(singleDisks); if ( dlgBindWizard.DoModal() == IDOK ) { // AING : Cause dlgBind use ndasop.lib to bind disks, // you can't ensure each disk information is stable after bind process. OnRefreshStatus(NULL, NULL, NULL); } LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return; CBindSheet dlgBind; dlgBind.SetSingleDisks(singleDisks); if ( dlgBind.DoModal() == IDOK ) { // AING : Cause dlgBind use ndasop.lib to bind disks, // you can't ensure each disk information is stable after bind process. OnRefreshStatus(NULL, NULL, NULL); } LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); }
/** * @brief dequeue message * @return pointer to message, or NULL for empty queue * First we check high priority queue. * if it is empty, we check for low priority queue */ Message *mq_dequeue(mq_t *q) { HAS_CRITICAL_SECTION; Message *tmp = NULL; ENTER_CRITICAL_SECTION(); #ifdef SOS_USE_PREEMPTION if((tmp = q->head) != NULL) { q->head = tmp->next; q->msg_cnt--; } LEAVE_CRITICAL_SECTION(); #else if ((tmp = q->hq_head) != NULL) { //! high priority message q->hq_head = tmp->next; q->hm_cnt--; //! system msgs } else if ((tmp = q->sq_head) != NULL) { q->sq_head = tmp->next; q->sm_cnt--; } else if ((tmp = q->lq_head) != NULL) { //! low priority message q->lq_head = tmp->next; q->lm_cnt--; } else { LEAVE_CRITICAL_SECTION(); return NULL; } q->msg_cnt--; #endif LEAVE_CRITICAL_SECTION(); return tmp; }
void CMainFrame::OnUnBind(UINT /*wNotifyCode*/, int /*wID*/, HWND /*hwndCtl*/) { ENTER_CRITICAL_SECTION(&m_csThreadRefreshStatus); CTreeItem itemSelected = m_view.GetSelectedItem(); if ( itemSelected.IsNull() ) { LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return; } CDiskObjectPtr obj, parent; obj = m_mapObject[m_view.GetItemData(itemSelected)]; // Find topmost group composite of bind parent = obj->GetParent(); while ( !parent->IsRoot() ) { obj = parent; parent = obj->GetParent(); } // // Check whether any disk is being accessed by other program/computer // if ( !obj->CanAccessExclusive() ) { LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); WTL::CString strMsg; strMsg.LoadString(IDS_FAIL_TO_ACCESS_EXCLUSIVELY); WTL::CString strTitle; strTitle.LoadString(IDS_APPLICATION); MessageBox( strMsg, strTitle, MB_OK | MB_ICONWARNING ); return; } // Unbind disks CUnBindDlg dlgUnbind; dlgUnbind.SetDiskToUnbind(obj); if ( dlgUnbind.DoModal() == IDOK ) { // AING : Cause dlgBind use ndasop.lib to bind disks, // you can't ensure each disk information is stable after bind process. OnRefreshStatus(NULL, NULL, NULL); } LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); }
void sp_signal_error( sp_pid_t pid, uint8_t err ) { HAS_CRITICAL_SECTION; ENTER_CRITICAL_SECTION(); if( spk_tasks[pid].status != TASK_WAITING ) { LEAVE_CRITICAL_SECTION(); return; } spk_tasks[pid].errno = err; LEAVE_CRITICAL_SECTION(); sp_signal( pid ); }
// Returns amount of time key (specified by "code") has been down since last call. // Returns float, unlike key_down_time() which returns a fix. float key_down_timef(uint scancode) { uint time_down, time; uint delta_time; if (!key_inited) { return 0.0f; } if (scancode >= NUM_KEYS) { return 0.0f; } ENTER_CRITICAL_SECTION(key_lock); time = timer_get_milliseconds(); delta_time = time - key_data.TimeKeyDownChecked[scancode]; key_data.TimeKeyDownChecked[scancode] = time; if (delta_time <= 1) { key_data.TimeKeyWentDown[scancode] = time; if (keyd_pressed[scancode]) { LEAVE_CRITICAL_SECTION(key_lock); return 1.0f; } else { LEAVE_CRITICAL_SECTION(key_lock); return 0.0f; } } if (!keyd_pressed[scancode]) { time_down = key_data.TimeKeyHeldDown[scancode]; key_data.TimeKeyHeldDown[scancode] = 0; } else { time_down = time - key_data.TimeKeyWentDown[scancode]; key_data.TimeKeyWentDown[scancode] = time; } LEAVE_CRITICAL_SECTION(key_lock); return i2fl(time_down) / i2fl(delta_time); }
int8_t os_semaphore_wait(t_os_semaphore *semaphore) { ENTER_CRITICAL_SECTION(); if (semaphore->count > 0) { semaphore->count--; LEAVE_CRITICAL_SECTION(); return 0; } uint8_t pid = os_get_current_pid(); semaphore->wait_list[pid] = 1; pcb[pid].semaphore_blocked = 1; LEAVE_CRITICAL_SECTION(); os_switch_processes(); return 0; }
/************************************************************************* * will be called by post_net, etc functions to send message * *************************************************************************/ void radio_msg_alloc(Message *msg) { HAS_CRITICAL_SECTION; uint16_t sleeptime = 0; uint8_t resend_pack = 1; ENTER_CRITICAL_SECTION(); if( Radio_Check_CCA() ) { incSeq(); if(radio_msg_send(msg)) { resend_pack = 0; msg_send_senddone(msg, 1, RADIO_PID); } } if(resend_pack) { if( getMsgNumOfQueue() < MAX_MSGS_IN_QUEUE ) //queue is full? { mq_enqueue(&vmac_pq, msg); ENTER_CRITICAL_SECTION(); // most probably mq_enqueue calls LEAVE_CRITICAL_SECTION somewhere! } else { msg_send_senddone(msg, 0, RADIO_PID); //release the memory for the msg ENTER_CRITICAL_SECTION(); // most probably msg_send_senddone calls LEAVE_CRITICAL_SECTION somewhere! } sleeptime = MacBackoff_congestionBackoff(retry_count); ker_timer_restart(RADIO_PID, WAKEUP_TIMER_TID, sleeptime); // setup backoff timer } LEAVE_CRITICAL_SECTION(); }
LRESULT CMainFrame::OnToolBarDropDown(LPNMHDR lpNMHDR) { ENTER_CRITICAL_SECTION(&m_csThreadRefreshStatus); NMTOOLBAR* pnmtb = reinterpret_cast<NMTOOLBAR*>(lpNMHDR); switch(pnmtb->iItem) { case IDM_AGGR_MIRROR: { // Display dropdown menu CMenu menu; CMenuHandle subMenu; CRect rect; m_wndToolBar.GetRect( pnmtb->iItem, rect ); m_wndToolBar.ClientToScreen( rect ); menu.LoadMenu( MAKEINTRESOURCE(IDR_MIRROR_MENU) ); subMenu = menu.GetSubMenu(0); subMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_VERTICAL, rect.left, rect.bottom, m_hWnd ); } default: break; } LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return 0; }
// Set global shift_status with modifier results (shift, ctrl, alt). uint key_get_shift_status() { unsigned int shift_status = 0; if ( !key_inited ) return 0; ENTER_CRITICAL_SECTION( key_lock ); if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) shift_status |= KEY_SHIFTED; if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) shift_status |= KEY_ALTED; if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) shift_status |= KEY_CTRLED; #ifndef NDEBUG if (keyd_pressed[KEY_DEBUG_KEY]) shift_status |= KEY_DEBUGGED; #else if (keyd_pressed[KEY_DEBUG_KEY]) { mprintf(("Cheats_enabled = %i, Key_normal_game = %i\n", Cheats_enabled, Key_normal_game)); if ((Cheats_enabled) && Key_normal_game) { mprintf(("Debug key\n")); shift_status |= KEY_DEBUGGED1; } } #endif LEAVE_CRITICAL_SECTION( key_lock ); return shift_status; }
/** * @brief timer hardware routine */ void timer_hardware_init(uint8_t interval, uint8_t scale){ HAS_CRITICAL_SECTION; ENTER_CRITICAL_SECTION(); scale &= 0x7; scale |= (1<<WGM1); // reset on match TIMSK &= ((unsigned char)~(1 << (TOIE0))); TIMSK &= ((unsigned char)~(1 << (OCIE0))); //!< Disable TC0 interrupt /** * set Timer/Counter0 to be asynchronous * from the CPU clock with a second external * clock(32,768kHz)driving it */ ASSR |= (1 << (AS0)); //!< us external oscillator TCCR0 = scale; TCNT0 = 0; OCR0 = interval; //TIMSK |= (1 << (OCIE0)); replaced by the line below timer_enable_interrupt(); LEAVE_CRITICAL_SECTION(); timer_init(); }
/** * Write a block of data into flash (block size is 64 bytes) * Note: this routine has to be in the RAM. */ static void __attribute__ ((section(".data"))) flash_write_block( uint32_t addr, uint8_t* buf, uint16_t len ) { HAS_CRITICAL_SECTION; register uint16_t i; register uint16_t* d = (uint16_t*) ((uint16_t)addr); register uint16_t* b = (uint16_t*) buf; ENTER_CRITICAL_SECTION(); while( FCTL3 & BUSY ); FCTL2 = FWKEY + FSSEL1 + FN2; // SMCLK / 5 FCTL3 = FWKEY; // Clear LOCK FCTL1 = FWKEY + BLKWRT + WRT; // Enable block write for( i = 0; i < 32; i++ ) { *d = *b; d++; b++; while( (FCTL3 & WAIT) == 0); } FCTL1 = FWKEY; // Clear WRT and BLKWRT while( FCTL3 & BUSY ); // Test Busy FCTL3 = FWKEY + LOCK; // Set LOCK LEAVE_CRITICAL_SECTION(); }
void mouse_init() { // Initialize queue if ( mouse_inited ) return; mouse_inited = 1; InitializeCriticalSection( &mouse_lock ); ENTER_CRITICAL_SECTION(&mouse_lock); mouse_flags = 0; Mouse_x = gr_screen.max_w / 2; Mouse_y = gr_screen.max_h / 2; #ifdef USE_DIRECTINPUT if (!di_init()) Mouse_mode = MOUSE_MODE_WIN; #else Mouse_mode = MOUSE_MODE_WIN; #endif LEAVE_CRITICAL_SECTION(&mouse_lock); atexit( mouse_close ); }
int SafeRealloc(void **Memory_ptr, size_t NewBytes) { void *New; #ifdef WIN32 ENTER_CRITICAL_SECTION(AllocCS); #else LOCK_SPIN(AllocSpin); #endif /* WIN32 */ New = realloc(*Memory_ptr, NewBytes); #ifdef WIN32 LEAVE_CRITICAL_SECTION(AllocCS); #else UNLOCK_SPIN(AllocSpin); #endif /* WIN32 */ if(New != NULL) { *Memory_ptr = New; return 0; } else { return -1; } }
// Destroy BOOL AudioStream::Destroy(void) { BOOL fRtn = SUCCESS; ENTER_CRITICAL_SECTION(write_lock); // Stop playback Stop(); // Release DirectSound buffer if (m_pdsb) { m_pdsb->Release(); m_pdsb = NULL; Snd_sram -= m_cbBufSize; } // Delete WaveFile object if (m_pwavefile) { m_pwavefile->Close(); vm_free(m_pwavefile); m_pwavefile = NULL; } status = ASF_FREE; LEAVE_CRITICAL_SECTION(write_lock); return fRtn; }
/** * Timer initialization */ void timer_init(uint8_t interval, uint8_t scale) { HAS_CRITICAL_SECTION; ENTER_CRITICAL_SECTION(); scale &= 0x7; scale |= 0x8; cbi(TIMSK, TOIE0); cbi(TIMSK, OCIE0); //!< Disable TC0 interrupt /** * set Timer/Counter0 to be asynchronous * from the CPU clock with a second external * clock(32,768kHz)driving it */ sbi(ASSR, AS0); outp(scale, TCCR0); //!< prescale the timer to be clock/128 to make it outp(0, TCNT0); outp(interval, OCR0); sbi(TIMSK, OCIE0); LEAVE_CRITICAL_SECTION(); }
// mouse_up_count() returns the number of times button n has gone from down to up // since the last call // // parameters: n - button of mouse (see #define's in mouse.h) // int mouse_up_count(int n) { int tmp = 0; if ( !mouse_inited ) return 0; if ( (n < LOWEST_MOUSE_BUTTON) || (n > HIGHEST_MOUSE_BUTTON)) return 0; ENTER_CRITICAL_SECTION( mouse_lock ); switch (n) { case MOUSE_LEFT_BUTTON: tmp = mouse_left_up; mouse_left_up = 0; break; case MOUSE_RIGHT_BUTTON: tmp = mouse_right_up; mouse_right_up = 0; break; case MOUSE_MIDDLE_BUTTON: tmp = mouse_middle_up; mouse_middle_up = 0; break; default: Assert(0); // can't happen break; } // end switch LEAVE_CRITICAL_SECTION( mouse_lock ); return tmp; }
/** * Send data over the spi */ int8_t ker_spi_send_data( uint8_t *msg, uint8_t msg_size, uint8_t calling_id) { HAS_CRITICAL_SECTION; if (s.state == SPI_SYS_IDLE) { return -EINVAL; } if ((s.calling_mod_id != calling_id) || ((s.state != SPI_SYS_WAIT) && (s.state != SPI_SYS_DMA_WAIT))) { return -EBUSY; } // ensure calling app gave us a message if (NULL != msg) { s.usrBuf = s.bufPtr = msg; } else { return -EINVAL; } // need to assert CS pin if (s.flags & SPI_SYS_CS_HIGH_FLAG) { spi_cs_high(s.addr); } else { spi_cs_low(s.addr); } ENTER_CRITICAL_SECTION(); s.len = msg_size; s.state = SPI_SYS_TX; LEAVE_CRITICAL_SECTION(); UART_DBG(a, 0x22, s.calling_mod_id, 0x01, 0x02, SPI_PID); return spi_masterTxData(s.bufPtr, s.len, s.flags); }
/** * @brief update delta queue * traverse each item in the queue until no more delta left * NOTE: this is executed in interrupt handler, so NO lock necessary */ static void timer_update_delta(void) { list_link_t *link; int32_t delta; HAS_CRITICAL_SECTION; ENTER_CRITICAL_SECTION(); delta = outstanding_ticks; outstanding_ticks = 0; LEAVE_CRITICAL_SECTION(); if(list_empty(&deltaq) == true) { return; } DEBUG("update delta = %d\n", delta); for(link = deltaq.l_next; link != (&deltaq); link = link->l_next) { sos_timer_t *h = (sos_timer_t*)link; if(h->delta >= delta) { // if we use all ticks... h->delta -= delta; return; } else { int32_t tmp = h->delta; h->delta -= delta; delta -= tmp; } } }
// Flush the keyboard buffer. // Clear the keyboard array (keyd_pressed). void key_flush() { int i; uint CurTime; if ( !key_inited ) return; ENTER_CRITICAL_SECTION( key_lock ); key_data.keyhead = key_data.keytail = 0; //Clear the keyboard buffer for (i=0; i<KEY_BUFFER_SIZE; i++ ) { key_data.keybuffer[i] = 0; key_data.time_pressed[i] = 0; } //Clear the keyboard array CurTime = timer_get_milliseconds(); for (i=0; i<NUM_KEYS; i++ ) { keyd_pressed[i] = 0; key_data.TimeKeyDownChecked[i] = CurTime; key_data.TimeKeyWentDown[i] = CurTime; key_data.TimeKeyHeldDown[i] = 0; key_data.NumDowns[i]=0; key_data.NumUps[i]=0; } LEAVE_CRITICAL_SECTION( key_lock ); }
int8_t timer_realtime_stop(timer_callback_t f) { uint8_t i; HAS_CRITICAL_SECTION; ENTER_CRITICAL_SECTION(); for( i = 0; i < MAX_REALTIME_CLOCK; i++ ) { if( realtime[i].f == f ) { realtime[i].f = NULL; num_realtime_clock--; LEAVE_CRITICAL_SECTION(); return SOS_OK; } } LEAVE_CRITICAL_SECTION(); return -EINVAL; }
void sp_wait( void ) { HAS_CRITICAL_SECTION; ENTER_CRITICAL_SECTION(); CURRENT_TASK()->errno = 0; CURRENT_TASK()->status = TASK_WAITING; LEAVE_CRITICAL_SECTION(); }
void ker_pop_current_pid() { HAS_CRITICAL_SECTION; ENTER_CRITICAL_SECTION(); pid_sp--; ker_set_current_pid(*pid_sp); LEAVE_CRITICAL_SECTION(); return; }
// change in mouse position since last call void mouse_eval_deltas() { static int old_x = 0; static int old_y = 0; int tmp_x, tmp_y, cx, cy; Mouse_dx = Mouse_dy = Mouse_dz = 0; if (!mouse_inited) return; #ifdef WIN32 if (Mouse_mode == MOUSE_MODE_DI) { mouse_eval_deltas_di(); return; } #endif cx = gr_screen.max_w / 2; cy = gr_screen.max_h / 2; ENTER_CRITICAL_SECTION( mouse_lock ); POINT pnt; getWindowMousePos(&pnt); tmp_x = pnt.x; tmp_y = pnt.y; Mouse_dx = tmp_x - old_x; Mouse_dy = tmp_y - old_y; Mouse_dz = 0; // Speeds up the menu mouse on higher resolutions. The check for a // visible mouse should eliminate any possible gameplay changes. if ( mouse_is_visible() ) { gr_resize_screen_pos( &Mouse_dx, &Mouse_dy ); } if (Keep_mouse_centered && Mouse_hidden) { if (Mouse_dx || Mouse_dy) mouse_force_pos(cx, cy); old_x = cx; old_y = cy; } else { old_x = tmp_x; old_y = tmp_y; } LEAVE_CRITICAL_SECTION( mouse_lock ); //WMC - For On Mouse Moved trigger if(Mouse_dx != 0 || Mouse_dy != 0) { Script_system.RunCondition(CHA_MOUSEMOVED); } }
/** * Read data from the spi */ int8_t ker_spi_read_data( uint8_t *sharedBuf, uint8_t rx_len, uint8_t rx_cnt, uint8_t calling_id) { HAS_CRITICAL_SECTION; if (s.state == SPI_SYS_IDLE) { // not reserved return -EINVAL; } if ((s.calling_mod_id != calling_id) || ((s.state != SPI_SYS_WAIT) && (s.state != SPI_SYS_DMA_WAIT) && (s.state != SPI_SYS_RX_WAIT))) { return -EBUSY; } // get a handle to users buffer if (rx_len >= MAX_SPI_READ_LEN) { return -EINVAL; } else { s.len = rx_len; } // need to assert CS pin if (s.flags & SPI_SYS_CS_HIGH_FLAG) { spi_cs_high(s.addr); } else { spi_cs_low(s.addr); } // only get/malloc a buffer if we are not currently in a DMA sequence if ((s.flags & SPI_SYS_SHARED_MEM_FLAG)) { if (NULL == sharedBuf) { return -EINVAL; } else { s.cnt = rx_cnt; s.bufPtr = sharedBuf; if (!(s.state == SPI_SYS_DMA_WAIT)) { s.usrBuf = sharedBuf; } } } else { // ignore value of sharedBuf if (NULL == (s.bufPtr = s.usrBuf = ker_malloc(s.len, SPI_PID))) { return -ENOMEM; } else { s.cnt = 1; } } ENTER_CRITICAL_SECTION(); s.state = SPI_SYS_RX; LEAVE_CRITICAL_SECTION(); return spi_masterRxData(s.usrBuf, s.len, s.flags); }