-
- command error_t ReadStream.postBuffer[uint8_t streamClient]( uint16_t* buf, uint16_t count )
- {
- struct stream_entry_t *newEntry = (struct stream_entry_t *) buf;
-
- newEntry->count = count;
- newEntry->next = 0;
- atomic {
- if (!streamBuf[streamClient])
- streamBuf[streamClient] = newEntry;
- else {
- struct stream_entry_t *tmp = streamBuf[streamClient];
- while (tmp->next)
- tmp = tmp->next;
- tmp->next = newEntry;
- }
- }
- return SUCCESS;
- }
-
- command error_t ReadStream.read[uint8_t streamClient]( uint32_t _usPeriod )
- {
- if (!streamBuf[streamClient])
- return EINVAL;
- if (call ResourceReadStream.isOwner[streamClient]())
- return EBUSY;
- usPeriod[streamClient] = _usPeriod;
- return call ResourceReadStream.request[streamClient]();
- }
-
- void task finishStreamRequest()
- {
- call ResourceReadStream.release[owner]();
- if (!streamBuf[owner])
- // all posted buffers were filled
- signal ReadStream.readDone[owner]( SUCCESS, usPeriod[owner] );
- else {
- // the commented code below makes gcc throw
- // "internal error: unsupported relocation error" !?!
- /*
- do {
- signal ReadStream.bufferDone[owner]( FAIL, (uint16_t *) streamBuf[owner], 0);
- streamBuf[owner] = streamBuf[owner]->next;
- } while (streamBuf[owner]);
- */
- signal ReadStream.readDone[owner]( FAIL, 0 );
- }
- }
-
- event void ResourceReadStream.granted[uint8_t streamClient]()
- {
- error_t result;
- const msp430adc12_channel_config_t *config;
- struct stream_entry_t *entry = streamBuf[streamClient];
-
- if (!entry)
- result = EINVAL;
- else {
- config = call ConfigReadStream.getConfiguration[streamClient]();
- if (config->inch == INPUT_CHANNEL_NONE)
- result = EINVAL;
- else {
- owner = streamClient;
- streamConfig = *config;
- streamConfig.sampcon_ssel = SAMPCON_SOURCE_SMCLK; // assumption: SMCLK runs at 1 MHz
- streamConfig.sampcon_id = SAMPCON_CLOCK_DIV_1;
- streamBuf[streamClient] = entry->next;
- result = call SingleChannelReadStream.configureMultiple[streamClient](
- &streamConfig, (uint16_t *) entry, entry->count, usPeriod[streamClient]);
- if (result == SUCCESS)
- result = call SingleChannelReadStream.getData[streamClient]();
- else {
- streamBuf[streamClient] = entry;
- post finishStreamRequest();
- return;
- }
- }
- }
- if (result != SUCCESS){
- call ResourceReadStream.release[streamClient]();
- signal ReadStream.readDone[streamClient]( FAIL, 0 );
- }
- return;
- }
-
-
- async event uint16_t* SingleChannelReadStream.multipleDataReady[uint8_t streamClient](
- uint16_t *buf, uint16_t length)
- {
- error_t nextRequest;
-
- if (!resultBuf){
- value = length;
- resultBuf = buf;
- post signalBufferDone();
- if (!streamBuf[streamClient])
- post finishStreamRequest();
- else {
- // fill next buffer (this is the only async code dealing with buffers)
- struct stream_entry_t *entry = streamBuf[streamClient];
- streamBuf[streamClient] = streamBuf[streamClient]->next;
- nextRequest = call SingleChannelReadStream.configureMultiple[streamClient](
- &streamConfig, (uint16_t *) entry, entry->count, usPeriod[streamClient]);
- if (nextRequest == SUCCESS)
- nextRequest = call SingleChannelReadStream.getData[streamClient]();
- if (nextRequest != SUCCESS){
- streamBuf[owner] = entry;
- post finishStreamRequest();
- }
- }
- } else {
- // overflow: can't signal data fast enough
- struct stream_entry_t *entry = (struct stream_entry_t *) buf;
- entry->next = streamBuf[streamClient];
- streamBuf[streamClient] = entry; // what a waste
- post finishStreamRequest();
- }
- return 0;
- }
-
- void task signalBufferDone()
- {
- signal ReadStream.bufferDone[owner]( SUCCESS, resultBuf, value);
- resultBuf = 0;
- }
-
- async event error_t SingleChannelReadStream.singleDataReady[uint8_t streamClient](uint16_t data)
- {
- // won't happen
- return SUCCESS;
- }