#include "hspi.h"
//#include <stdio.h>
//#include <string.h>
#include "py/nlr.h"
#include "py/obj.h"
#include "py/runtime.h"
#include "py/binary.h"
#include "portmodules.h"
STATIC mp_obj_t hspi_txchunk(mp_obj_t data) {
// for offset in range(0, len(buf), 10): # iterate trough data 10 bytes at the time
// sdata = buf[offset : offset + 10] # buf is a bytearray
// hspitxchunk.send(sdata)
if (!MP_OBJ_IS_TYPE(data, &mp_type_bytearray)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "takes bytearray"));
}
// uint8_t dlen;
// dlen = mp_obj_len(data);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
// const char *str = mp_obj_str_get_str(data);
// for (; *str; ++str) {
// int chr = *(uint8_t*)str;
// }
uint16_t tat = bufinfo.len / 10;
uint16_t trm = bufinfo.len % 10;
uint8_t nbytes = 10;
for (uint32_t t = 0; t < (tat + 1); t++) {
if (t == tat) { //remainder bytes?
nbytes = trm;
}
uint8_t cmdbits = 0;
uint32_t addrbits = 0;
uint32_t doutbits = 0;
uint8_t cshift = 0;
uint8_t ashift = 0;
uint8_t dshift = 0;
for (uint8_t bl = 0; bl < nbytes; bl++)
{
if (cmdbits < 16) {
cmdbits = cmdbits + 8;
cshift += 1;
}
else {
if (addrbits < 32) {
addrbits = addrbits + 8;
ashift += 1;
}
else {
if (doutbits < 32) {
doutbits = doutbits + 8;
dshift += 1;
}
else {
break;
}
}
}
}
uint16_t cmddata = 0;
uint32_t addrdata = 0;
uint32_t doutdata = 0;
const uint8_t *p = (const uint8_t*)bufinfo.buf;
p = &p[t * 10];
for (uint8_t n = 0; n < 4; n++)
{
if (n <= 1) {
if (((n + 1) * 8) <= cmdbits) {
cmddata |= (p[n] << (8 * (1 - n)));
}
}
if (addrbits != 0) {
if (((n + 1) * 8) <= addrbits) {
addrdata |= (p[n + 2] << (8 * (3 - n)));
}
}
if (doutbits != 0) {
if (((n + 1) * 8) <= doutbits) {
doutdata |= (p[n + 6] << (8 * (3 - n)));
}
}
}
cmddata = cmddata >> ((2 - cshift) * 8);
addrdata = addrdata >> ((4 - ashift) * 8);
doutdata = doutdata >> ((4 - dshift) * 8);
while (spi_busy(1)) {}; // Wait for SPI to be ready
// Enable SPI Functions
// Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
CLEAR_PERI_REG_MASK(SPI_USER(1), SPI_USR_MOSI | SPI_USR_MISO | SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);
// Setup Bitlengths
WRITE_PERI_REG(SPI_USER1(1),
// Number of bits in Address
((addrbits - 1) & SPI_USR_ADDR_BITLEN) << SPI_USR_ADDR_BITLEN_S |
// Number of bits to Send
((doutbits - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S);
// Setup Command Data
if (cmdbits) {
// Enable COMMAND function in SPI module
SET_PERI_REG_MASK(SPI_USER(1), SPI_USR_COMMAND);
// Align command data to high bits
uint16_t command = cmddata << (16 - cmdbits);
// Swap byte order
command = ((command >> 8) & 0xff) | ((command << 8) & 0xff00);
WRITE_PERI_REG(SPI_USER2(1), (
(((cmdbits - 1) & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) |
(command & SPI_USR_COMMAND_VALUE)
));
}
// Setup Address Data
if (addrbits) {
// Enable ADDRess function in SPI module
SET_PERI_REG_MASK(SPI_USER(1), SPI_USR_ADDR);
// Align address data to high bits
WRITE_PERI_REG(SPI_ADDR(1), addrdata << (32 - addrbits));
}
// Setup DOUT data
if (doutbits) {
// Enable MOSI function in SPI module
SET_PERI_REG_MASK(SPI_USER(1), SPI_USR_MOSI);
// Copy data to W0
if (READ_PERI_REG(SPI_USER(1))&SPI_WR_BYTE_ORDER) {
WRITE_PERI_REG(SPI_W0(1), doutdata << (32 - doutbits));
}
else {
WRITE_PERI_REG(SPI_W0(1), doutdata);
}
}
// Begin SPI Transaction
SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR);
}
// Transaction completed
return mp_const_none; //return None
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(hspitxchunk_send_obj, hspi_txchunk);
//STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(hspitxchunk_send_obj, 1, 10, hspi_txchunk);
// declare python module
STATIC const mp_map_elem_t hspitxchunk_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_hspitxchunk) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&hspitxchunk_send_obj },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_hspitxchunk_globals, hspitxchunk_globals_table);
const mp_obj_module_t mp_module_hspitxchunk = {
.base = { &mp_type_module },
//.name = MP_QSTR_hspitxchunk, // depricated
.globals = (mp_obj_dict_t*)&mp_module_hspitxchunk_globals,
};
// end declaration
I2luY2x1ZGUgImhzcGkuaCIKCi8vI2luY2x1ZGUgPHN0ZGlvLmg+Ci8vI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgInB5L25sci5oIgojaW5jbHVkZSAicHkvb2JqLmgiCiNpbmNsdWRlICJweS9ydW50aW1lLmgiCiNpbmNsdWRlICJweS9iaW5hcnkuaCIKI2luY2x1ZGUgInBvcnRtb2R1bGVzLmgiCgoKU1RBVElDIG1wX29ial90IGhzcGlfdHhjaHVuayhtcF9vYmpfdCBkYXRhKSB7CgovLwlmb3Igb2Zmc2V0IGluIHJhbmdlKDAsIGxlbihidWYpLCAxMCk6ICMgaXRlcmF0ZSB0cm91Z2ggZGF0YSAxMCBieXRlcyBhdCB0aGUgdGltZQovLwkJc2RhdGEgPSBidWZbb2Zmc2V0IDogb2Zmc2V0ICsgMTBdICMgYnVmIGlzIGEgYnl0ZWFycmF5Ci8vCQloc3BpdHhjaHVuay5zZW5kKHNkYXRhKQoJaWYgKCFNUF9PQkpfSVNfVFlQRShkYXRhLCAmbXBfdHlwZV9ieXRlYXJyYXkpKSB7CgkJbmxyX3JhaXNlKG1wX29ial9uZXdfZXhjZXB0aW9uX21zZygmbXBfdHlwZV9WYWx1ZUVycm9yLCAidGFrZXMgYnl0ZWFycmF5IikpOwoJfQoJLy8gdWludDhfdCBkbGVuOwoJLy8gZGxlbiA9IG1wX29ial9sZW4oZGF0YSk7CgoJbXBfYnVmZmVyX2luZm9fdCBidWZpbmZvOwoJbXBfZ2V0X2J1ZmZlcl9yYWlzZShkYXRhLCAmYnVmaW5mbywgTVBfQlVGRkVSX1JFQUQpOyAKCi8vCWNvbnN0IGNoYXIgKnN0ciA9IG1wX29ial9zdHJfZ2V0X3N0cihkYXRhKTsKLy8JZm9yICg7ICpzdHI7ICsrc3RyKSB7CgovLwkJaW50IGNociA9ICoodWludDhfdCopc3RyOwovLwl9CgoJdWludDE2X3QgdGF0ID0gYnVmaW5mby5sZW4gLyAxMDsKCXVpbnQxNl90IHRybSA9IGJ1ZmluZm8ubGVuICUgMTA7Cgl1aW50OF90IG5ieXRlcyA9IDEwOwoJZm9yICh1aW50MzJfdCB0ID0gMDsgdCA8ICh0YXQgKyAxKTsgdCsrKSB7CgkJaWYgKHQgPT0gdGF0KSB7IC8vcmVtYWluZGVyIGJ5dGVzPwoJCQluYnl0ZXMgPSB0cm07CgkJfQoKCQl1aW50OF90IGNtZGJpdHMgPSAwOwoJCXVpbnQzMl90IGFkZHJiaXRzID0gMDsKCQl1aW50MzJfdCBkb3V0Yml0cyA9IDA7CgkJdWludDhfdCBjc2hpZnQgPSAwOwoJCXVpbnQ4X3QgYXNoaWZ0ID0gMDsKCQl1aW50OF90IGRzaGlmdCA9IDA7CgoJCWZvciAodWludDhfdCBibCA9IDA7IGJsIDwgbmJ5dGVzOyBibCsrKQoJCXsKCQkJaWYgKGNtZGJpdHMgPCAxNikgewoJCQkJY21kYml0cyA9IGNtZGJpdHMgKyA4OwoJCQkJY3NoaWZ0ICs9IDE7CgkJCX0KCQkJZWxzZSB7CgkJCQlpZiAoYWRkcmJpdHMgPCAzMikgewoJCQkJCWFkZHJiaXRzID0gYWRkcmJpdHMgKyA4OwoJCQkJCWFzaGlmdCArPSAxOwoJCQkJfQoJCQkJZWxzZSB7CgkJCQkJaWYgKGRvdXRiaXRzIDwgMzIpIHsKCQkJCQkJZG91dGJpdHMgPSBkb3V0Yml0cyArIDg7CgkJCQkJCWRzaGlmdCArPSAxOwoJCQkJCX0KCQkJCQllbHNlIHsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoKCQl1aW50MTZfdCBjbWRkYXRhID0gMDsKCQl1aW50MzJfdCBhZGRyZGF0YSA9IDA7CgkJdWludDMyX3QgZG91dGRhdGEgPSAwOwoJCWNvbnN0IHVpbnQ4X3QgKnAgPSAoY29uc3QgdWludDhfdCopYnVmaW5mby5idWY7CgkJcCA9ICZwW3QgKiAxMF07CgoJCWZvciAodWludDhfdCBuID0gMDsgbiA8IDQ7IG4rKykKCQl7CgkJCWlmIChuIDw9IDEpIHsKCQkJCWlmICgoKG4gKyAxKSAqIDgpIDw9IGNtZGJpdHMpIHsKCQkJCQljbWRkYXRhIHw9IChwW25dIDw8ICg4ICogKDEgLSBuKSkpOwoJCQkJfQoJCQl9CgkJCWlmIChhZGRyYml0cyAhPSAwKSB7CgkJCQlpZiAoKChuICsgMSkgKiA4KSA8PSBhZGRyYml0cykgewoJCQkJCWFkZHJkYXRhIHw9IChwW24gKyAyXSA8PCAoOCAqICgzIC0gbikpKTsKCQkJCX0KCQkJfQoJCQlpZiAoZG91dGJpdHMgIT0gMCkgewoJCQkJaWYgKCgobiArIDEpICogOCkgPD0gZG91dGJpdHMpIHsKCQkJCQlkb3V0ZGF0YSB8PSAocFtuICsgNl0gPDwgKDggKiAoMyAtIG4pKSk7CgkJCQl9CgkJCX0KCQl9CgoJCWNtZGRhdGEgPSBjbWRkYXRhID4+ICgoMiAtIGNzaGlmdCkgKiA4KTsKCQlhZGRyZGF0YSA9IGFkZHJkYXRhID4+ICgoNCAtIGFzaGlmdCkgKiA4KTsKCQlkb3V0ZGF0YSA9IGRvdXRkYXRhID4+ICgoNCAtIGRzaGlmdCkgKiA4KTsKCgkJd2hpbGUgKHNwaV9idXN5KDEpKSB7fTsgIC8vIFdhaXQgZm9yIFNQSSB0byBiZSByZWFkeQoKCQkvLyBFbmFibGUgU1BJIEZ1bmN0aW9ucwoJCS8vIERpc2FibGUgTU9TSSwgTUlTTywgQUREUiwgQ09NTUFORCwgRFVNTVkgaW4gY2FzZSBwcmV2aW91c2x5IHNldC4KCQlDTEVBUl9QRVJJX1JFR19NQVNLKFNQSV9VU0VSKDEpLCBTUElfVVNSX01PU0kgfCBTUElfVVNSX01JU08gfCBTUElfVVNSX0NPTU1BTkQgfCBTUElfVVNSX0FERFIgfCBTUElfVVNSX0RVTU1ZKTsKCgkJLy8gU2V0dXAgQml0bGVuZ3RocwoJCVdSSVRFX1BFUklfUkVHKFNQSV9VU0VSMSgxKSwKCQkJLy8gTnVtYmVyIG9mIGJpdHMgaW4gQWRkcmVzcwoJCQkoKGFkZHJiaXRzIC0gMSkgJiBTUElfVVNSX0FERFJfQklUTEVOKSA8PCBTUElfVVNSX0FERFJfQklUTEVOX1MgfAoJCQkvLyBOdW1iZXIgb2YgYml0cyB0byBTZW5kCgkJCSgoZG91dGJpdHMgLSAxKSAmIFNQSV9VU1JfTU9TSV9CSVRMRU4pIDw8IFNQSV9VU1JfTU9TSV9CSVRMRU5fUyk7CgoJCS8vIFNldHVwIENvbW1hbmQgRGF0YQoJCWlmIChjbWRiaXRzKSB7CgkJCS8vIEVuYWJsZSBDT01NQU5EIGZ1bmN0aW9uIGluIFNQSSBtb2R1bGUKCQkJU0VUX1BFUklfUkVHX01BU0soU1BJX1VTRVIoMSksIFNQSV9VU1JfQ09NTUFORCk7CgkJCS8vIEFsaWduIGNvbW1hbmQgZGF0YSB0byBoaWdoIGJpdHMKCQkJdWludDE2X3QgY29tbWFuZCA9IGNtZGRhdGEgPDwgKDE2IC0gY21kYml0cyk7CgkJCS8vIFN3YXAgYnl0ZSBvcmRlcgoJCQljb21tYW5kID0gKChjb21tYW5kID4+IDgpICYgMHhmZikgfCAoKGNvbW1hbmQgPDwgOCkgJiAweGZmMDApOwoJCQlXUklURV9QRVJJX1JFRyhTUElfVVNFUjIoMSksICgKCQkJCSgoKGNtZGJpdHMgLSAxKSAmIFNQSV9VU1JfQ09NTUFORF9CSVRMRU4pIDw8IFNQSV9VU1JfQ09NTUFORF9CSVRMRU5fUykgfAoJCQkJKGNvbW1hbmQgJiBTUElfVVNSX0NPTU1BTkRfVkFMVUUpCgkJCQkpKTsKCQl9CgoJCS8vIFNldHVwIEFkZHJlc3MgRGF0YQoJCWlmIChhZGRyYml0cykgewoJCQkvLyBFbmFibGUgQUREUmVzcyBmdW5jdGlvbiBpbiBTUEkgbW9kdWxlCgkJCVNFVF9QRVJJX1JFR19NQVNLKFNQSV9VU0VSKDEpLCBTUElfVVNSX0FERFIpOwoJCQkvLyBBbGlnbiBhZGRyZXNzIGRhdGEgdG8gaGlnaCBiaXRzCgkJCVdSSVRFX1BFUklfUkVHKFNQSV9BRERSKDEpLCBhZGRyZGF0YSA8PCAoMzIgLSBhZGRyYml0cykpOwoJCX0KCgkJLy8gU2V0dXAgRE9VVCBkYXRhCgkJaWYgKGRvdXRiaXRzKSB7CgkJCS8vIEVuYWJsZSBNT1NJIGZ1bmN0aW9uIGluIFNQSSBtb2R1bGUKCQkJU0VUX1BFUklfUkVHX01BU0soU1BJX1VTRVIoMSksIFNQSV9VU1JfTU9TSSk7CgkJCS8vIENvcHkgZGF0YSB0byBXMAoJCQlpZiAoUkVBRF9QRVJJX1JFRyhTUElfVVNFUigxKSkmU1BJX1dSX0JZVEVfT1JERVIpIHsKCQkJCVdSSVRFX1BFUklfUkVHKFNQSV9XMCgxKSwgZG91dGRhdGEgPDwgKDMyIC0gZG91dGJpdHMpKTsKCQkJfQoJCQllbHNlIHsKCQkJCVdSSVRFX1BFUklfUkVHKFNQSV9XMCgxKSwgZG91dGRhdGEpOwoJCQl9CgkJfQoKCQkvLyBCZWdpbiBTUEkgVHJhbnNhY3Rpb24KCQlTRVRfUEVSSV9SRUdfTUFTSyhTUElfQ01EKDEpLCBTUElfVVNSKTsKCX0KCS8vIFRyYW5zYWN0aW9uIGNvbXBsZXRlZAoJcmV0dXJuIG1wX2NvbnN0X25vbmU7IC8vcmV0dXJuIE5vbmUKfQoKClNUQVRJQyBNUF9ERUZJTkVfQ09OU1RfRlVOX09CSl8xKGhzcGl0eGNodW5rX3NlbmRfb2JqLCBoc3BpX3R4Y2h1bmspOwovL1NUQVRJQyBNUF9ERUZJTkVfQ09OU1RfRlVOX09CSl9WQVJfQkVUV0VFTihoc3BpdHhjaHVua19zZW5kX29iaiwgMSwgMTAsIGhzcGlfdHhjaHVuayk7CgovLyBkZWNsYXJlIHB5dGhvbiBtb2R1bGUKU1RBVElDIGNvbnN0IG1wX21hcF9lbGVtX3QgaHNwaXR4Y2h1bmtfZ2xvYmFsc190YWJsZVtdID0gewoJeyBNUF9PQkpfTkVXX1FTVFIoTVBfUVNUUl9fX25hbWVfXyksIE1QX09CSl9ORVdfUVNUUihNUF9RU1RSX2hzcGl0eGNodW5rKSB9LAoJeyBNUF9PQkpfTkVXX1FTVFIoTVBfUVNUUl9zZW5kKSwgKG1wX29ial90KSZoc3BpdHhjaHVua19zZW5kX29iaiB9LAp9OwoKU1RBVElDIE1QX0RFRklORV9DT05TVF9ESUNUKG1wX21vZHVsZV9oc3BpdHhjaHVua19nbG9iYWxzLCBoc3BpdHhjaHVua19nbG9iYWxzX3RhYmxlKTsKCmNvbnN0IG1wX29ial9tb2R1bGVfdCBtcF9tb2R1bGVfaHNwaXR4Y2h1bmsgPSB7CgkuYmFzZSA9IHsgJm1wX3R5cGVfbW9kdWxlIH0sCgkvLy5uYW1lID0gTVBfUVNUUl9oc3BpdHhjaHVuaywgLy8gZGVwcmljYXRlZAoJLmdsb2JhbHMgPSAobXBfb2JqX2RpY3RfdCopJm1wX21vZHVsZV9oc3BpdHhjaHVua19nbG9iYWxzLAp9OwovLyBlbmQgZGVjbGFyYXRpb24KCg==