/*! * \brief Display a specified status. * * \param status Status to be displayed. */ void DisplayStatus(u_char status) { RADIOSTATION *rsp = &station[radio.rc_cstation]; if (radio.rc_cstatus != status) { if (status == DIST_FORCE) status = radio.rc_cstatus; else radio.rc_cstatus = status; if (status == DIST_NONE) { strcpy(sline[0], "NutPiper"); strcpy(sline[1], "Version 1.0"); NutEventPost(&updevt); } else if (status == DIST_DEAD) { sprintf(sline[0], "Station %03u", radio.rc_cstation); strcpy(sline[1], "not available"); NutEventPost(&updevt); } else if (status == DIST_CONNECTING) { DisplayStation(rsp); strcpy(sline[1], "Connecting..."); NutEventPost(&updevt); } else if (status == DIST_CONNECTED) { DisplayStation(rsp); if (player.psi_metatitle && player.psi_metatitle[0]) strncpy(sline[1], player.psi_metatitle, DISPLAY_VCOLUMNS); else if (rsp->rs_genre && rsp->rs_genre[0]) strncpy(sline[1], rsp->rs_genre, DISPLAY_VCOLUMNS); NutEventPost(&updevt); } } }
/*! * \brief Initialize TWI interface bus. * * The specified slave address is not used here as we don't support twi-slave * on the bitbanging interface * * \param sla Slave address, must be specified as a 7-bit address, * always lower than 128. */ int NutRegisterTwiBus( NUTTWIBUS *bus, uint8_t sla ) { int rc = 0; NUTTWIICB *icb = NULL; /* Check if bus was already registered */ if( bus->bus_icb) { return 0; } /* Allocate ICB for this bus */ icb = NutHeapAlloc(sizeof(NUTTWIICB)); if( icb == NULL) { return rc; } memset( icb, 0, sizeof(NUTTWIICB)); /* Link bus and ICB */ bus->bus_icb = icb; /* Initialize interface hardware */ if (bus->bus_initbus) { rc = bus->bus_initbus(); } /* Initialize mutex semaphores. */ NutEventPost(&bus->bus_mutex); return rc; }
/*! * \brief Read or verify a single block. * * \param ifc Specifies the hardware interface. * \param blk Block number to read or verify. * \param buf Data buffer. Receives the data or is verified against the * data being read from the card. * * \return 0 on success, -1 otherwise. */ static int At91MciReadSingle(MCIFC * ifc, u_long blk, u_char * buf) { int rc = -1; u_int sr; /* Gain mutex access. */ NutEventWait(&mutex, 0); #ifdef NUTDEBUG printf("[RB%lu]", blk); #endif sr = At91MciTxCmd(ifc, MCI_MAXLAT | MCI_RSPTYP_48 | MMCMD_SELECT_CARD, ifc->ifc_reladdr << 16); if ((sr & 0xC07F0000) == 0) { sr = At91MciTxCmd(ifc, MCI_MAXLAT | MCI_RSPTYP_48 | MMCMD_SET_BLOCKLEN, MMC_BLOCK_SIZE); if ((sr & 0xC07F0000) == 0) { ifc->ifc_buff = buf; sr = At91MciTxCmd(ifc, MCI_TRDIR | MCI_TRCMD_START | MCI_MAXLAT | MCI_RSPTYP_48 | MMCMD_READ_SINGLE_BLOCK, blk * MMC_BLOCK_SIZE); if ((sr & 0xC07F0000) == 0) { rc = 0; } } At91MciTxCmd(ifc, MMCMD_SELECT_CARD, 0); } /* Release mutex access. */ NutEventPost(&mutex); return rc; }
/*! * \brief Initialize TWI interface. * * The specified slave address is used only, if the local system * is running as a slave. Anyway, care must be taken that it doesn't * conflict with another connected device. * * \note This function is only available on ATmega128 systems. * * \param sla Slave address, must be specified as a 7-bit address, * always lower than 128. */ int TwInit(u_char sla) { #ifndef __AVR_ENHANCED__ return -1; #else u_long speed = 2400; if (NutRegisterIrqHandler(&sig_2WIRE_SERIAL, TwInterrupt, 0)) { return -1; } /* * Set address register, enable general call address, set transfer * speed and enable interface. */ outb(TWAR, (sla << 1) | 1); TwIOCtl(TWI_SETSPEED, &speed); outb(TWCR, _BV(TWINT)); outb(TWCR, _BV(TWEN) | _BV(TWIE)); /* * Initialize mutex semaphores. */ NutEventPost(&tw_mm_mutex); return 0; #endif /* __AVR_ENHANCED__ */ }
/*! * \brief Unlock a sempahore. * * \note: Should not be called from interrupt context */ void NutSemPost(SEM * sem) { sem->value++; if (sem->value <= 0) { NutEventPost(&sem->qhp); } }
/*! * \brief Send Ethernet packet. * * \param dev Identifies the device to use. * \param nb Network buffer structure containing the packet to be sent. * The structure must have been allocated by a previous * call NutNetBufAlloc(). * * \return 0 on success, -1 in case of any errors. */ int LancOutput(NUTDEVICE * dev, NETBUF * nb) { static uint32_t mx_wait = 5000; int rc = -1; lanc111_nic_t *ni; /* * After initialization we are waiting for a long time to give * the PHY a chance to establish an Ethernet link. */ if (NutEventWait(&nic->ni_tx_rdy, mx_wait) == 0) { ni = (lanc111_nic_t *) dev->dev_dcb; if (NicPutPacket(nb) == 0) { ni->ni_tx_packets++; rc = 0; /* Ethernet works. Set a long waiting time in case we temporarly lose the link next time. */ mx_wait = 5000; } NutEventPost(&nic->ni_tx_rdy); } /* * Probably no Ethernet link. Significantly reduce the waiting * time, so following transmission will soon return an error. */ else { mx_wait = 500; } return rc; }
/*! \brief Select a device on the first SPI bus. * * Locks and activates the bus for the specified node. * * \param node Specifies the SPI bus node. * \param tmo Timeout in milliseconds. To disable timeout, set this * parameter to NUT_WAIT_INFINITE. * * \return 0 on success. In case of an error, -1 is returned and the bus * is not locked. */ int NplSpiBusSelect(NUTSPINODE * node, uint32_t tmo) { int rc; /* Sanity check. */ NUTASSERT(node != NULL); NUTASSERT(node->node_bus != NULL); /* Allocate the bus. */ rc = NutEventWait(&node->node_bus->bus_mutex, tmo); if (rc) { errno = EIO; } else { /* If the mode update bit is set, then update our shadow registers. */ if (node->node_mode & SPI_MODE_UPDATE) { NplSpiSetup(node); } /* Finally activate the node's chip select. */ rc = NplSpiChipSelect(node->node_cs, 0); if (rc) { /* Release the bus in case of an error. */ NutEventPost(&node->node_bus->bus_mutex); } } return rc; }
/* * Main application routine. */ int main(void) { uint32_t baud = 115200; /* * Register the UART device, open it, assign stdout to it and set * the baudrate. */ NutRegisterDevice(&DEV_CONSOLE, 0, 0); freopen(DEV_CONSOLE_NAME, "w", stdout); _ioctl(_fileno(stdout), UART_SETSPEED, &baud); /* * Print title. */ puts("\nNut/OS Event Queue Demo"); puts("High Main Low "); /* * Post an initial event. This will put the queue into signaled * state and immediately grant the next call to NutEventWait(). */ NutEventPost(&mutex); /* * Start two background threads. */ NutThreadCreate("high", High, 0, 256); NutThreadCreate("low", Low, 0, 256); for(;;) { puts(" Request"); if (NutEventWait(&mutex, 1000)) { puts(" Timeout"); } else { puts(" Acquired"); NutSleep(1500); puts(" Release"); NutEventPost(&mutex); } NutSleep(1000); } return 0; }
/* @@@ 2003-10-24: modified by OS for udp packet queue */ void NutUdpInput(NETBUF * nb, ureg_t bcast) { UDPHDR *uh; UDPSOCKET *sock; uh = (UDPHDR *) nb->nb_tp.vp; nb->nb_ap.vp = uh + 1; nb->nb_ap.sz = nb->nb_tp.sz - sizeof(UDPHDR); nb->nb_tp.sz = sizeof(UDPHDR); /* * Find a port. If none exists and if this datagram hasn't been * broadcasted, return an ICMP unreachable. */ if ((sock = NutUdpFindSocket(uh->uh_dport)) == 0) { if (bcast || NutIcmpResponse(ICMP_UNREACH, ICMP_UNREACH_PORT, 0, nb) == 0) { NutNetBufFree(nb); } return; } /* if buffer size is defined, use packet queue */ if (sock->so_rx_bsz) { /* New packet fits into the buffer? */ if (sock->so_rx_cnt + nb->nb_ap.sz > sock->so_rx_bsz) { /* No, so discard it */ NutNetBufFree(nb); return; } else { /* if a first packet is already in the queue, find the end * and add the new packet */ if (sock->so_rx_nb) { NETBUF *snb; for (snb = sock->so_rx_nb; snb->nb_next != 0; snb = snb->nb_next); snb->nb_next = nb; } else sock->so_rx_nb = nb; /* increment input buffer count */ sock->so_rx_cnt += nb->nb_ap.sz; }; } else { /* no packet queue */ /* if a packet is still buffered, discard it */ if (sock->so_rx_nb) { NutNetBufFree(sock->so_rx_nb); } sock->so_rx_nb = nb; sock->so_rx_cnt = nb->nb_ap.sz; /* set input buffer count to size of new packet */ }; /* post the event only, if one thread is waiting */ if (sock->so_rx_rdy) NutEventPost(&sock->so_rx_rdy); }
/*! * \brief Display a specified text. * * \param row Row position of the message. * \param secs Number of seconds to display the message. Set to 0 for * permanent display. * \param fmt Format string containing conversion specifications. */ void DisplayMessage(u_char row, u_char secs, CONST char *fmt, ...) { va_list ap; va_start(ap, fmt); if (secs) { vsprintf(mline[row], fmt, ap); mticks[row] = secs * 4; } else vsprintf(sline[row], fmt, ap); va_end(ap); NutEventPost(&updevt); }
/*! \brief Deselect a device on the first SPI bus. * * Deactivates the chip select and unlocks the bus. * * \param node Specifies the SPI bus node. * * \return Always 0. */ int NplSpiBusDeselect(NUTSPINODE * node) { /* Sanity check. */ NUTASSERT(node != NULL); NUTASSERT(node->node_bus != NULL); /* Deactivate the node's chip select. */ NplSpiChipSelect(node->node_cs, 1); /* Release the bus. */ NutEventPost(&node->node_bus->bus_mutex); return 0; }
/*! * \brief Transmit and/or receive data as a master. * * The two-wire serial interface must have been initialized by calling * TwInit() before this function can be used. * * \param sla Slave address of the destination. This slave address * must be specified as a 7-bit address. For example, the * PCF8574A may be configured to slave addresses from 0x38 * to 0x3F. * \param txdata Points to the data to transmit. Ignored, if the number * of data bytes to transmit is zero. * \param txlen Number of data bytes to transmit. If zero, then the * interface will not send any data to the slave device * and will directly enter the master receive mode. * \param rxdata Points to a buffer, where the received data will be * stored. Ignored, if the maximum number of bytes to * receive is zero. * \param rxsiz Maximum number of bytes to receive. Set to zero, if * no bytes are expected from the slave device. * \param tmo Timeout in milliseconds. To disable timeout, set this * parameter to NUT_WAIT_INFINITE. * * \return The number of bytes received, -1 in case of an error or timeout. * * \note Timeout is not used in the bit banging version. */ int NutTwiMasterTranceive(NUTTWIBUS *bus, uint8_t sla, const void *txdata, uint16_t txlen, void *rxdata, uint16_t rxsiz, uint32_t tmo) { int rc = 0; uint8_t *cp; NUTTWIICB *icb = bus->bus_icb; if (!twibb_initialized) { TwInit(0); } /* This routine is marked reentrant, so lock the interface. */ if (NutEventWait(&bus->bus_mutex, tmo)) { icb->tw_mm_error = TWERR_IF_LOCKED; return -1; } TwStart(); /* Send SLA+W and check for ACK. */ if ((rc = TwPut(sla << 1)) == 0) { for (cp = (uint8_t *)txdata; txlen--; cp++) { if ((rc = TwPut(*cp)) != 0) { break; } } } if (rc == 0 && rxsiz) { TwStart(); /* Send SLA+R and check for ACK. */ if ((rc = TwPut((sla << 1) | 1)) == 0) { for (cp = rxdata;; cp++) { *cp = TwGet(); if (++rc >= rxsiz) { break; } TwAck(); } } } TwStop(); if (rc == -1) { icb->tw_mm_error = TWERR_SLA_NACK; } /* Release the interface. */ NutEventPost(&bus->bus_mutex); return rc; }
/*! \brief Deselect a device on the SPI bus. * * Deactivates the chip select and unlocks the bus. * * \param node Specifies the SPI bus node. * * \return Always 0. */ int GpioSpiBus0Deselect(NUTSPINODE * node) { /* Sanity check. */ NUTASSERT(node != NULL); NUTASSERT(node->node_bus != NULL); /* Deactivate the node's chip select. */ GpioSpi0ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) == 0); /* Release the bus. */ NutEventPost(&node->node_bus->bus_mutex); return 0; }
/*! * \brief Mount a raw volume. * * This routine is called by the block device driver while mounting a * partition. * * The routine may also initializes any caching mechanism. Thus, it must * be called before any other read or write access. * * \param dev Specifies the file system device. * \param blkmnt Handle of the block device's partition mount. * \param part_type Partition type, ignored. * * \return 0 on success or -1 in case of an error. */ int RawFsMount(NUTDEVICE * dev, NUTFILE * blkmnt, uint8_t part_type) { BLKPAR_INFO pari; RAWVOLUME *vol; NUTASSERT(blkmnt != NULL); NUTASSERT(blkmnt->nf_dev != NULL); NUTASSERT(dev != NULL); /* Allocate the volume information structure */ if ((dev->dev_dcb = malloc(sizeof(RAWVOLUME))) == 0) { return -1; } vol = (RAWVOLUME *) memset(dev->dev_dcb, 0, sizeof(RAWVOLUME)); /* * Query information from the block device driver. */ pari.par_nfp = blkmnt; if ((*blkmnt->nf_dev->dev_ioctl) (blkmnt->nf_dev, NUTBLKDEV_INFO, &pari)) { free(vol); errno = ENODEV; return -1; } vol->vol_sect_num = pari.par_nblks; vol->vol_sect_cnt = pari.par_nblks; vol->vol_sect_len = (size_t) pari.par_blksz; vol->vol_sect_buf = pari.par_blkbp; /* Initialize mutual exclusion semaphores. */ NutEventPost(&vol->vol_fsmutex); NutEventPost(&vol->vol_iomutex); dev->dev_icb = blkmnt; return 0; }
/* * Low priority background thread. */ THREAD(Low, arg) { NutThreadSetPriority(96); for(;;) { puts(" Request"); if (NutEventWait(&mutex, 3000)) { puts(" Timeout"); } else { puts(" Acquired"); NutSleep(3500); puts(" Release"); NutEventPost(&mutex); } } }
/* * High priority background thread. */ THREAD(High, arg) { NutThreadSetPriority(32); for(;;) { puts("Request"); if (NutEventWait(&mutex, 2000)) { puts("Timeout"); } else { puts("Acquired"); NutSleep(2500); puts("Release"); NutEventPost(&mutex); } NutSleep(1000); } }
/*! * \brief Reentrant variant of RawFsFileOpen(). */ static NUTFILE *RawFsApiFileOpen(NUTDEVICE * dev, CONST char *path, int mode, int acc) { NUTFILE *rc; RAWVOLUME *vol; NUTASSERT(dev != NULL); vol = (RAWVOLUME *) dev->dev_dcb; NUTASSERT(vol != NULL); /* Lock filesystem access. */ NutEventWait(&vol->vol_fsmutex, 0); /* Call worker routine. */ rc = RawFsFileOpen(dev, path, mode, acc); /* Release filesystem lock. */ NutEventPost(&vol->vol_fsmutex); return rc; }
/*! * \brief Reentrant variant of RawFsFileRead(). */ static int RawFsApiFileRead(NUTFILE * nfp, void *buffer, int size) { int rc; RAWVOLUME *vol; NUTASSERT(nfp != NULL); NUTASSERT(nfp->nf_dev != NULL); vol = (RAWVOLUME *) nfp->nf_dev->dev_dcb; NUTASSERT(vol != NULL); /* Lock filesystem access. */ NutEventWait(&vol->vol_fsmutex, 0); /* Call worker routine. */ rc = RawFsFileRead(nfp, buffer, size); /* Release filesystem lock. */ NutEventPost(&vol->vol_fsmutex); return rc; }
/*! * \brief Mimic initialization without actually registering the device. * * This is a little bit tricky. If we want to use the existing DataFlash * routines for accessing the system configuration, they must be * properly initialized. This is normally done by calling NutRegister... * in the application. However, the system configuration must be know * before entering any application code. * */ static int SpiAt45dConfigDevice(void) { #if !defined(DEV_SPIBUS) return -1; #else /* DEV_SPIBUS */ if (devSysConf == NULL) { NUTSPINODE *node; NUTDEVICE *dev; #if NUT_CONFIG_AT45D == 0 dev = &devSpiAt45d0; #elif NUT_CONFIG_AT45D == 1 dev = &devSpiAt45d1; #elif NUT_CONFIG_AT45D == 2 dev = &devSpiAt45d2; #elif NUT_CONFIG_AT45D == 3 dev = &devSpiAt45d3; #else return -1; #endif node = (NUTSPINODE *) dev->dev_icb; NUTASSERT(node != NULL); if (node->node_bus == NULL) { NUTSPIBUS *bus; bus = &DEV_SPIBUS; node->node_bus = bus; } #ifdef NUT_CONFIG_AT45D_CS node->node_cs = NUT_CONFIG_AT45D_CS; #endif NUTASSERT(node->node_bus->bus_initnode != NULL); if ((*node->node_bus->bus_initnode) (node)) { return -1; } NutEventPost(&node->node_bus->bus_mutex); if (SpiAt45dInit(dev)) { return -1; } devSysConf = dev; } return 0; #endif /* DEV_SPIBUS */ }
/* * This handler will be called on every incoming ICMP packet * and handle all echo replies. * * We must return 0, if we processed the packet, or -1 if we * are not interested. In the latter case the packet will be * passed to other registered handlers or handled by Nut/Net. */ static int IcmpCallback(NUTDEVICE * dev, NETBUF * nb) { ICMPHDR *icp; /* ICMP header is in the transport part. */ icp = (ICMPHDR *) nb->nb_tp.vp; /* Make sure we have a valid echo reply packet, ... */ if (icp && nb->nb_tp.sz >= sizeof(ICMPHDR) && icp->icmp_type == ICMP_ECHOREPLY /* ... but limit the number of unprocessed packets. */ && nbuf_count < 8) { /* Add the packet to the queue and wake up the main thread. */ nb->nb_next = nbuf_queue; nbuf_queue = nb; NutEventPost(&sign_queue); return 0; } return -1; }
int EEInit( void ) /****************************************************************************/ { uint8_t dummy; at24c32s.PageSize = AT24C_ROW_SIZE; at24c32s.EepromSize = AT24C_CHIP_SIZE; at24c32s.SlaveAddress = NUT_CONFIG_AT24_ADR; at24c32s.IAddrW = AT24C_ADR_SIZE; #ifdef AT24C_BLOCK_ADDR at24c32s.BlInSla = 1; #endif at24c32s.Timeout = 20; NutEventPost( &at24c32s.ee_mutex); if( TwInit(0)) return -1; /* Do a dummy read for communication test */ return At24cRead( &at24c32s, &dummy, 1, 0); }
/*! * \brief Reentrant variant of RawFsIOCtl(). */ static int RawFsApiIOCtl(NUTDEVICE * dev, int req, void *conf) { int rc; RAWVOLUME *vol; NUTASSERT(dev != NULL); vol = (RAWVOLUME *) dev->dev_dcb; /* Lock filesystem access. */ if (req != FS_VOL_MOUNT && vol) { NutEventWait(&vol->vol_fsmutex, 0); } /* Call worker routine. */ rc = RawFsIOCtl(dev, req, conf); /* Release filesystem lock. */ if (req != FS_VOL_MOUNT && req != FS_VOL_UNMOUNT && vol) { NutEventPost(&vol->vol_fsmutex); } return rc; }
/*! * \brief Flush file buffers. * * \param nfp Specifies the file. * * \return 0 on success, -1 otherwise. */ static int RawFsFileFlush(NUTFILE * nfp) { int rc; NUTDEVICE *dev; RAWVOLUME *vol; NUTASSERT(nfp != NULL); dev = nfp->nf_dev; NUTASSERT(dev != NULL); vol = (RAWVOLUME *) dev->dev_dcb; NUTASSERT(vol != NULL); /* Gain mutex access. */ NutEventWait(&vol->vol_iomutex, 0); /* Flush sector buffer. */ rc = RawFsSectorFlush(nfp->nf_dev); /* Release mutex access. */ NutEventPost(&vol->vol_iomutex); return rc; }
/*! * \brief Display specified entry of the list of stations. * * \param rs Index of the list entry. */ void DisplayEntry(u_char rs) { RADIOSTATION *rsp = &station[rs]; if (rsp->rs_port && rsp->rs_name) sprintf(sline[0], "%03u %.12s", rs, rsp->rs_name); else sprintf(sline[0], "%03u", rs); if (rsp->rs_scandead) strcpy(sline[1], "not available"); else if (rsp->rs_scantitle) strncpy(sline[1], rsp->rs_scantitle, DISPLAY_VCOLUMNS); else if (rsp->rs_genre) strncpy(sline[1], rsp->rs_genre, DISPLAY_VCOLUMNS); else if (rsp->rs_ip) strncpy(sline[1], inet_ntoa(rsp->rs_ip), DISPLAY_VCOLUMNS); else sline[1][0] = 0; NutEventPost(&updevt); }
int TwWaitBusFree( NUTTWIBUS *bus) { int ret = -1; uint32_t tout = 100; NUTTWIICB *icb = bus->bus_icb; I2C_TypeDef* I2Cx = (I2C_TypeDef*)bus->bus_base; /* Wait till last transfer finished */ tout = 100; while (I2C_Is_Busy(I2Cx) && tout) { TPRINTF("B"); NutSleep(1); tout--; } if (tout) { /* Interface released in time */ ret = 0; } else { TPRINTF("R"); I2Cx->CR1 &= ~I2C_CR1_PE; I2Cx->CR1 |= I2C_CR1_SWRST; bus->bus_recover(); I2Cx->CR1 &= ~I2C_CR1_SWRST; I2Cx->CR1 &= ~I2C_CR1_PE; NutSleep(1); if (I2C_Is_Busy(I2Cx)) { /* Bus still blocked */ icb->tw_mm_error = TWERR_BUS; /* Release the interface. */ NutEventPost( &bus->bus_mutex ); } else { /* We made it! */ ret = 0; } } return ret; }
/*! \brief Select a device on the SPI bus. * * Locks and activates the bus for the specified node. * * \param node Specifies the SPI bus node. * \param tmo Timeout in milliseconds. To disable timeout, set this * parameter to NUT_WAIT_INFINITE. * * \return 0 on success. In case of an error, -1 is returned and the bus * is not locked. */ int GpioSpiBus0Select(NUTSPINODE * node, uint32_t tmo) { int rc; /* Sanity check. */ NUTASSERT(node != NULL); NUTASSERT(node->node_stat != NULL); /* Allocate the bus. */ rc = NutEventWait(&node->node_bus->bus_mutex, tmo); if (rc) { errno = EIO; } else { /* Do the update, if the mode update bit is set. */ if (node->node_mode & SPI_MODE_UPDATE) { GpioSpiSetup(node); } /* Set clock output using the correct idle mode level. */ #if defined(SBBI0_SCK_BIT) GpioPinSetLow(SBBI0_SCK_PORT, (node->node_mode & SPI_MODE_CPOL) != 0); GpioPinConfigSet(SBBI0_SCK_PORT, SBBI0_SCK_BIT, GPIO_CFG_OUTPUT); #endif /* Enable MOSI output and MISO input. */ #if defined(SBBI0_MOSI_BIT) GpioPinConfigSet(SBBI0_MOSI_PORT, SBBI0_MOSI_BIT, GPIO_CFG_OUTPUT); #endif #if defined(SBBI0_MISO_BIT) GpioPinConfigSet(SBBI0_MISO_PORT, SBBI0_MISO_BIT, 0); #endif /* Activate the node's chip select. */ if (GpioSpi0ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) != 0) == NULL) { /* Release the bus in case of an error. */ NutEventPost(&node->node_bus->bus_mutex); rc = -1; } } return rc; }
/* * Received Configure-Request. */ static void IpcpRxConfReq(NUTDEVICE * dev, uint8_t id, NETBUF * nb) { PPPDCB *dcb = dev->dev_dcb; int rc = XCP_CONFACK; XCPOPT *xcpo; uint16_t xcpl; XCPOPT *xcpr; uint16_t xcps; uint16_t len = 0; uint_fast8_t i; uint32_t ip; switch (dcb->dcb_ipcp_state) { case PPPS_CLOSED: /* * Go away, we're closed. */ NutNetBufFree(nb); NutIpcpOutput(dev, XCP_TERMACK, id, 0); return; case PPPS_CLOSING: case PPPS_STOPPING: /* * Ignore if we are going down. */ NutNetBufFree(nb); return; case PPPS_OPENED: /* * Go down and restart negotiation. */ IpcpLowerDown(dev); IpcpTxConfReq(dev, ++dcb->dcb_reqid); break; case PPPS_STOPPED: /* * Negotiation started by our peer. */ IpcpTxConfReq(dev, ++dcb->dcb_reqid); dcb->dcb_ipcp_state = PPPS_REQSENT; break; } /* * Check if there is anything to reject. */ xcpo = nb->nb_ap.vp; xcpl = nb->nb_ap.sz; xcpr = nb->nb_ap.vp; xcps = 0; while (xcpl >= 2) { len = xcpo->xcpo_len; if (len > xcpl) len = xcpl; else { switch (xcpo->xcpo_type) { case IPCP_MS_DNS1: if (xcpo->xcpo_.ul == 0 && dcb->dcb_ip_dns1 == 0) { break; } case IPCP_MS_DNS2: if (xcpo->xcpo_.ul == 0 && dcb->dcb_ip_dns2 == 0) { break; } case IPCP_ADDR: if (xcpo->xcpo_len == 6) len = 0; break; } } if (len) { if (xcpr != xcpo) { xcpr->xcpo_type = xcpo->xcpo_type; xcpr->xcpo_len = len; for (i = 0; i < len - 2; i++) xcpr->xcpo_.uc[i] = xcpo->xcpo_.uc[i]; } xcpr = (XCPOPT *) ((char *) xcpr + len); xcps += len; } xcpl -= xcpo->xcpo_len; xcpo = (XCPOPT *) ((char *) xcpo + xcpo->xcpo_len); } if (xcps) { nb->nb_ap.sz = xcps; rc = XCP_CONFREJ; } /* * Check if there is anything to negotiate. */ else { xcpo = nb->nb_ap.vp; xcpl = nb->nb_ap.sz; xcpr = nb->nb_ap.vp; xcps = 0; len = 0; while (xcpl >= 2) { ip = xcpo->xcpo_.ul; switch (xcpo->xcpo_type) { case IPCP_ADDR: len = IpcpValidateIpReq(&dcb->dcb_remote_ip, &ip); break; case IPCP_MS_DNS1: len = IpcpValidateIpReq(&dcb->dcb_ip_dns1, &ip); break; case IPCP_MS_DNS2: len = IpcpValidateIpReq(&dcb->dcb_ip_dns2, &ip); break; } if (len) { if (xcpr != xcpo) { xcpr->xcpo_type = xcpo->xcpo_type; xcpr->xcpo_len = len; } xcpr->xcpo_.ul = ip; xcpr = (XCPOPT *) ((char *) xcpr + len); xcps += len; len = 0; } xcpl -= xcpo->xcpo_len; xcpo = (XCPOPT *) ((char *) xcpo + xcpo->xcpo_len); } if (xcps) { nb->nb_ap.sz = xcps; rc = XCP_CONFNAK; } } NutIpcpOutput(dev, rc, id, nb); if (rc == XCP_CONFACK) { if (dcb->dcb_ipcp_state == PPPS_ACKRCVD) { dcb->dcb_ipcp_state = PPPS_OPENED; NutEventPost(&dcb->dcb_state_chg); } else dcb->dcb_ipcp_state = PPPS_ACKSENT; dcb->dcb_ipcp_naks = 0; } else if (dcb->dcb_ipcp_state != PPPS_ACKRCVD) dcb->dcb_ipcp_state = PPPS_REQSENT; }
static void MMCSemaInit(void) { NutEventPost(&hMMCSemaphore); } /* MMCSemaInit */
static void MMCFree(void) { NutEventPost(&hMMCSemaphore); } /* MMCFree */
/*! \brief Select a device on the SPI bus. * * Locks and activates the bus for the specified node. * * \param node Specifies the SPI bus node. * \param tmo Timeout in milliseconds. To disable timeout, set this * parameter to NUT_WAIT_INFINITE. * * \return 0 on success. In case of an error, -1 is returned and the bus * is not locked. */ static int Stm32SpiBusSelect(NUTSPINODE * node, uint32_t tmo) { int rc; SPI_TypeDef* base; /* Sanity check. */ NUTASSERT(node != NULL); NUTASSERT(node->node_bus != NULL); NUTASSERT(node->node_stat != NULL); base=(SPI_TypeDef*)(node->node_bus->bus_base); /* Allocate the bus. */ rc = NutEventWait(&node->node_bus->bus_mutex, tmo); if (rc) { errno = EIO; } else { SPI_TypeDef *spireg = node->node_stat; SPI_ENABLE_CLK; /* Activate the IO Pins to avoid glitches*/ GpioPinConfigSet(SPIBUS_SCK_PORT, SPIBUS_SCK_PIN, GPIO_CFG_DISABLED);//SCK GpioPinConfigSet(SPIBUS_MISO_PORT, SPIBUS_MISO_PIN, GPIO_CFG_DISABLED );//MISO GpioPinConfigSet(SPIBUS_MOSI_PORT, SPIBUS_MOSI_PIN, GPIO_CFG_DISABLED);//MOSI /* If the mode update bit is set, then update our shadow registers. */ if (node->node_mode & SPI_MODE_UPDATE) { Stm32SpiSetup(node); } /* Set SPI mode. */ base->CR1 = spireg->CR1; base->CR1 |= SPI_CR1_SSI|SPI_CR1_MSTR; base->CR2=spireg->CR2; #if !defined(STM32L1XX_MD) base->I2SCFGR=spireg->I2SCFGR; base->I2SPR=spireg->I2SPR; #endif //No enable - set it only during transfer #if defined(STM32F10X_CL) #if defined(SPIBUS_REMAP_BB) SPIBUS_REMAP_BB = SPI_DOREMAP; #endif #elif defined (MCU_STM32L1) || defined (MCU_STM32F2) || defined (MCU_STM32F4) GPIO_PinAFConfig( SPIBUS_SCK_PORT, SPIBUS_SCK_PIN, SPI_GPIO_AF); GPIO_PinAFConfig( SPIBUS_MISO_PORT, SPIBUS_MISO_PIN, SPI_GPIO_AF); GPIO_PinAFConfig( SPIBUS_MOSI_PORT, SPIBUS_MOSI_PIN, SPI_GPIO_AF); #endif GpioPinConfigSet(SPIBUS_SCK_PORT, SPIBUS_SCK_PIN, GPIO_CFG_OUTPUT|GPIO_CFG_PERIPHAL);//SCK GpioPinConfigSet(SPIBUS_MISO_PORT, SPIBUS_MISO_PIN, GPIO_CFG_PERIPHAL);//MISO GpioPinConfigSet(SPIBUS_MOSI_PORT, SPIBUS_MOSI_PIN, GPIO_CFG_OUTPUT|GPIO_CFG_PERIPHAL);//MOSI /* Finally activate the node's chip select. */ rc = Stm32SpiChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) != 0); if (rc) { /* Release the bus in case of an error. */ NutEventPost(&node->node_bus->bus_mutex); } } return rc; }