2013-07-17 6 views
0

Я работаю с микроконтроллером LPC1788, и я пытаюсь отправлять и получать данные с UFDC-1 (универсальный преобразователь частоты-в-цифровой) с использованием SPI. Я могу передавать данные через MOSI на это отлично (я подтвердил это с помощью осциллографа), но всякий раз, когда я отправляю инструкцию типа «получить точность», единственными данными, которые у меня есть в буфере данных, являются данные или инструкции Я только что отправил. «Loop back» не включен.LPC1788: Общение с UFDC-1 с использованием SPI

Это код, у меня есть:

SSP_CFG_Type sspConfig; 
SSP_DATA_SETUP_Type sspData; 
LPC_SSP_TypeDef *SSPx = NULL; 

UFDC_RESULT_T result_SSP0_FX1, result_SSP0_FX2; 
UFDC_RESULT_T result_SSP1_FX1, result_SSP1_FX2; 
UFDC_RESULT_T *result, *resultFX1, *resultFX2 = NULL; 

uint8_t resultSign; 
uint64_t resultInt, resultFract; 

uint8_t SSP0resultFX1sign, SSP0resultFX2sign; 
uint8_t SSP1resultFX1sign, SSP1resultFX2sign; 

uint64_t SSP0resultFX1int, SSP0resultFX2int; 
uint64_t SSP1resultFX1int, SSP1resultFX2int; 

uint64_t SSP0resultFX1fract, SSP0resultFX2fract; 
uint64_t SSP1resultFX1fract, SSP1resultFX2fract; 

uint16_t getAccInstr = 0x01FF; 
uint16_t setAccInstr = 0x020A; 
uint16_t checkStatusInstr = 0x03FF; 
uint16_t setMeasureModeInstr1 = 0x0600; 
uint16_t setMeasureModeInstr2 = 0x060E; 
uint16_t getBCDResultInstr = 0x07FF; 
uint8_t startMeasureInstr = 0x09; 

uint32_t measureInstr; 

uint8_t txData[2]; 
uint8_t rxData[2]; 

uint16_t data; 

sspConfig.CPHA = SSP_CPHA_FIRST; 
sspConfig.CPOL = SSP_CPOL_HI; 
sspConfig.ClockRate = 100000; 
sspConfig.Databit = SSP_DATABIT_16; 
sspConfig.Mode = SSP_MASTER_MODE; 
sspConfig.FrameFormat = SSP_FRAME_SPI; 

sspData.tx_data = txData; 
sspData.rx_data = rxData; 
sspData.length = 2; 

printf("Initialising SSP0 and SSP1...\n\n"); 

PINSEL_ConfigPin(0, 15, 2); // SSP0_SCK 
PINSEL_ConfigPin(0, 16, 2); // SSP0_SSEL 
PINSEL_ConfigPin(0, 17, 2); // SSP0_MISO 
PINSEL_ConfigPin(0, 18, 2); // SSP0_MOSI 
PINSEL_ConfigPin(0, 6, 2); // SSP1_SCK 
PINSEL_ConfigPin(0, 7, 2); // SSP1_SSEL 
PINSEL_ConfigPin(0, 8, 2); // SSP1_MISO 
PINSEL_ConfigPin(0, 9, 2); // SSP1_MOSI 

PINSEL_SetFilter(0, 7, DISABLE); 
PINSEL_SetFilter(0, 8, DISABLE); 
PINSEL_SetFilter(0, 9, DISABLE); 

SSP_Init(LPC_SSP0, &sspConfig); 
SSP_Init(LPC_SSP1, &sspConfig); 
SSP_Cmd(LPC_SSP0, ENABLE); 
SSP_Cmd(LPC_SSP1, ENABLE); 

printf("Reading UDFC frequency values...\n\n"); 
for(int i=0; i < 2; i++) 
{ 
    if(i == 0) 
    { 
    SSPx = LPC_SSP0; 
    resultFX1 = &result_SSP0_FX1; 
    resultFX2 = &result_SSP0_FX2; 
    } 
    else 
    { 
    SSPx = LPC_SSP1; 
    resultFX1 = &result_SSP1_FX1; 
    resultFX2 = &result_SSP1_FX2; 
    } 

    // Set UFDC accuracy to 1%. 
    SSP_SendData(SSPx, setAccInstr); 
    while(SSPx->SR & SSP_SR_BSY); 

    // Check accuracy. 
    while(1) 
    { 
    printf("Sending data...\n"); 
    SSP_SendData(SSPx, getAccInstr); 

    while(SSPx->SR & SSP_SR_BSY); 

    // Wait to receive back data. 
    while(SSPx->SR & SSP_SR_RNE) 
    { 
     printf("Received data here: 0x%x\n", SSP_ReceiveData(SSPx)); 
    } 

    //data = SSP_ReceiveData(SSPx); 
    //printf("Accuracy check 1: %i\n", data >> 8); 
    //printf("Accuracy check 2: %i\n", data & 0xFF); 
    } 

Edit: Here является захват всех моих линий SPI после отправки "установить точность" инструкцию (0x020A). Ожидается, что данные в MISO будут бессмысленными. Я могу произвести захват для других инструкций, если это необходимо.

Сверху вниз:

  • MISO
  • MOSI
  • SS
  • SCLK

Edit 2: В частности, то, что я пытаюсь сделать, это установить точность UFDC-1 с инструкцией 0x020A. Последняя часть этого («0A») - это номер точности. После этого у меня есть цикл while, где я пытаюсь прочитать эту точность. Инструкция «получить точность» - 0x01FF, где «FF» - это фиктивный байт, отправленный для чтения номера точности. Поэтому, когда я отправляю «0x01FF», я ожидаю, что вернусь «0A» где-нибудь в данных, которые я получаю обратно от UFDC-1.

Редактировать 3: Here - это захват линий SPI, поскольку я впервые отправляю инструкцию «получить точность» в UFDC-1. Синяя линия (вторая сверху) - MOSI, и она, безусловно, дает правильную команду (0x01FF). Если это работает правильно, UFDC-1 должен отвечать через MISO с «0A» (0b00001010), который является номером точности, в то же время, когда MOSI передает «FF». Вместо этого я получаю сообщение «1A» в то время, и я не считаю, что «A» на самом деле происходит из UFDC-1, но только из инструкции «set precision» (0x020A), которую я отправил ранее. Это связано с тем, что у меня есть инструкция «получить точность», проходящую в цикле while, и фиксированное значение, которое я читаю, «0x7F00» - ничего общего с номером точности UFDC-1.

Это то, что мой выход выглядит следующим образом:

Initialising SSP0 and SSP1... 

Reading UDFC frequency values... 

Sending data... 
Received data here: 0xff00 
Received data here: 0xa1a 
Sending data... 
Received data here: 0xff00 
Sending data... 
Received data here: 0x7f00 
Sending data... 
Received data here: 0x7f00 
Sending data... 
Received data here: 0x7f00 
Sending data... 
Received data here: 0x7f00 
Sending data... 
Received data here: 0x7f00 
Sending data... 

Edit: Оказывается, проблема была с CPOL и CPHA битами. Оба они были изменены с 0 на 1. Это похоже на то, что контроллер SPI корректно взаимодействует с UFDC.

Остается одна проблема в том, что часы SPI в случайных данных на MISO. Например, у меня есть цикл while, в котором я ожидаю получить только «0xedff». Что я получаю вместо этого:

Data : 0xedff 
Data : 0xffff 
Data : 0xff01 
Data : 0xffff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
+1

Я не совсем понимаю ваш вопрос. Но я предполагаю, что вы ожидаете полученные данные в буфере, но не получаете его. Вы посмотрели на сигнал SPI в таблице данных UFDC-1? Я не знаю, как линия выбора микросхемы обрабатывается вашей функцией. Большинство интегральных микросхем SPI требуют от ведущего устройства сохранить выбранный чип для ответа на команду. – Thanushan

+0

«Но я предполагаю, что вы ожидаете полученные данные в буфере, но не получаете его». Ага. Я уточню вопрос с разъяснением. «Большинство интегральных микросхем SPI требуют, чтобы ведущий держал выбранный чип для ответа на команду« Мой микроконтроллер, похоже, обрабатывает это автоматически, основываясь на захватах, которые я получил от осциллографа. Выбор подчиненного устройства, кажется, удерживается до тех пор, пока не будет отправлена ​​вся команда. – Tagc

+1

Получаете ли вы ответ от UFDC-1, глядя с объемом? Я думаю, что линия выбора чипа обрабатывается SSP_SendData() и SSP_ReceiveData. Но UFDC-1, возможно, захочет поддерживать низкую линию до тех пор, пока ответ не будет отправлен, т. Е. Не будет тянуть его высоко после записи инструкции, а затем потянуть его на низком уровне для получения данных (только угадать). – Thanushan

ответ

0

В SSPs в LPC17xx имеют FIFOs как для приема и передачи. Это означает, что вы должны соответствовать вашим вызовам SSP_SendData() и SSP_ReceiveData(), или пустым FIFO. Вам также придется отправить фиктивное значение, когда принимает данные - обычно 0x00 или 0xFF используется как манекен.

Библиотека делает это в SSP_ReadWrite(), которую вы можете использовать вместо этого.

Более простой вариант будет выглядеть следующим образом:

uint16_t spi_write_read(LPC_SSP_TypeDef* SSPx, uint16_t outgoing) 
{ 
    uint16_t incoming; 

    while(!(SSPx->SR & (1 << SSP_SR_TNF))) { ; } 
    SSPx->DR = outgoing; 
    while(!(SSPSR & (1 << SSP_SR_RNE))) { ; } 
    incoming = SSPx->DR; 

    return incoming; 
} 

Эта функция может быть использована в качестве замены для обоих SSP_SendData() и SSP_ReceiveData() в вашем коде.

Заключительная записка: Возможно, вы, возможно, не хотите аппаратное обеспечение Chip Select, так как это может отменить выбор между подчиненными командами и словами ответа. Прочтите соответствующие спецификации, во многих случаях это недопустимо.

+0

Я попытался использовать SSP_ReadWrite(), а также вручную удерживая линию выбора микросхемы при передаче инструкции «получить точность» (я установил ее по умолчанию для функции GPIO перед отправкой, а затем установил ее как аппаратную CS. проверил соответствующие таблицы данных, и я ничего не могу найти о необходимости держать фишку в любом случае вручную. – Tagc

+0

Показать код. Необходимость фиктивных байтов также применяется к 'SPI_ReadWrite()'. –

+0

Извините за поздний ответ. работала над чем-то другим. Коллега получил SPI, работая, изменив бит CPOL и CPHA. Я не мог найти в них ссылок на них в таблицах данных, так что это раздражает то, что они были проблемой. Осталась проблема - SPI теперь будет синхронизироваться с нужными данными, но он также будет синхронизироваться с кучей случайных значений. Я попытаюсь найти способ остановить это из-за г. – Tagc