/*----------------------------------------------------------------------------* * NAME * spiSlaveSSELStatusCallback * * DESCRIPTION * Callback issued by the SPI Slave library when slave select is asserted * (start of transaction) or de-asserted (end of transaction) * * PARAMETERS * is_asserted [in] TRUE if SSEL was asserted, FALSE if de-asserted * * RETURNS * Nothing *----------------------------------------------------------------------------*/ static void spiSlaveSSELStatusCallback(bool is_asserted) { if (is_asserted) { #ifdef ENABLE_DEBUG_PRINT DebugWriteString("\r\n\r\n\r\n SSEL Assert"); #else DebugWriteChar('<'); #endif } else /* If SPI Slave is de-selected, prepare the length of the next * transaction ready in the Tx queue */ { /* Length of the data in the Rx queue */ uint16 len = OQSize(&(g_spi_data.rx_q)); /* Clear the Tx queue and get it ready for the next transaction */ OQClear(&(g_spi_data.tx_q)); /* The first octet in the next transaction is the length of the data * to be transferred */ OQQueueData(&(g_spi_data.tx_q), &len, 1U); /* Data to be transferred in the next transaction */ OQTransferData(&(g_spi_data.rx_q), &(g_spi_data.tx_q), len); /* Ask for the next data callback to be sent when the next octet is * received */ SpiSlaveConfigDataStatusCallback(spiSlaveDataCallback, 1U); if (SpiSlaveGetSharedRAMTxDataSize() > 0) /* If the SPI Slave still has some un-transmitted data from the * previous transaction */ { /* Reset the SPI Slave to remove the pending data */ SpiSlaveReset(TRUE); } /* Update state to indicate we're waiting for the length octet */ g_spi_data.state = state_waiting_for_len; /* Clear the Rx queue and get it ready for the next transaction */ OQClear(&(g_spi_data.rx_q)); #ifdef ENABLE_DEBUG_PRINT DebugWriteString("\r\nSSEL De-Assert -"); DebugWriteUint16(len); #else DebugWriteChar('>'); #endif } } /* spiSlaveSSELStatusCallback */
/*----------------------------------------------------------------------------* * NAME * AppInit * * DESCRIPTION * This user application function is called after a power-on reset * (including after a firmware panic), after a wakeup from Hibernate or * Dormant sleep states, or after an HCI Reset has been requested. * * NOTE: In the case of a power-on reset, this function is called * after AppPowerOnReset(). * * PARAMETERS * last_sleep_state [in] Last sleep state * * RETURNS * Nothing *----------------------------------------------------------------------------*/ void AppInit(sleep_state last_sleep_state) { /* Initialise communications */ DebugInit(1, uartRxDataCallback, NULL); DebugWriteString("Hello, world\r\n"); }
static uint8 writeASCIICodedNumber(uint32 value) { #define BUFFER_SIZE 11 /* Buffer size required to hold maximum value */ uint8 i = BUFFER_SIZE; /* Loop counter */ uint32 remainder = value; /* Remaining value to send */ char buffer[BUFFER_SIZE]; /* Buffer for ASCII string */ /* Ensure the string is correctly terminated */ buffer[--i] = '\0'; /* Loop at least once and until the whole value has been converted */ do { /* Convert the unit value into ASCII and store in the buffer */ buffer[--i] = (remainder % 10) + '0'; /* Shift the value right one decimal */ remainder /= 10; } while (remainder > 0); /* Send the string to the UART */ DebugWriteString(buffer + i); /* Return length of ASCII string sent to UART */ return (BUFFER_SIZE - 1) - i; }
extern void HeartRateHandleAccessWrite(GATT_ACCESS_IND_T *p_ind) { uint8 *p_value = p_ind->value; gatt_client_config client_config; sys_status rc = sys_status_success; switch(p_ind->handle) { /* Heart Rate measurement characteristic client configuration is being * written */ case HANDLE_EEG_MEASUREMENT_C_CFG: { client_config = BufReadUint16(&p_value); /* Client Configuration is bit field value so ideally bitwise * comparison should be used but since the application supports only * notifications, direct comparison is being used. */ if((client_config == gatt_client_config_notification) || (client_config == gatt_client_config_none)) { /* Store the new client configuration */ g_eeg_serv_data.hr_meas_client_config = client_config; /* Write Heart Rate Measurement Client configuration to NVM if * the device is bonded. */ if(AppIsDeviceBonded()) { Nvm_Write((uint16*)&client_config, sizeof(client_config), g_eeg_serv_data.nvm_offset + HR_NVM_HR_MEAS_CLIENT_CONFIG_OFFSET); } /* Start sending the HR measurement notifications if they are * not being sent currently. */ StartSendingHRMeasurements(); } else { /* INDICATION or RESERVED */ /* Return Error as only Notifications are supported */ rc = gatt_status_desc_improper_config; } break; } /* EEG channels Control point is being written */ case HANDLE_EEG_CHANNELS: { /* Extract the written value */ g_eeg_serv_data.channel_map = BufReadUint16(&p_value); DebugWriteString("\n\rChannel map updated"); break; } case HANDLE_EEG_ACQUISITION_RATE: { g_eeg_serv_data.acquisition_rate = BufReadUint16(&p_value); TimerDelete(g_eeg_serv_data.acq_tmr); g_eeg_serv_data.acq_tmr = TimerCreate((uint32) (1000000/g_eeg_serv_data.acquisition_rate), TRUE, acquireData); DebugWriteString("\n\rAcq Rate changed"); break; } default: { /* Write is not permitted on any other characteristic/attribute */ rc = gatt_status_write_not_permitted; break; } } /* Send ACCESS RESPONSE */ GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL); }
VOID EnemyDefaults(short SpriteNum, ACTOR_ACTION_SETp action, PERSONALITYp person) { USERp u = User[SpriteNum]; SPRITEp sp = &sprite[SpriteNum]; unsigned int wpn; short wpn_cnt; short depth = 0; extern short TotalKillable; extern BOOL DebugSecret; switch(u->ID) { case PACHINKO1: case PACHINKO2: case PACHINKO3: case PACHINKO4: case 623: case TOILETGIRL_R0: case WASHGIRL_R0: case CARGIRL_R0: case MECHANICGIRL_R0: case SAILORGIRL_R0: case PRUNEGIRL_R0: case TRASHCAN: case BUNNY_RUN_R0: break; default: { TotalKillable++; #if DEBUG if (DebugSecret) { sprintf(ds,"COUNTED: spnum %d, pic %d, x %d, y %d",SpriteNum,sp->picnum,sp->x,sp->y); DebugWriteString(ds); } #endif } break; } RESET(sp->cstat, CSTAT_SPRITE_RESTORE); u->spal = sp->pal; u->RotNum = 5; sp->clipdist = (256) >> 2; u->zclip = Z(48); u->lo_step = Z(32); u->floor_dist = u->zclip - u->lo_step; u->ceiling_dist = SPRITEp_SIZE_Z(sp) - u->zclip; u->Radius = 400; u->MaxHealth = u->Health; u->PainThreshold = DIV16(u->Health) - 1; //u->PainThreshold = DIV4(u->Health) - 1; SET(sp->cstat,CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN); SET(sp->extra,SPRX_PLAYER_OR_ENEMY); sprite[SpriteNum].picnum = u->State->Pic; change_sprite_stat(SpriteNum, STAT_ENEMY); u->Personality = person; u->ActorActionSet = action; DoActorZrange(SpriteNum); //KeepActorOnFloor(SpriteNum); // for swimming actors // make sure we start in the water if thats where we are if (u->lo_sectp)// && SectUser[u->lo_sectp - sector]) { short i,nexti; short sectnum = u->lo_sectp - sector; if (SectUser[sectnum] && TEST(u->lo_sectp->extra, SECTFX_SINK)) { depth = SectUser[sectnum]->depth; } else { TRAVERSE_SPRITE_SECT(headspritesect[sectnum],i,nexti) { SPRITEp np = &sprite[i]; if (np->picnum == ST1 && np->hitag == SECT_SINK) { depth = np->lotag; } } }
/*----------------------------------------------------------------------------* * NAME * showHelp * * DESCRIPTION * Send help message to UART * * PARAMETERS * None * * RETURNS * Nothing *----------------------------------------------------------------------------*/ static void showHelp(void) { /* Send usage information to UART */ DebugWriteString("\r\n"); DebugWriteString("\r\n"); DebugWriteString("Analogue IO Example application\r\n"); DebugWriteString("===============================\r\n"); DebugWriteString("\r\n"); DebugWriteString("Command syntax (<port> can be 0, 1 or 2):\r\n"); DebugWriteString("\r\n"); DebugWriteString(" To get measured voltage at an AIO port: g <port>\r\n"); DebugWriteString(" To set voltage at an AIO port: s <port> <voltage (in mV)>\r\n"); DebugWriteString(" To set digital voltage at an AIO port: d <port> <0/1>\r\n"); DebugWriteString(" To clear AIO voltage level: c <port>\r\n"); DebugWriteString(" To display this help message: h\r\n"); DebugWriteString("\r\n"); DebugWriteString("NOTE: All the AIOs are multiplexed via an analog switch to a single\r\n"); DebugWriteString(" physical ADC & DAC instance. Hence it is not possible to use more\r\n"); DebugWriteString(" than one AIO port at a time\r\n"); DebugWriteString("\r\n"); }
/*----------------------------------------------------------------------------* * NAME * processRxCmd * * DESCRIPTION * Read and process the next command from the byte queue. * * PARAMETERS * None * * RETURNS * Nothing *----------------------------------------------------------------------------*/ static void processRxCmd(void) { /* Loop until the byte queue is empty */ while (BQGetDataSize() > 0) { uint8 byte = '\0'; /* Read in the next byte */ if (BQPopBytes(&byte, 1) > 0) { CMD_T cmd_type; /* Convert byte into a command */ switch (byte) { case 's': case 'S': cmd_type = cmd_set; break; case 'g': case 'G': cmd_type = cmd_get; break; case 'c': case 'C': cmd_type = cmd_clear; break; case 'd': case 'D': cmd_type = cmd_digital; break; case 'h': case 'H': showHelp(); continue; default: /* Discard the byte (we don't know what to do with it) and * jump back to the top of the loop. */ continue; } /* At this point a valid command has been found */ uint32 value; /* Read in the port number (in ASCII) from the byte queue */ if (readASCIICodedNumber(&value)) { const aio_select port = (aio_select)value; /* Validate the port number */ if ((port == value) && (port < NUMBER_OF_AIOS)) { switch (cmd_type) { /* Read the voltage level of an analogue port */ case cmd_get: { /* Read the analogue voltage... */ const uint16 mvs = AioRead(port); /* ...and send it to the UART */ DebugWriteString("\r\nAnalog voltage measured on AIO "); writeASCIICodedNumber(port); DebugWriteString(" is "); writeASCIICodedNumber(mvs); DebugWriteString("mV\r\n"); break; } /* Clear the voltage set on an analogue port */ case cmd_clear: { /* Turn off the specified analogue port... */ AioOff(port); /* ...and print confirmation to the UART */ DebugWriteString("\r\nAnalog voltage set on AIO "); writeASCIICodedNumber(port); DebugWriteString(" is now cleared\r\n"); break; } /* Set the requested voltage in mV on an analogue port */ case cmd_set: { uint32 vol; /* Read in the requested voltage from the byte queue */ if (readASCIICodedNumber(&vol)) { /* Validate the requested voltage */ if ((uint16)vol == vol) { /* Set the analogue port to the requested voltage... */ AioDrive(port, (uint16)vol); /* ...and print confirmation to the UART */ DebugWriteString("\r\nAIO "); writeASCIICodedNumber(port); DebugWriteString(" is attempting to drive "); writeASCIICodedNumber((uint16)vol); DebugWriteString( "mV output\r\n"); } } break; } /* Set the requested digital output on an analogue port */ case cmd_digital: { uint32 vol; /* Read in the requested value from the byte queue */ if (readASCIICodedNumber(&vol)) { /* Validate the requested value */ if ((uint16)vol == vol) { /* Set the analogue port to the requested output... */ AioSetDig(port, vol); /* ...and print confirmation to the UART */ DebugWriteString("\r\nAIO "); writeASCIICodedNumber(port); DebugWriteString(" is attempting to drive "); DebugWriteString(vol ? "HIGH\r\n" : "LOW\r\n"); } } break; } default: /* This case should never be called */ DebugWriteString("\r\nCommand not recognised\r\n"); break; } } } } } }
/*----------------------------------------------------------------------------* * NAME * AppInit * * DESCRIPTION * This user application function is called after a power-on reset * (including after a firmware panic), after a wakeup from Hibernate or * Dormant sleep states, or after an HCI Reset has been requested. * * NOTE: In the case of a power-on reset, this function is called * after app_power_on_reset(). * * PARAMETERS * last_sleep_state [in] Last sleep state * * RETURNS * Nothing *----------------------------------------------------------------------------*/ void AppInit(sleep_state last_sleep_state) { /* Length octet for first transaction */ uint16 len = 0U; /* Initialise communications */ DebugInit(1, NULL, NULL); /* Set up the queue containing data to be sent to the SPI Master. The queue * is read by the SPI Slave library and the data transferred over to the Tx * area of the shared RAM when an interrupt from the PIO controller is * received. The application can queue data at any time. */ OQSetFill(&(g_spi_data.tx_q), FALSE, 0U); OQCreate(g_spi_data.data_tx, MAX_TRANSACTION_SIZE, OQDataMode_packed, &(g_spi_data.tx_q)); /* Set up the queue containing data received from the SPI Master. Data is * transferred from the Rx area of the shared memory and added to the queue * by the SPI Slave library when it receives an interrupt from the PIO * controller. The application may read data from the queue at any time, * but in order to prevent the buffer from overflowing and corrupting the * incoming data the queue should be read as soon as possible after the data * status callback is received. */ OQSetFill(&(g_spi_data.rx_q), FALSE, 0U); OQCreate(g_spi_data.data_rx, MAX_TRANSACTION_SIZE, OQDataMode_packed, &(g_spi_data.rx_q)); /* Only enter shallow sleep mode, because the PIO controller needs to run at * 16MHz in order to operate the SPI bus at ~1MHz */ SleepModeChange(sleep_mode_shallow); /* Keep awake when WAKE pin is low */ SleepWakePinEnable(wakepin_mode_low_level); /* Queue the length octet for the first transfer */ OQQueueData(&(g_spi_data.tx_q), &len, 1U); /* Initialise the SPI Slave, and fill the Tx area of the shared RAM with the * general response octet, which will be sent in tha absence of any data in * the queue. */ SpiSlaveInit(PIO_CTRLR_CODE_ADDR, spiSlaveSSELStatusCallback, &(g_spi_data.tx_q), &(g_spi_data.rx_q), GENERAL_RESP); /* Configure the SPI Slave data callback to occur when the length octet for * the next transaction is received. */ SpiSlaveConfigDataStatusCallback(spiSlaveDataCallback, 1U); /* Set the pull-up for the SSEL pin */ PioSetPullModes(PIO_BIT_MASK(SPI_SLAVE_PIO_SSEL), pio_mode_weak_pull_up); /* Set the pull-up for MOSI pin */ PioSetPullModes(PIO_BIT_MASK(SPI_SLAVE_PIO_MOSI), pio_mode_weak_pull_up); /* Set the pull-up/pull-down for SCLK pin, depending on the SPI Mode */ PioSetPullModes(PIO_BIT_MASK(SPI_SLAVE_PIO_SCLK), PIO_CTRLR_SCLK_PULL_MODE); /* Start the SPI slave */ SpiSlaveStart(); /* Set state to indicate we're ready to receive the length octet for the * next transaction */ g_spi_data.state = state_waiting_for_len; DebugWriteString("\r\nSPI Slave test application, stores previous data sent" " from SPI Master and returns the data in the subsequent " "transactions\r\n"); DebugWriteString("Transaction format: \r\n"); DebugWriteString("<LEN> <delay (at least 60us)> <DATA>\r\n"); DebugWriteString("Ready to receive data\r\n"); } /* AppInit */
/*----------------------------------------------------------------------------* * NAME * spiSlaveDataCallback * * DESCRIPTION * Data status callback issued by the SPI Slave library when a previously * set threshold number of octets have been received, or a SPI transaction * has completed because the Slave has been de-selected. In this case * p_rx_q will refer to the queue containing the received data. * * It will also be issued to notify the application that a certain amount * of data has been transferred over to the Tx area of the shared RAM for * onward transmission to the SPI Master. This allows the application to * keep track of the size of the Tx queue and keep adding more data as * required. In this case p_rx_q will be NULL. * * PARAMETERS * p_rx_q [in] Rx queue handle when data has been received or * a transaction has completed. * NULL when data has been transferred from the Tx * queue into the Tx area of shared RAM. * p_tx_q [in] Tx queue handle. * tx_data_size [in] Number of octets that have been transferred over * to the Tx area of the shared RAM * * RETURNS * Nothing *----------------------------------------------------------------------------*/ static void spiSlaveDataCallback(OQ_HANDLE p_rx_q, OQ_HANDLE p_tx_q, uint16 tx_data_size) { /* Check whether callback has been issued because more data has arrived */ if (p_rx_q != NULL) { /* Number of octets received */ const uint16 rx_data_size = OQSize(p_rx_q); if (rx_data_size > 0) { if (g_spi_data.state == state_waiting_for_len) /* If waiting for length octet */ { /* Value of the length octet */ uint16 len = 0U; if (OQPopData(p_rx_q, &len, 1U)) { /* Ask for the next callback to be sent when the stated * number of octets have been received */ SpiSlaveConfigDataStatusCallback(spiSlaveDataCallback, len); /* Update the state to indicate we're waiting for the * data */ g_spi_data.state = state_waiting_for_data; #ifdef ENABLE_DEBUG_PRINT DebugWriteString("\r\nRx Len: 0x"); DebugWriteUint16(len); #else DebugWriteChar('L'); #endif } } else /* (g_spi_data.state == state_waiting_for_data) */ /* If waiting for the actual data */ { #ifdef ENABLE_DEBUG_PRINT DebugWriteString("\r\nRx Data Len: 0x"); DebugWriteUint16(rx_data_size); #else DebugWriteChar('D'); #endif } } else /* No data in the Rx queue, we should not have received this * callback */ { #ifdef ENABLE_DEBUG_PRINT DebugWriteString("\r\nSpurious callback: RxDataSize: 0x"); DebugWriteUint16(rx_data_size); DebugWriteString(" TxDataSize: 0x"); DebugWriteUint16(tx_data_size); DebugWriteString(" RemTxDataSize: 0x"); DebugWriteUint16(OQSize(p_tx_q)); #else DebugWriteChar('?'); #endif } } /* Ignore callback if issued because more data has been transferred from * the Tx queue to the Tx area of the shared memory. */ } /* spiSlaveDataCallback */
/*----------------------------------------------------------------------------* * NAME * AppInit * * DESCRIPTION * This user application function is called after a power-on reset * (including after a firmware panic), after a wakeup from Hibernate or * Dormant sleep states, or after an HCI Reset has been requested. * * NOTE: In the case of a power-on reset, this function is called * after AppPowerOnReset(). * * PARAMETERS * last_sleep_state [in] Last sleep state * * RETURNS * Nothing *----------------------------------------------------------------------------*/ void AppInit(sleep_state last_sleep_state) { /* Initialise UART communications */ DebugInit(1, NULL, NULL); DebugWriteString("Configuring PWM Modes\r\n"); /* Configure the output PIO on which the slow flashing LED signal is * generated */ PioSetDir(PIO_LED, PIO_DIR_OUTPUT); /* SLOW FLASHING WITH PWM: * Configure PWM 0 to have the following characteristics * DULL LED Light is generated by having pulses of 0ms ON and * 6ms OFF (~0% duty cycle) * BRIGHT LED Light is generated by having pulses of 6ms ON and * 0ms OFF (~100% duty cycle) * Dullest and Brightest level are held for ~1s * * The brightness level ramps for ~1s when going from dullest to * brightest and vice-versa */ if (PioConfigPWM(0, pio_pwm_mode_push_pull, /* Pulse timings for the dullest part of the sequence: * dullest part of the sequence has the pulse off for the whole * period, in effect the line stays low for the duration for which * the dullest part of the sequence lasts. */ 0, /* ON time for the pulse is 0us */ 255, /* OFF time for the pulse is (255 * 30)us */ 62, /* Dullest part of the sequence lasts for ( 62 * 16 )ms before ramping up to the brightest part of the sequence */ /* Pulse timings for the brightest part of the sequence: * brightest part of the sequence has the pulse ON for the whole * period, in effect the line stays high for the duration for which * the brightest part of the sequence lasts. */ 255, /* ON time for the pulse is (255 * 30)us */ 0, /* OFF time for the pulse is 0us */ 62, /* Brightest part of the sequence lasts for ( 62 * 16 )ms before ramping down to the dullest part of the sequence */ /* Ramping between dullest and brightest parts of the sequence * This parameter determines the duration for which the ramping * lasts when going from dullest to the brightest (and vice-versa). * * The total duration for which the ramping lasts is determined by * multiplying this value with one less than the difference between * the on_time or off_time of the two states, whichever is bigger; * in the units of 30us * */ 132 /* Ramping lasts for ((255-1) * 132 * 30)us */ )) { DebugWriteString("PWM0 was set to ramp between brightest and dullest " "levels\r\n"); /* Connect PWM0 output to LED */ PioSetMode(PIO_LED, pio_mode_pwm0); /* Enable the PWM0 */ PioEnablePWM(0, TRUE); } else { DebugWriteString("PWM0 couldn't be configured\r\n"); } /* Set both outputs to have strong internal pull ups */ PioSetPullModes((1UL << PIO_MOTOR) | (1UL << PIO_LED), pio_mode_strong_pull_up); /* Configure motor PIO to be output */ PioSetDir(PIO_MOTOR, PIO_DIR_OUTPUT); /* Connect PWM1 output to motor PIO */ PioSetMode(PIO_MOTOR, pio_mode_pwm1); /* Initialise timers */ TimerInit(MAX_APP_TIMERS, app_timers); /* Call the function (with a dummy timer ID to start with) to configure * the PWM1 with initial duty cycle and start a timer. When the timer * expires the same function gets called again and the duty cycle for * PWM1 gets updated. It takes care of restarting the timer and ensuring * that duty cycle alternates between 0% and 100% back and forth. */ dutyCycleTask(TIMER_INVALID); /* Enable the PWM1 */ PioEnablePWM(1, TRUE); }