Форум сайта python.su
Здравствуйте, друзья!
Прошу вашего совета по следующему вопросу…
У меня есть двухканальный передатчик, позволяющий взаимодействовать с ним по SPI протоколу, Имею в наличии нечто вроде протокола информационного взаимодействия. В качестве “железки” для работы по указанному протоколу я решил использовать Raspberry Pi 2. Задача вроде бы вполне решаемая этими средствами и применением Python.
Параметры обмена: CPOL=0, CPHA=1. Период обмена 2,5 мс. Частота – 500 кГц..10 МГц.
Состав слов MOSI:
1 байт - 6 бит контрольное слово (checkword), полученное от передатчика в предыдущем цикле обмена + 2 бита - установка уровня выходной мощности (полная мощность, -3 дБ, -6 дБ, -9 дБ).
3 байт - кодовое слово, передаваемое в передатчик для подтверждения целостности канала.
2,4,5,6 байты - резерв, не используются
Состав слов MISO:
1 байт - 6 бит контрольное слово (передаваемое передатчиком) + 1 бит подтверждение запроса + 1 бит признак исправности.
2 байт - выходная мощность основного канала (Pout_o в моей программе).
3 байт - выходная мощность резервного канала (Pout_k в моей программе).
4 байт - контрольное слово, полученное от стенда.
5 байт - коэффициент стоячей волны по основному каналу (KSV_o в моей программе).
6 байт - коэффициент стоячей волны по резервному каналу (KSV_k в моей программе).
Вот мой код:
import spidev
import time
import math
import random
from tkinter import *
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 110000
spi.bits_per_word = 8
spi.mode = 0b00
spi.cshigh = False
#spi.loop = True
root = Tk()
root.title("SPI-CONFIG")
root.geometry("500x300+600+300")
def printer(event):
print("SPI-test")
def Pout(sec_byte):
P=100*(10**(0.0058*sec_byte))
return P
def KSV(fifth_byte):
k=1+0.1*fifth_byte
return k
var=IntVar()
radbut1 = Radiobutton(root,variable=var,text = "3 dB",value=1)
radbut2 = Radiobutton(root,variable=var,text = "6 dB",value=2)
radbut3 = Radiobutton(root,variable=var,text = "9 dB",value=3)
radbut3.pack(side=BOTTOM)
radbut2.pack(side=BOTTOM)
radbut1.pack(side=BOTTOM)
KSV_o=StringVar()
P_o=StringVar()
P_k=StringVar()
lab_P_o = Label(root, textvariable=P_o)
lab_P_o.pack(side=TOP)
lab_P_k = Label(root,textvariable=P_k)
lab_P_k.pack(side=TOP)
lab_KSV_o = Label(root, textvariable=KSV_o)
lab_KSV_o.pack(side=TOP)
b_in_0 = 0
def callback(event=None):
global b_in_0
Pset=0b00000011
b_out_0 = (b_in_0 << 2) + int(Pset) ## Control word TRMTT - answer
b_out_1 = 0xAA #in_dat_0[2] ## Reserve
b_out_2 = 0xAB #in_dat_0[3] ## Control word RPi
b_out_3 = 0xAD #in_dat_0[4] ## Reserve
b_out_4 = 0xFA #in_dat_0[5] ## Reserve
b_out_5 = 0xFB #in_dat_0[6] ## Reserve
b_out_6 = 0xFC #in_dat_0[7] ## Reserve
b_out_7 = 0xFD #in_dat_0[8] ## Reserve
out_dat= spi.writebytes([b_out_0,b_out_1,b_out_2,b_out_3,b_out_4,b_out_5])
in_dat = spi.readbytes(6)
b_in_0 = int(in_dat[0]) >> 2 ## Control word TRMTT
b_in_1 = 100*(10**(0.0058*int(in_dat[1]))) ## Pout_o
b_in_2 = 100*(10**(0.0058*in_dat[4]))#in_dat[2] ## Pout_k
b_in_3 = in_dat[3] ## Control word RPi
b_in_4 = in_dat[4] ## KSV_0
b_in_5 = in_dat[5] ## KSV_k
KSV_o.set('KSV = '+ str(b_in_5))
P_o.set('Pout_o = '+ str(b_in_1))
P_k.set('Pout_k = '+ str(b_in_2))
#lab_P_o.after(50,callback)
#lab_P_k.after(50,callback)
lab_KSV_o.after(50,callback)
#print(in_dat)
lab_P_o.after(50,callback)
lab_P_k.after(50,callback)
lab_KSV_o.after(50,callback)
root.mainloop()
Отредактировано Oolong (Июнь 20, 2017 13:06:37)
Офлайн
readbytes только читает, writebytes только пишет. Для обмена xfer, что-то типа:
in_dat = spi.xfer([b_out_0,b_out_1,b_out_2,b_out_3,b_out_4,b_out_5])
Офлайн
PooHНо тогда, как я понимаю, я не имею возможности “вклиниться” в обмен? То есть spi.xfer позволит мне делать что? При этом расберри будет ждать повторения переданной информации? Вообще не очень понимаю эту функцию. Мне кажется она нужна только при какой-нибудь проверке работоспособности канала… Или я неправ?
readbytes только читает, writebytes только пишет. Для обмена xfer, что-то типа:
Офлайн
Ээээ, вы представляете себе как SPI работает? По каждому такты синхры бит из буфера сдвигается на MOSI, бит с MISO встает на сдвинутое место. Тоже самое только линии наоборот у приемника. Это и есть обмен, xfer. readbytes и writebytes просто отбрасывают соответственно записанные/прочитанные данные. Полноценного дуплекса вы не получите.
ЗЫ: Первый раз бестолково написал, пришлось редактировать
Отредактировано PooH (Июнь 20, 2017 14:00:42)
Офлайн
PooHХм… То есть результатом этого “отбрасывания” и является наличие двух последовательных пачек синхроимпульсов на осциллограмме? И, судя по всему, чтобы реализовать свой замысел, мне придется каким-то образом делать динамически изменяемые данные в xfer ?
Ээээ, вы представляете себе как SPI работает? По каждому такты синхры бит из буфера сдвигается на MOSI, бит с MISO встает на сдвинутое место. Тоже самое только линии наоборот у приемника. Это и есть обмен, xfer. readbytes и writebytes просто отбрасывают соответственно записанные/прочитанные данные. Полноценного дуплекса вы не получите.ЗЫ: Первый раз бестолково написал, пришлось редактировать
Отредактировано Oolong (Июнь 20, 2017 14:14:20)
Офлайн
вроде есть модуль spi для RPi
https://geektimes.ru/post/255052/
Офлайн
vic57Ну именно его я и использую. Я еще попробовал проверил скомпилировал С-шный код с помощью gcc, как там описано. Замкнул - работает. Так что железо в норме. Дело “за малым” - разобраться, как написать с использованием xfer, чтобы работало.
вроде есть модуль spi для RPihttps://geektimes.ru/post/255052/
Отредактировано Oolong (Июнь 20, 2017 15:47:44)
Офлайн
Oolongspi.readbytes != spi.readbits
оманде “spi.readbytes” должно начаться с первым битом сообщения, переданного по команде spi.writebytes. У меня же картина другая :
Устройство, управляющее шиной тактирования (то есть генерирующее на ней синхроимпульсы), является “Ведущим” или “Мастером”. Собственно, “Master” управляет всем обменом данными, - он решает: когда начинать обмен, когда заканчивать, сколько бит передать и т.д. Второе устройство, участвующее в обмене, является “Ведомым” или “Slave”. В SPI, в отличии от, например, того же I2C, “Slave” совсем бесправен, он вообще никак не может влиять на шину тактирования и никак не может сообщить мастеру, что не успевает или, наоборот, что уже готов к обмену. То есть “Мастер” сам должен знать: когда, что и на какой скорости спросить у “Слэйва”, чтобы тот смог ему ответить.http://www.radiohlam.ru/teory/SPI.htm
Отредактировано vic57 (Июнь 20, 2017 17:26:09)
Офлайн
OolongЧто-то я не пойму в чем вы проблему видите? Подготовили свои данные, вызвали xfer, в результате получили данные со слейва, а свои туда закинули, обработали, снова выставили, снова вызвали. Как-то в упор проблемы не вижу. Просто передача идет одновременно в две стороны.
И, судя по всему, чтобы реализовать свой замысел, мне придется каким-то образом делать динамически изменяемые данные в xfer
Отредактировано PooH (Июнь 20, 2017 17:50:09)
Офлайн
PooHНу в общем я сделал вывод, что с xfer надо поработать плотнее. Просто у меня в голове пока не совсем укладывается, как я смогу получить какие-то данные со слейка, кроме тех, что я ему отправлял, если использовать именно xfer. Я считал, что он не предполагает возврат каких-либо значений.
Что-то я не пойму в чем вы проблему видите? Подготовили свои данные, вызвали xfer, в результате получили данные со слейва, а свои туда закинули, обработали, снова выставили, снова вызвали. Как-то в упор проблемы не вижу. Просто передача идет одновременно в две стороны.
Отредактировано Oolong (Июнь 21, 2017 10:41:44)
Офлайн